Skip to content

Commit a79463c

Browse files
author
Eela Nagaraj
committed
Move API tracing tests to e2e
1 parent 9ffa6f7 commit a79463c

File tree

2 files changed

+40
-214
lines changed

2 files changed

+40
-214
lines changed

e2e_test/e2e_test.go

+40
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package e2e_test
22

33
import (
44
"context"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"math/big"
@@ -93,6 +94,45 @@ func TestTraceSendCeloViaGoldToken(t *testing.T) {
9394
// Check top level gas values
9495
require.Equal(t, result["gasUsed"], "0x3a46")
9596
require.Equal(t, result["gas"], "0x3ac4")
97+
// TODO add more specific trace-checking as part of
98+
// this issue: https://github.com/celo-org/celo-blockchain/issues/2078
99+
}
100+
101+
// Moved from API tests because registering the callTracer (necessary after the
102+
// go native tracer refactor) causes a circular import.
103+
// Use the callTracer to trace a native CELO transfer.
104+
func TestCallTraceTransactionNativeTransfer(t *testing.T) {
105+
ac := test.AccountConfig(1, 2)
106+
gc, ec, err := test.BuildConfig(ac)
107+
require.NoError(t, err)
108+
network, shutdown, err := test.NewNetwork(ac, gc, ec)
109+
require.NoError(t, err)
110+
defer shutdown()
111+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
112+
defer cancel()
113+
114+
accounts := test.Accounts(ac.DeveloperAccounts(), gc.ChainConfig())
115+
116+
// Send one celo from external account 0 to 1 via node 0.
117+
tx, err := accounts[0].SendCelo(ctx, accounts[1].Address, 1, network[0])
118+
require.NoError(t, err)
119+
120+
// Wait for the whole network to process the transaction.
121+
err = network.AwaitTransactions(ctx, tx)
122+
require.NoError(t, err)
123+
c, err := rpc.DialContext(ctx, network[0].WSEndpoint())
124+
require.NoError(t, err)
125+
126+
var result map[string]interface{}
127+
tracerStr := "callTracer"
128+
err = c.CallContext(ctx, &result, "debug_traceTransaction", tx.Hash().String(), tracers.TraceConfig{Tracer: &tracerStr})
129+
require.NoError(t, err)
130+
res_json, err := json.Marshal(result)
131+
if err != nil {
132+
t.Fatalf("failed to marshal result: %v", err)
133+
}
134+
expectedTraceStr := fmt.Sprintf(`{"from":"0x%x","gas":"0x0","gasUsed":"0x0","input":"0x","output":"0x","to":"0x%x","type":"CALL","value":"0x1"}`, accounts[0].Address, accounts[1].Address)
135+
require.JSONEq(t, expectedTraceStr, string(res_json))
96136
}
97137

98138
// This test verifies correct behavior in a network of size one, in the case that

eth/tracers/api_test.go

-214
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import (
2929
"testing"
3030
"time"
3131

32-
"github.com/celo-org/celo-blockchain/accounts/abi"
3332
"github.com/celo-org/celo-blockchain/common"
3433
"github.com/celo-org/celo-blockchain/common/hexutil"
3534
"github.com/celo-org/celo-blockchain/consensus"
@@ -404,194 +403,6 @@ func TestTraceTransactionWithRegistryDeployed(t *testing.T) {
404403
}
405404
}
406405

407-
// Use the callTracer to trace a native CELO transfer after the
408-
// registry has been deployed, as above.
409-
func TestCallTraceTransactionNativeTransfer(t *testing.T) {
410-
t.Parallel()
411-
412-
// Initialize test accounts
413-
accounts := newAccounts(2)
414-
genesis := &core.Genesis{Alloc: core.GenesisAlloc{
415-
accounts[0].addr: {Balance: big.NewInt(params.Ether)},
416-
accounts[1].addr: {Balance: big.NewInt(params.Ether)},
417-
common.HexToAddress("0xce10"): { // Registry Proxy
418-
Code: testutil.RegistryProxyOpcodes,
419-
Storage: map[common.Hash]common.Hash{
420-
// Hashes represent the storage slot for Registry.sol's `registry` mapping
421-
// which is stored in the RegistryProxy's storage.
422-
// Hashes are computed by taking: keccack(packed(params.GoldTokenRegistryId, 1)),
423-
// where 1 is the storage offset)
424-
common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"): common.HexToHash("0xce11"), // Registry Implementation
425-
common.HexToHash("0x91646b8507bf2e54d7c3de9155442ba111546b81af1cbdd1f68eeb6926b98d58"): common.HexToHash("0xd023"), // Governance Proxy
426-
},
427-
Balance: big.NewInt(0),
428-
},
429-
common.HexToAddress("0xce11"): { // Registry Implementation
430-
Code: testutil.RegistryOpcodes,
431-
Balance: big.NewInt(0),
432-
},
433-
}}
434-
435-
target := common.Hash{}
436-
signer := types.HomesteadSigner{}
437-
transferVal := big.NewInt(1000)
438-
api := NewAPI(newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
439-
// Transfer from account[0] to account[1]
440-
// value: 1000 wei
441-
// fee: 0 wei
442-
tx, _ := types.SignTx(types.NewTransaction(uint64(i), accounts[1].addr, transferVal, params.TxGas, nil, nil, nil, nil, nil), signer, accounts[0].key)
443-
b.AddTx(tx)
444-
target = tx.Hash()
445-
}))
446-
tracerStr := "callTracer"
447-
result, err := api.TraceTransaction(context.Background(), target, &TraceConfig{Tracer: &tracerStr})
448-
if err != nil {
449-
t.Errorf("Failed to trace transaction %v", err)
450-
}
451-
452-
ret := new(callTrace)
453-
if err := json.Unmarshal(result.(json.RawMessage), ret); err != nil {
454-
t.Fatalf("failed to unmarshal trace result: %v", err)
455-
}
456-
expectedTrace := &callTrace{
457-
Type: "CALL",
458-
From: accounts[0].addr,
459-
To: accounts[1].addr,
460-
Input: hexutil.Bytes(common.Hex2Bytes("0x")),
461-
Output: hexutil.Bytes(common.Hex2Bytes("0x")),
462-
Gas: newRPCUint64(0),
463-
GasUsed: newRPCUint64(0),
464-
Value: (*hexutil.Big)(transferVal),
465-
}
466-
if !jsonEqual(ret, expectedTrace) {
467-
t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, expectedTrace)
468-
}
469-
}
470-
471-
// Use the callTracer to trace a CELO transfer made via the transfer
472-
// precompile (by sending this from the registered GoldToken contract).
473-
func TestCallTraceTransactionPrecompileTransfer(t *testing.T) {
474-
// Invoke the transfer precompile by sending a transfer from an account
475-
// registered as GoldToken in the mock registry
476-
t.Parallel()
477-
// Initialize test accounts
478-
accounts := newAccounts(3)
479-
goldToken := accounts[0]
480-
registryProxyAddr := common.HexToAddress("0xce10")
481-
registryImplAddr := common.HexToAddress("0xce11")
482-
genesis := &core.Genesis{Alloc: core.GenesisAlloc{
483-
goldToken.addr: {Balance: big.NewInt(params.Ether)},
484-
accounts[1].addr: {Balance: big.NewInt(params.Ether)},
485-
accounts[2].addr: {Balance: big.NewInt(params.Ether)},
486-
registryProxyAddr: { // Registry Proxy
487-
Code: testutil.RegistryProxyOpcodes,
488-
Storage: map[common.Hash]common.Hash{
489-
common.HexToHash("0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc"): common.HexToHash("0xce11"), // Registry Implementation
490-
common.HexToHash("0x91646b8507bf2e54d7c3de9155442ba111546b81af1cbdd1f68eeb6926b98d58"): common.HexToHash("0xd023"), // Governance Proxy
491-
common.HexToHash("0x773cc8652456781771d48fb3d560d7ba3d6d1882654492b68beec583d2c590aa"): goldToken.addr.Hash(), // GoldToken Implementation
492-
common.HexToHash("0x2131a4338f6fb8d4507e234a7c72af8efefbbf2f1817ed570bce33eb6667feb9"): common.HexToHash("0xd007"), // Reserve Implementation
493-
},
494-
Balance: big.NewInt(0),
495-
},
496-
registryImplAddr: { // Registry Implementation
497-
Code: testutil.RegistryOpcodes,
498-
Balance: big.NewInt(0),
499-
},
500-
}}
501-
502-
target := common.Hash{}
503-
signer := types.HomesteadSigner{}
504-
transferVal := big.NewInt(1000)
505-
506-
// Construct and pack data for transfer precompile representing [from, to, value]
507-
addressTy, err := abi.NewType("address", "", nil)
508-
if err != nil {
509-
t.Fatalf("failed to create address type: %v", err)
510-
}
511-
uint256Ty, err := abi.NewType("uint256", "", nil)
512-
if err != nil {
513-
t.Fatalf("failed to create uint256 type: %v", err)
514-
}
515-
516-
transferArgs := abi.Arguments{
517-
{
518-
Type: addressTy,
519-
},
520-
{
521-
Type: addressTy,
522-
},
523-
{
524-
Type: uint256Ty,
525-
},
526-
}
527-
data, err := transferArgs.Pack(accounts[1].addr, accounts[2].addr, transferVal)
528-
if err != nil {
529-
t.Fatalf("failed to pack args: %v", err)
530-
}
531-
transferPrecompile := common.HexToAddress("0xfd")
532-
gas := params.TxGas * 2
533-
api := NewAPI(newTestBackend(t, 1, genesis, func(i int, b *core.BlockGen) {
534-
// Transfer via transfer precompile by sending tx from GoldToken addr
535-
tx, _ := types.SignTx(types.NewTransaction(uint64(i), transferPrecompile, big.NewInt(0), gas, big.NewInt(3), nil, nil, nil, data), signer, goldToken.key)
536-
b.AddTx(tx)
537-
target = tx.Hash()
538-
}))
539-
tracerStr := "callTracer"
540-
result, err := api.TraceTransaction(context.Background(), target, &TraceConfig{Tracer: &tracerStr})
541-
542-
if err != nil {
543-
t.Errorf("Failed to trace transaction %v", err)
544-
}
545-
546-
ret := new(callTrace)
547-
if err := json.Unmarshal(result.(json.RawMessage), ret); err != nil {
548-
t.Fatalf("failed to unmarshal trace result: %v", err)
549-
}
550-
551-
// Registry ABI packed version of Registry.getAddressFor("GoldToken")
552-
packedGetAddressForGoldToken := common.FromHex("0xdd927233d7e89ade8430819f08bf97a087285824af3351ee12d72a2d132b0c6c0687bfaf")
553-
expectedTrace := &callTrace{
554-
// Outer transaction call
555-
Type: "CALL",
556-
From: goldToken.addr,
557-
To: transferPrecompile,
558-
Input: data,
559-
Output: data,
560-
Gas: newRPCUint64(20112),
561-
// Note that top-level traces do not currently include intrinsic gas
562-
GasUsed: newRPCUint64(params.CallValueTransferGas),
563-
Value: (*hexutil.Big)(big.NewInt(0)),
564-
Calls: []callTrace{
565-
{
566-
// Lookup of GoldToken contract address with capped gas
567-
Type: "STATICCALL",
568-
From: common.ZeroAddress,
569-
To: registryProxyAddr,
570-
Input: packedGetAddressForGoldToken,
571-
Output: common.LeftPadBytes(goldToken.addr.Bytes(), 32),
572-
Gas: newRPCUint64(params.MaxGasForGetAddressFor),
573-
GasUsed: newRPCUint64(0),
574-
Calls: []callTrace{
575-
{
576-
// RegistryProxy -> RegistryImpl delegate call to
577-
// retrieve GoldToken address
578-
Type: "DELEGATECALL",
579-
From: registryProxyAddr,
580-
To: registryImplAddr,
581-
Input: packedGetAddressForGoldToken,
582-
Output: common.LeftPadBytes(goldToken.addr.Bytes(), 32),
583-
Gas: newRPCUint64(0),
584-
GasUsed: newRPCUint64(0),
585-
},
586-
},
587-
},
588-
},
589-
}
590-
if !jsonEqual(ret, expectedTrace) {
591-
t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, expectedTrace)
592-
}
593-
}
594-
595406
func TestTraceBlock(t *testing.T) {
596407
t.Parallel()
597408

@@ -905,11 +716,6 @@ func newRPCBalance(balance *big.Int) **hexutil.Big {
905716
return &rpcBalance
906717
}
907718

908-
func newRPCUint64(number uint64) *hexutil.Uint64 {
909-
rpcUint64 := hexutil.Uint64(number)
910-
return &rpcUint64
911-
}
912-
913719
func newRPCBytes(bytes []byte) *hexutil.Bytes {
914720
rpcBytes := hexutil.Bytes(bytes)
915721
return &rpcBytes
@@ -925,23 +731,3 @@ func newStates(keys []common.Hash, vals []common.Hash) *map[common.Hash]common.H
925731
}
926732
return &m
927733
}
928-
929-
// jsonEqual is similar to reflect.DeepEqual, but does a 'bounce' via json prior to
930-
// comparison
931-
// Note: this is duplicated from calltrace_test due to keep the diff minimal
932-
// after package restructuring in go-ethereum.
933-
func jsonEqual(x, y interface{}) bool {
934-
xTrace := new(callTrace)
935-
yTrace := new(callTrace)
936-
if xj, err := json.Marshal(x); err == nil {
937-
json.Unmarshal(xj, xTrace)
938-
} else {
939-
return false
940-
}
941-
if yj, err := json.Marshal(y); err == nil {
942-
json.Unmarshal(yj, yTrace)
943-
} else {
944-
return false
945-
}
946-
return reflect.DeepEqual(xTrace, yTrace)
947-
}

0 commit comments

Comments
 (0)