@ -25,8 +25,12 @@ import (
"testing"
"time"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/eth/ethconfig"
"github.com/ethereum/go-ethereum/node"
@ -55,7 +59,7 @@ func TestBuildSchema(t *testing.T) {
// Tests that a graphQL request is successfully handled when graphql is enabled on the specified endpoint
func TestGraphQLBlockSerialization ( t * testing . T ) {
stack := createNode ( t , true )
stack := createNode ( t , true , false )
defer stack . Close ( )
// start node
if err := stack . Start ( ) ; err != nil {
@ -157,9 +161,45 @@ func TestGraphQLBlockSerialization(t *testing.T) {
}
}
func TestGraphQLBlockSerializationEIP2718 ( t * testing . T ) {
stack := createNode ( t , true , true )
defer stack . Close ( )
// start node
if err := stack . Start ( ) ; err != nil {
t . Fatalf ( "could not start node: %v" , err )
}
for i , tt := range [ ] struct {
body string
want string
code int
} {
{
body : ` { "query": " { block { number transactions { from { address } to { address } value hash type accessList { address storageKeys } index}}}"} ` ,
want : ` { "data": { "block": { "number":1,"transactions":[ { "from": { "address":"0x71562b71999873db5b286df957af199ec94617f7"},"to": { "address":"0x0000000000000000000000000000000000000dad"},"value":"0x64","hash":"0x4f7b8d718145233dcf7f29e34a969c63dd4de8715c054ea2af022b66c4f4633e","type":0,"accessList":[],"index":0}, { "from": { "address":"0x71562b71999873db5b286df957af199ec94617f7"},"to": { "address":"0x0000000000000000000000000000000000000dad"},"value":"0x32","hash":"0x9c6c2c045b618fe87add0e49ba3ca00659076ecae00fd51de3ba5d4ccf9dbf40","type":1,"accessList":[ { "address":"0x0000000000000000000000000000000000000dad","storageKeys":["0x0000000000000000000000000000000000000000000000000000000000000000"]}],"index":1}]}}} ` ,
code : 200 ,
} ,
} {
resp , err := http . Post ( fmt . Sprintf ( "%s/graphql" , stack . HTTPEndpoint ( ) ) , "application/json" , strings . NewReader ( tt . body ) )
if err != nil {
t . Fatalf ( "could not post: %v" , err )
}
bodyBytes , err := ioutil . ReadAll ( resp . Body )
if err != nil {
t . Fatalf ( "could not read from response body: %v" , err )
}
if have := string ( bodyBytes ) ; have != tt . want {
t . Errorf ( "testcase %d %s,\nhave:\n%v\nwant:\n%v" , i , tt . body , have , tt . want )
}
if tt . code != resp . StatusCode {
t . Errorf ( "testcase %d %s,\nwrong statuscode, have: %v, want: %v" , i , tt . body , resp . StatusCode , tt . code )
}
}
}
// Tests that a graphQL request is not handled successfully when graphql is not enabled on the specified endpoint
func TestGraphQLHTTPOnSamePort_GQLRequest_Unsuccessful ( t * testing . T ) {
stack := createNode ( t , false )
stack := createNode ( t , false , false )
defer stack . Close ( )
if err := stack . Start ( ) ; err != nil {
t . Fatalf ( "could not start node: %v" , err )
@ -173,7 +213,7 @@ func TestGraphQLHTTPOnSamePort_GQLRequest_Unsuccessful(t *testing.T) {
assert . Equal ( t , http . StatusNotFound , resp . StatusCode )
}
func createNode ( t * testing . T , gqlEnabled bool ) * node . Node {
func createNode ( t * testing . T , gqlEnabled bool , txEnabled bool ) * node . Node {
stack , err := node . New ( & node . Config {
HTTPHost : "127.0.0.1" ,
HTTPPort : 0 ,
@ -186,7 +226,11 @@ func createNode(t *testing.T, gqlEnabled bool) *node.Node {
if ! gqlEnabled {
return stack
}
createGQLService ( t , stack )
if ! txEnabled {
createGQLService ( t , stack )
} else {
createGQLServiceWithTransactions ( t , stack )
}
return stack
}
@ -226,3 +270,87 @@ func createGQLService(t *testing.T, stack *node.Node) {
t . Fatalf ( "could not create graphql service: %v" , err )
}
}
func createGQLServiceWithTransactions ( t * testing . T , stack * node . Node ) {
// create backend
key , _ := crypto . HexToECDSA ( "b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" )
address := crypto . PubkeyToAddress ( key . PublicKey )
funds := big . NewInt ( 1000000000 )
dad := common . HexToAddress ( "0x0000000000000000000000000000000000000dad" )
ethConf := & ethconfig . Config {
Genesis : & core . Genesis {
Config : params . AllEthashProtocolChanges ,
GasLimit : 11500000 ,
Difficulty : big . NewInt ( 1048576 ) ,
Alloc : core . GenesisAlloc {
address : { Balance : funds } ,
// The address 0xdad sloads 0x00 and 0x01
dad : {
Code : [ ] byte {
byte ( vm . PC ) ,
byte ( vm . PC ) ,
byte ( vm . SLOAD ) ,
byte ( vm . SLOAD ) ,
} ,
Nonce : 0 ,
Balance : big . NewInt ( 0 ) ,
} ,
} ,
} ,
Ethash : ethash . Config {
PowMode : ethash . ModeFake ,
} ,
NetworkId : 1337 ,
TrieCleanCache : 5 ,
TrieCleanCacheJournal : "triecache" ,
TrieCleanCacheRejournal : 60 * time . Minute ,
TrieDirtyCache : 5 ,
TrieTimeout : 60 * time . Minute ,
SnapshotCache : 5 ,
}
ethBackend , err := eth . New ( stack , ethConf )
if err != nil {
t . Fatalf ( "could not create eth backend: %v" , err )
}
signer := types . LatestSigner ( ethConf . Genesis . Config )
legacyTx , _ := types . SignNewTx ( key , signer , & types . LegacyTx {
Nonce : uint64 ( 0 ) ,
To : & dad ,
Value : big . NewInt ( 100 ) ,
Gas : 50000 ,
GasPrice : big . NewInt ( 1 ) ,
} )
envelopTx , _ := types . SignNewTx ( key , signer , & types . AccessListTx {
ChainID : ethConf . Genesis . Config . ChainID ,
Nonce : uint64 ( 1 ) ,
To : & dad ,
Gas : 30000 ,
GasPrice : big . NewInt ( 1 ) ,
Value : big . NewInt ( 50 ) ,
AccessList : types . AccessList { {
Address : dad ,
StorageKeys : [ ] common . Hash { { 0 } } ,
} } ,
} )
// Create some blocks and import them
chain , _ := core . GenerateChain ( params . AllEthashProtocolChanges , ethBackend . BlockChain ( ) . Genesis ( ) ,
ethash . NewFaker ( ) , ethBackend . ChainDb ( ) , 1 , func ( i int , b * core . BlockGen ) {
b . SetCoinbase ( common . Address { 1 } )
b . AddTx ( legacyTx )
b . AddTx ( envelopTx )
} )
_ , err = ethBackend . BlockChain ( ) . InsertChain ( chain )
if err != nil {
t . Fatalf ( "could not create import blocks: %v" , err )
}
// create gql service
err = New ( stack , ethBackend . APIBackend , [ ] string { } , [ ] string { } )
if err != nil {
t . Fatalf ( "could not create graphql service: %v" , err )
}
}