From e1d6f4ec9d2f0755af0a80632b324784412a64b4 Mon Sep 17 00:00:00 2001 From: Tyler Smith Date: Tue, 16 Jan 2024 13:40:44 -0400 Subject: [PATCH] fix: Merge errors with v1.13.10. --- eth/catalyst/simulated_beacon.go | 27 --- eth/tracers/blocknative/blocknative.go | 31 ++- eth/tracers/blocknative/cache/trace_cache.go | 27 --- eth/tracers/blocknative/decoder/asset.go | 86 +++++++- eth/tracers/blocknative/decoder/contract.go | 12 +- eth/tracers/blocknative/decoder/decoder.go | 98 +-------- eth/tracers/blocknative/decoder/evm_caller.go | 121 ----------- eth/tracers/blocknative/decoder/types.go | 7 +- eth/tracers/blocknative/decoder_evm.go | 17 +- eth/tracers/blocknative/tracer.go | 12 -- eth/tracers/blocknative/utils.go | 40 ++-- .../internal/tracetest/blocknative_test.go | 2 - .../with_decoding/delegatecall.json | 45 ++++- .../erc20_transfer_with_tax.json | 189 ------------------ 14 files changed, 173 insertions(+), 541 deletions(-) delete mode 100644 eth/tracers/blocknative/cache/trace_cache.go delete mode 100644 eth/tracers/blocknative/decoder/evm_caller.go delete mode 100644 eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go index ffe8413a7a90..3c081074cc52 100644 --- a/eth/catalyst/simulated_beacon.go +++ b/eth/catalyst/simulated_beacon.go @@ -19,7 +19,6 @@ package catalyst import ( "crypto/rand" "errors" - "github.com/ethereum/go-ethereum/core" "math/big" "sync" "time" @@ -200,32 +199,6 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u return nil } -// loopOnDemand runs the block production loop for "on-demand" configuration (period = 0) -func (c *SimulatedBeacon) loopOnDemand() { - var ( - newTxs = make(chan core.NewTxsEvent) - sub = c.eth.TxPool().SubscribeTransactions(newTxs, true) - ) - defer sub.Unsubscribe() - - for { - select { - case <-c.shutdownCh: - return - case w := <-c.withdrawals.pending: - withdrawals := append(c.withdrawals.gatherPending(9), w) - if err := c.sealBlock(withdrawals); err != nil { - log.Warn("Error performing sealing work", "err", err) - } - case <-newTxs: - withdrawals := c.withdrawals.gatherPending(10) - if err := c.sealBlock(withdrawals); err != nil { - log.Warn("Error performing sealing work", "err", err) - } - } - } -} - // loop runs the block production loop for non-zero period configuration func (c *SimulatedBeacon) loop() { timer := time.NewTimer(0) diff --git a/eth/tracers/blocknative/blocknative.go b/eth/tracers/blocknative/blocknative.go index c67fe0ba8894..fd1517a8672d 100644 --- a/eth/tracers/blocknative/blocknative.go +++ b/eth/tracers/blocknative/blocknative.go @@ -4,7 +4,6 @@ import ( "encoding/json" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" ) @@ -41,24 +40,24 @@ type Trace struct { // BlockContext contains information about the block we simulate transactions in. type BlockContext struct { - Number uint64 `json:"number"` - BaseFee uint64 `json:"baseFee"` - Time uint64 `json:"time"` - GasLimit uint64 `json:"gasLimit"` - Coinbase common.Address `json:"coinbase"` - StateRoot hexutil.Bytes `json:"stateRoot,omitempty"` - Random common.Hash `json:"random,omitempty"` + Number uint64 `json:"number"` + StateRoot string `json:"stateRoot,omitempty"` + BaseFee uint64 `json:"baseFee"` + Time uint64 `json:"time"` + Coinbase string `json:"coinbase"` + GasLimit uint64 `json:"gasLimit"` + Random string `json:"random,omitempty"` } type CallFrame struct { Type string `json:"type"` - From common.Address `json:"from"` - To common.Address `json:"to,omitempty"` - Value Big `json:"value,omitempty"` - Gas Uint64 `json:"gas"` - GasUsed Uint64 `json:"gasUsed"` - Input hexutil.Bytes `json:"input"` - Output hexutil.Bytes `json:"output,omitempty"` + From string `json:"from"` + To string `json:"to,omitempty"` + Value string `json:"value,omitempty"` + Gas string `json:"gas"` + GasUsed string `json:"gasUsed"` + Input string `json:"input"` + Output string `json:"output,omitempty"` Error string `json:"error,omitempty"` ErrorReason string `json:"errorReason,omitempty"` Calls []CallFrame `json:"calls,omitempty"` @@ -71,7 +70,7 @@ type CallLog struct { Address common.Address `json:"address"` // Data is the encoded memory provided with the log. - Data hexutil.Bytes `json:"data"` + Data string `json:"data"` // Topics is a slice of up to 4 32byte words provided with the log. Topics []common.Hash `json:"topics"` diff --git a/eth/tracers/blocknative/cache/trace_cache.go b/eth/tracers/blocknative/cache/trace_cache.go deleted file mode 100644 index afdc4f0cbedc..000000000000 --- a/eth/tracers/blocknative/cache/trace_cache.go +++ /dev/null @@ -1,27 +0,0 @@ -package cache - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/ethereum/go-ethereum/eth/tracers/blocknative" -) - -var ( - traceCacheSize = 10_000 - traceCache = lru.NewCache[[64]byte, *blocknative.Trace](traceCacheSize) -) - -func PutTrace(blockHash, txHash common.Hash, trace *blocknative.Trace) bool { - return traceCache.Add(traceCacheKey(blockHash, txHash), trace) -} - -func GetTrace(blockHash, txHash common.Hash) (*blocknative.Trace, bool) { - return traceCache.Get(traceCacheKey(blockHash, txHash)) -} - -func traceCacheKey(blockHash, txHash common.Hash) [64]byte { - key := [64]byte{} - copy(key[:32], blockHash[:]) - copy(key[32:], txHash[:]) - return key -} diff --git a/eth/tracers/blocknative/decoder/asset.go b/eth/tracers/blocknative/decoder/asset.go index cc07add591d7..82b5853a7f33 100644 --- a/eth/tracers/blocknative/decoder/asset.go +++ b/eth/tracers/blocknative/decoder/asset.go @@ -46,13 +46,13 @@ func decodeERC20Metadata(evmCall evmCallFn, addr common.Address) AssetMetadata { var err error metadata := AssetMetadata{Type: AssetTypeERC20} - if metadata.Name, err = evmCallMethodName(evmCall, addr); err != nil { + if metadata.Name, err = decodeMetadataName(evmCall, addr); err != nil { log.Trace("failed to decode ERC20 name", "err", err) } - if metadata.Symbol, err = evmCallMethodSymbol(evmCall, addr); err != nil { + if metadata.Symbol, err = decodeMetadataSymbol(evmCall, addr); err != nil { log.Trace("failed to decode ERC20 symbol", "err", err) } - if metadata.Decimals, err = evmCallMethodDecimals(evmCall, addr); err != nil { + if metadata.Decimals, err = decodeMetadataDecimals(evmCall, addr); err != nil { log.Trace("failed to decode ERC20 decimals", "err", err) } @@ -64,10 +64,10 @@ func decodeERC721Metadata(evmCall evmCallFn, addr common.Address, tokenID *big.I var err error metadata := AssetMetadata{Type: AssetTypeERC721} - if metadata.Name, err = evmCallMethodName(evmCall, addr); err != nil { + if metadata.Name, err = decodeMetadataName(evmCall, addr); err != nil { log.Trace("failed to decode ERC721 name", "err", err) } - if metadata.Symbol, err = evmCallMethodSymbol(evmCall, addr); err != nil { + if metadata.Symbol, err = decodeMetadataSymbol(evmCall, addr); err != nil { log.Trace("failed to decode ERC721 symbol", "err", err) } @@ -94,6 +94,82 @@ func decodeERC1155Metadata(evmCall evmCallFn, addr common.Address, tokenID *big. return metadata } +// decodeMetadataName decodes the name of an asset from the EVM. +func decodeMetadataName(evmCall evmCallFn, addr common.Address) (string, error) { + return callAndDecodeString(evmCall, addr, methodIDName) +} + +// decodeMetadataSymbol decodes the symbol of an asset from the EVM. +func decodeMetadataSymbol(evmCall evmCallFn, addr common.Address) (string, error) { + return callAndDecodeString(evmCall, addr, methodIDSymbol) +} + +// decodeMetadataDecimals decodes the decimals of an asset from the EVM. +func decodeMetadataDecimals(evmCall evmCallFn, addr common.Address) (uint8, error) { + return callAndDecodeUint8(evmCall, addr, methodIDDecimals) +} + +// decodeMetadataTokenURI decodes the tokenURI of an asset from the EVM. +func decodeMetadataTokenURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { + tokenIDBytes := tokenID.Bytes() + if len(tokenIDBytes) > 32 { + return "", fmt.Errorf("tokenID is too large") + } + common.LeftPadBytes(tokenIDBytes, 32) + input := append(methodIDTokenURI, tokenIDBytes...) + return callAndDecodeString(evmCall, addr, input) +} + +// decodeMetadataURI decodes the URI of an asset from the EVM. +func decodeMetadataURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { + tokenIDBytes := tokenID.Bytes() + if len(tokenIDBytes) > 32 { + return "", fmt.Errorf("tokenID is too large") + } + common.LeftPadBytes(tokenIDBytes, 32) + input := append(methodIDURI, tokenIDBytes...) + return callAndDecodeString(evmCall, addr, input) +} + +// callAndDecodeString calls a method and decodes the result as a string. +func callAndDecodeString(evmCall evmCallFn, addr common.Address, method []byte) (string, error) { + // Load bytes from the EVM. + stringBytes, err := evmCall(addr, method) + if err != nil { + return "", err + } + + // Parse into a string. + stringInterface, err := abiArgs.singleString.Unpack(stringBytes) + if err != nil { + return "", err + } + if len(stringInterface) < len(abiArgs.singleString) { + return "", fmt.Errorf("unexpected decoded size") + } + str, ok := stringInterface[0].(string) + if !ok { + return "", fmt.Errorf("unexpected type for decoded string") + } + + return str, nil +} + +// callAndDecodeUint8 calls a method and decodes the result as a uint8. +func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, method []byte) (uint8, error) { + // Load bytes from the EVM. + uint8Bytes, err := evmCall(addr, method) + if err != nil { + return 0, err + } + + // Parse into a uint8. + if len(uint8Bytes) < 1 { + return 0, fmt.Errorf("unexpected decoded size") + } + return uint8Bytes[len(uint8Bytes)-1], nil +} + // decodeArgsSafeBatchTransferFrom calls a method and decodes the result as a uint256[]. func decodeArgsSafeBatchTransferFrom(bytes []byte) ([]*Transfer, error) { args, err := abiArgs.batchTransfer.UnpackValues(bytes) diff --git a/eth/tracers/blocknative/decoder/contract.go b/eth/tracers/blocknative/decoder/contract.go index 195a31b4cdb3..cd967c5a45df 100644 --- a/eth/tracers/blocknative/decoder/contract.go +++ b/eth/tracers/blocknative/decoder/contract.go @@ -2,14 +2,18 @@ package decoder import ( "bytes" - "golang.org/x/exp/slices" ) // decodeContract decodes the contract bytecode and determines all interfaces -func decodeContract(c *Contract, bytecode ByteCode) { - c.interfaces = bytecode.DecodeInterfaces() - c.Type = contractTypeForInterfaces(c.interfaces) +func decodeContract(bytecode ByteCode) (*Contract, error) { + + interfaces := bytecode.DecodeInterfaces() + + return &Contract{ + interfaces: interfaces, + Type: contractTypeForInterfaces(interfaces), + }, nil } // IsERC20 returns true iff the contract interfaces contains ERC-20. diff --git a/eth/tracers/blocknative/decoder/decoder.go b/eth/tracers/blocknative/decoder/decoder.go index e3692b28bfaa..077e331438b5 100644 --- a/eth/tracers/blocknative/decoder/decoder.go +++ b/eth/tracers/blocknative/decoder/decoder.go @@ -72,95 +72,6 @@ func (d *Decoder) DecodeCallFrame(sender common.Address, receiver common.Address return cf, nil } -func (d *Decoder) DecodeCallFrameEnd(cf *CallFrame) error { - if cf == nil || cf.Contract == nil || cf.CallData == nil { - return nil - } - - // Check updated balances for taxable transfers and look for active taxes. - // If we find them, add them as new transfers. - transfers := cf.CallData.Transfers - for _, transfer := range transfers { - // First check if we set a balanceBeforeTo. If we didn't then we can't - // utilize this inference. - if transfer.balanceBeforeTo == nil { - continue - } - - // Get the balance after the transfer. At this point balanceOf worked - // once so we don't expect it to fail. If it does then we report it as - // an error so we can inspect later, and then we continue to the next - // transfer. - var ( - err error - balanceAfterTo *big.Int - ) - switch cf.Contract.Type { - case ContractTypeERC20: - if balanceAfterTo, err = evmCallMethodBalanceOf(d.evm.CallCode, cf.Contract.address, transfer.To); err != nil { - log.Error("failed to get balance after for receiver", "err", err) - continue - } - case ContractTypeERC1155: - if balanceAfterTo, err = evmCallMethodBalanceOf2(d.evm.CallCode, cf.Contract.address, transfer.To, transfer.TokenID); err != nil { - log.Error("failed to get balance after for receiver", "err", err) - continue - } - default: - continue - } - - // If the increase in balance of the transfer recipient is less than we - // decoded it to be, then we know that the transfer was taxed. - // - // We don't know where the tax went but it will often go to the contract - // itself so we check the contract balance to see if that's the case. - decodedValue := transfer.Value.ToInt() - deltaTo := balanceAfterTo.Sub(balanceAfterTo, transfer.balanceBeforeTo) - if deltaTo.Cmp(decodedValue) < 0 { - // First, update the transfer value to the actual delta. - transfer.Value = NewAmount(deltaTo) - - // Now let's see if the contract was the tax recipient. - balanceAfterContract, err := evmCallMethodBalanceOf(d.evm.CallCode, cf.Contract.address, cf.Contract.address) - if err != nil { - log.Error("failed to get balance after for contract", "err", err) - continue - } - deltaContract := balanceAfterContract.Sub(balanceAfterContract, transfer.balanceBeforeContract) - if deltaContract.Sign() == 1 { - // The contract balance increased so we know at least some of - // the tax went there. Add a tax transfer. - cf.Transfers = append(cf.Transfers, &Transfer{ - Asset: transfer.Asset, - From: transfer.From, - - To: cf.Contract.address, - Value: NewAmount(deltaContract), - }) - } - - // Check to see if there was a tax amount not accounted for by - // subtracting the known deltas from the decoded value. - unaccountedTax := new(big.Int).Add(deltaTo, deltaContract) - unaccountedTax.Sub(decodedValue, unaccountedTax) - if unaccountedTax.Sign() == 1 { - cf.Transfers = append(cf.Transfers, &Transfer{ - Asset: transfer.Asset, - From: transfer.From, - - To: common.Address{}, - Value: NewAmount(unaccountedTax), - }) - } - } - } - - d.balances.captureCallFrameEnd(cf) - - return nil -} - // DecodeContract decodes the contract at the given address. func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { // Check the cache for an existing entry. @@ -182,8 +93,10 @@ func (d *Decoder) DecodeContract(addr common.Address) (*Contract, error) { } // We have an unknown contract; decode itm, add it to the cache, and return it. - contract = &Contract{address: addr} - decodeContract(contract, bytecode) + contract, err := decodeContract(bytecode) + if err != nil { + return nil, err + } d.caches.contracts.Add(addr, contract) return contract, nil } @@ -217,11 +130,14 @@ func (d *Decoder) decodeAsset(contract *Contract, assetID AssetID) (*AssetMetada } // Cache miss; decode and add to the cache. + asset, err := DecodeAsset(d.evm.CallCode, contract, assetID) if err != nil { return nil, err } + d.caches.assets.Add(assetID, asset) + return asset, nil } diff --git a/eth/tracers/blocknative/decoder/evm_caller.go b/eth/tracers/blocknative/decoder/evm_caller.go deleted file mode 100644 index 5e5bdd9b1fd0..000000000000 --- a/eth/tracers/blocknative/decoder/evm_caller.go +++ /dev/null @@ -1,121 +0,0 @@ -package decoder - -import ( - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -var ( - ErrUnexpectedDecodedSize = fmt.Errorf("unexpected decoded size") - ErrUnexpectedType = fmt.Errorf("unexpected type") -) - -// -// General callers -// - -// callAndDecodeString calls a method and decodes the result as a string. -func callAndDecodeString(evmCall evmCallFn, addr common.Address, msg []byte) (string, error) { - // Load bytes from the EVM. - ret, err := evmCall(addr, msg) - if err != nil { - return "", err - } - - // Parse into a string. - stringIntf, err := abiArgs.singleString.Unpack(ret) - if err != nil { - return "", fmt.Errorf("decoding string: %w", err) - } - if len(stringIntf) < len(abiArgs.singleString) { - return "", fmt.Errorf("decoding string: %w", ErrUnexpectedDecodedSize) - } - str, ok := stringIntf[0].(string) - if !ok { - return "", fmt.Errorf("decoding string: %w", ErrUnexpectedType) - } - - return str, nil -} - -// callAndDecodeUint8 calls a method and decodes the result as a uint8. -func callAndDecodeUint8(evmCall evmCallFn, addr common.Address, msg []byte) (uint8, error) { - // Load bytes from the EVM. - ret, err := evmCall(addr, msg) - if err != nil { - return 0, err - } - - // Parse into a uint8. - if len(ret) < 1 { - return 0, fmt.Errorf("decoding uint8: %w", ErrUnexpectedDecodedSize) - } - return ret[len(ret)-1], nil -} - -// callAndDecodeUint256 calls a method and decodes the result as a *big.Int. -func callAndDecodeUint256(evmCall evmCallFn, addr common.Address, msg []byte) (*big.Int, error) { - ret, err := evmCall(addr, msg) - if err != nil { - return nil, err - } - if len(ret) > 32 { - return nil, fmt.Errorf("decoding uint256: %w", ErrUnexpectedDecodedSize) - } - return new(big.Int).SetBytes(ret), nil -} - -// -// Specific method callers -// - -// evmCallMethodName decodes the name of an asset from the EVM. -func evmCallMethodName(evmCall evmCallFn, addr common.Address) (string, error) { - return callAndDecodeString(evmCall, addr, methodIDName) -} - -// evmCallMethodSymbol decodes the symbol of an asset from the EVM. -func evmCallMethodSymbol(evmCall evmCallFn, addr common.Address) (string, error) { - return callAndDecodeString(evmCall, addr, methodIDSymbol) -} - -// evmCallMethodDecimals decodes the decimals of an asset from the EVM. -func evmCallMethodDecimals(evmCall evmCallFn, addr common.Address) (uint8, error) { - return callAndDecodeUint8(evmCall, addr, methodIDDecimals) -} - -// evmCallMethodTokenURI decodes the tokenURI of an asset from the EVM. -func evmCallMethodTokenURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { - tokenIDBytes := tokenID.Bytes() - if len(tokenIDBytes) > 32 { - return "", fmt.Errorf("tokenID is too large") - } - common.LeftPadBytes(tokenIDBytes, 32) - input := append(methodIDTokenURI, tokenIDBytes...) - return callAndDecodeString(evmCall, addr, input) -} - -// evmCallMethodURI decodes the URI of an asset from the EVM. -func evmCallMethodURI(evmCall evmCallFn, addr common.Address, tokenID *big.Int) (string, error) { - tokenIDBytes := common.LeftPadBytes(tokenID.Bytes(), 32) - input := append(methodIDURI, tokenIDBytes...) - return callAndDecodeString(evmCall, addr, input) -} - -// evmCallMethodBalanceOf decodes the balance of an asset from the EVM. -func evmCallMethodBalanceOf(evmCall evmCallFn, addr common.Address, owner common.Address) (*big.Int, error) { - ownerBytes := common.LeftPadBytes(owner.Bytes(), 32) - input := append(methodIDBalanceOf, ownerBytes...) - return callAndDecodeUint256(evmCall, addr, input) -} - -// evmCallMethodBalanceOf2 decodes the balance of an asset from the EVM. -func evmCallMethodBalanceOf2(evmCall evmCallFn, addr common.Address, owner common.Address, tokenID *big.Int) (*big.Int, error) { - tokenIDBytes := common.LeftPadBytes(tokenID.Bytes(), 32) - ownerBytes := common.LeftPadBytes(owner.Bytes(), 32) - input := append(methodIDBalanceOf2, ownerBytes...) - input = append(input, tokenIDBytes...) - return callAndDecodeUint256(evmCall, addr, input) -} diff --git a/eth/tracers/blocknative/decoder/types.go b/eth/tracers/blocknative/decoder/types.go index 34194f491e59..251470e80268 100644 --- a/eth/tracers/blocknative/decoder/types.go +++ b/eth/tracers/blocknative/decoder/types.go @@ -3,9 +3,8 @@ package decoder import ( "encoding/json" "fmt" - "math/big" - "github.com/ethereum/go-ethereum/common" + "math/big" ) type CallFrame struct { @@ -15,7 +14,6 @@ type CallFrame struct { type Contract struct { Type ContractType `json:"type,omitempty"` - address common.Address interfaces []Interface } @@ -32,9 +30,6 @@ type Transfer struct { To common.Address `json:"to"` Value *Amount `json:"value"` TokenID *big.Int `json:"tokenID,omitempty"` - - balanceBeforeTo *big.Int - balanceBeforeContract *big.Int } type Asset struct { diff --git a/eth/tracers/blocknative/decoder_evm.go b/eth/tracers/blocknative/decoder_evm.go index bca14175f72a..75f762a95a51 100644 --- a/eth/tracers/blocknative/decoder_evm.go +++ b/eth/tracers/blocknative/decoder_evm.go @@ -1,10 +1,9 @@ package blocknative import ( - "math" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/vm" + "math" ) // decoderEVM contains the functionality required by the decoder from the EVM. @@ -19,19 +18,9 @@ func (d decoderEVM) GetCode(addr common.Address) []byte { } // CallCode executes the given method on the code at the given address. -var callCodeCallerAddr = vm.AccountRef(common.HexToAddress("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")) - func (d decoderEVM) CallCode(addr common.Address, method []byte) ([]byte, error) { code := d.StateDB.GetCode(addr) - contract := vm.NewContract(callCodeCallerAddr, vm.AccountRef(addr), common.Big0, math.MaxUint64) + contract := vm.NewContract(vm.AccountRef(common.Address{}), vm.AccountRef(addr), common.Big0, math.MaxUint64) contract.SetCallCode(&addr, d.StateDB.GetCodeHash(addr), code) - - // Stash the tracer and disable tracing for the call, then replace it. - // Otherwise the call will be traced as part of the current trace. - t := d.EVM.Config.Tracer - d.EVM.Config.Tracer = nil - ret, err := d.Interpreter().Run(contract, method, false) - d.EVM.Config.Tracer = t - - return ret, err + return d.Interpreter().Run(contract, method, false) } diff --git a/eth/tracers/blocknative/tracer.go b/eth/tracers/blocknative/tracer.go index 9d69a088c8fc..30808cb55f20 100644 --- a/eth/tracers/blocknative/tracer.go +++ b/eth/tracers/blocknative/tracer.go @@ -242,18 +242,6 @@ func finalizeCallFrame(call *CallFrame, output []byte, gasUsed uint64, err error call.Output = bytesToHex(output) } -func cloneBytes(src []byte) []byte { - dst := make([]byte, len(src)) - copy(dst, src) - return dst -} - -// EmptyCache is for testing purposes. It clears the global cache so tests don't -// interfere with each other. -func EmptyCache() { - decoderCache = decoder.NewCaches() -} - // // Unused interface methods. // diff --git a/eth/tracers/blocknative/utils.go b/eth/tracers/blocknative/utils.go index d0a18b032c99..96d9262d4c72 100644 --- a/eth/tracers/blocknative/utils.go +++ b/eth/tracers/blocknative/utils.go @@ -1,39 +1,31 @@ package blocknative import ( + "encoding/hex" "math/big" "strconv" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common" ) -// Big overrides hexutil.Big to to use a faster serialization method. -type Big hexutil.Big - -// MarshalText implements encoding.TextMarshaler -func (b Big) MarshalText() ([]byte, error) { - b2 := big.Int(b) - return []byte("0x" + b2.Text(16)), nil +func bytesToHex(s []byte) string { + return "0x" + common.Bytes2Hex(s) } -func (b Big) UnmarshalJSON(input []byte) error { - b2 := hexutil.Big(b) - return b2.UnmarshalJSON(input) +func bigToHex(n *big.Int) string { + if n == nil { + return "" + } + return "0x" + n.Text(16) } -// Uint64 overrides hexutil.Uint64 to to use a faster serialization method. -type Uint64 hexutil.Uint64 - -// MarshalText implements encoding.TextMarshaler. -func (b Uint64) MarshalText() ([]byte, error) { - return []byte("0x" + strconv.FormatUint(uint64(b), 16)), nil +func uintToHex(n uint64) string { + return "0x" + strconv.FormatUint(n, 16) } -func (b *Uint64) UnmarshalJSON(input []byte) error { - u := hexutil.Uint64(*b) - if err := u.UnmarshalJSON(input); err != nil { - return err - } - *b = Uint64(u) - return nil +func addrToHex(a common.Address) string { + var buf [len(a)*2 + 2]byte + copy(buf[:2], "0x") + hex.Encode(buf[2:], a[:]) + return string(buf[:]) } diff --git a/eth/tracers/internal/tracetest/blocknative_test.go b/eth/tracers/internal/tracetest/blocknative_test.go index c40e242d0d6a..ff1e94f590ca 100644 --- a/eth/tracers/internal/tracetest/blocknative_test.go +++ b/eth/tracers/internal/tracetest/blocknative_test.go @@ -19,7 +19,6 @@ import ( "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers/blocknative" "github.com/ethereum/go-ethereum/eth/tracers/blocknative/decoder" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/tests" ) @@ -43,7 +42,6 @@ type blocknativeTracerTest struct { } func TestBlocknativeTracer(t *testing.T) { - log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(true))) testBlocknativeTracer("blocknative", t) testBlocknativeTracer("blocknative/with_decoding", t) } diff --git a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json index 9514fecaa656..151c773bfb9b 100644 --- a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json +++ b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/delegatecall.json @@ -313,6 +313,26 @@ ] } }, + { + "type": "CALL", + "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" + }, + { + "type": "CALL", + "from": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" + }, { "type": "CALL", "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", @@ -465,6 +485,26 @@ ] } }, + { + "type": "CALL", + "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" + }, + { + "type": "CALL", + "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", + "to": "0x0000000000000000000000000000000000000004", + "value": "0x0", + "gas": "0xf", + "gasUsed": "0xf", + "input": "0x", + "output": "0x" + }, { "type": "CALL", "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", @@ -516,12 +556,11 @@ }, "blockContext": { "number": 2340153, + "stateRoot": "0xfd6b6b8e67375609b44379ad18b293b1d6369d8e93e17f8240600a3f990caeae", "baseFee": 16711680, "time": 1475034716, - "gasLimit": 1500062, "coinbase": "0x61c808d82a3ac53231750dadc13c777b59310bd9", - "stateRoot": "0xfd6b6b8e67375609b44379ad18b293b1d6369d8e93e17f8240600a3f990caeae", - "random": "0x0000000000000000000000000000000000000000000000000000000000000000" + "gasLimit": 1500062 }, "balanceChanges": [ { diff --git a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json b/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json deleted file mode 100644 index 7a3cf2e5da56..000000000000 --- a/eth/tracers/internal/tracetest/testdata/blocknative/with_decoding/erc20_transfer_with_tax.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "genesis": { - "baseFeePerGas": "15276637384", - "difficulty": "0", - "extraData": "0x6275696c64657230783639", - "gasLimit": "30000000", - "hash": "0x8d67e46fc4bb9facbaeb26627d30e2567db96e66eb22c9f811a6f44e277b5ebf", - "miner": "0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263", - "mixHash": "0x572668f17a2e0a384117e5ae5f062b1ab2bbb25213e509d1f95dce2f6f90c0f9", - "nonce": "0x0000000000000000", - "number": "16967879", - "stateRoot": "0xb0fe203965f60ee45cf6686f06e2f9b0fe228446b668b3a5c1466b4eabca1dca", - "timestamp": "1674198911", - "totalDifficulty": "5.8750003716598352816469e+22", - "alloc": { - "0xf527A5Ee2155fAD99A5bBB23c9e52B0a11b99dD4": { - "balance": "0x3C3A38E5AB72FC0000", - "nonce": "3" - }, - "0xc3761EB917CD790B30dAD99f6Cc5b4Ff93C4F9eA": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c8063313ce56711610071578063313ce5671461015f57806370a082311461016e57806395d89b4114610197578063a9059cbb146101b6578063b632612b146101c9578063dd62ed3e146101d157600080fd5b806306fdde03146100b9578063095ea7b3146100f057806318160ddd1461011357806323b872dd1461012457806327e235e314610137578063300126ff14610157575b600080fd5b6040805180820190915260098152682a30bc102a37b5b2b760b91b60208201525b6040516100e791906102a1565b60405180910390f35b6101036100fe36600461030b565b6101df565b60405190151581526020016100e7565b60005b6040519081526020016100e7565b610103610132366004610335565b6101e8565b610116610145366004610371565b60006020819052908152604090205481565b610116600181565b604051600281526020016100e7565b61011661017c366004610371565b6001600160a01b031660009081526020819052604090205490565b6040805180820190915260038152620a882b60eb1b60208201526100da565b6101036101c436600461030b565b6101fc565b610116606481565b6101166100fe36600461038c565b60005b92915050565b60006101f4838361020f565b949350505050565b6000610208838361020f565b9392505050565b600080606461021f6001856103d5565b61022991906103ec565b90506000610237828561040e565b905080600080876001600160a01b03166001600160a01b03168152602001908152602001600020600082825461026d9190610421565b90915550503060009081526020819052604081208054849290610291908490610421565b9091555060019695505050505050565b600060208083528351808285015260005b818110156102ce578581018301518582016040015282016102b2565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461030657600080fd5b919050565b6000806040838503121561031e57600080fd5b610327836102ef565b946020939093013593505050565b60008060006060848603121561034a57600080fd5b610353846102ef565b9250610361602085016102ef565b9150604084013590509250925092565b60006020828403121561038357600080fd5b610208826102ef565b6000806040838503121561039f57600080fd5b6103a8836102ef565b91506103b6602084016102ef565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176101e2576101e26103bf565b60008261040957634e487b7160e01b600052601260045260246000fd5b500490565b818103818111156101e2576101e26103bf565b808201808211156101e2576101e26103bf56fea2646970667358221220cefe50dd4d581917165a9a4385cdd9446091c1e068ff1a11713ca3ceed8e7ad064736f6c63430008150033" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 10, - "eip150Block": 10, - "eip155Block": 10, - "eip158Block": 10, - "byzantiumBlock": 10, - "constantinopleBlock": 10, - "petersburgBlock": 10, - "istanbulBlock": 10, - "berlinBlock": 10, - "londonBlock": 10 - } - }, - "tracerConfig": { - "decode": true - }, - "context": { - "number": "16967879", - "difficulty": "58750003716598352816469", - "timestamp": "1674198923", - "gasLimit": "30000000", - "miner": "0x4675C7e5BaAFBFFbca748158bEcBA61ef3b0a263" - }, - "input": "0x02f8b301038505b3524e108505b3524e108405f5e10094c3761eb917cd790b30dad99f6cc5b4ff93c4f9ea80b844a9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007cac080a07371e0060c5a04e594e52bc949f0155ef29c9205cfce0dffebe6cef23a68c8eba00ff5c780cf75d1e6eeb9d08719e2988bb09e1f4bd18af3ee357dd47186265160", - "result": { - "type": "CALL", - "from": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "to": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "value": "0x0", - "gas": "0x5f58c50", - "gasUsed": "0xa188", - "input": "0xa9059cbb000000000000000000000000fba9f22d040e53e5fac36698080cee3dd3792262000000000000000000000000000000000000000000000207b733832c88c007ca", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "decoded": { - "type": "erc20", - "method": "0xa9059cbb", - "signature": "transfer(address,uint256)", - "args": [ - "0xFbA9F22D040e53e5FAc36698080cee3dD3792262", - "9587061213415306430410" - ] - }, - "blockContext": { - "number": 16967879, - "baseFee": 16711680, - "time": 1674198923, - "gasLimit": 30000000, - "coinbase": "0x4675c7e5baafbffbca748158becba61ef3b0a263", - "stateRoot": "0x4b7559defbb79e8de7975492f30fb5f6fae2d5afc06ef5e4905d97e346355265", - "random": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "balanceChanges": [ - { - "address": "0x4675c7e5baafbffbca748158becba61ef3b0a263", - "balanceChanges": [ - { - "delta": "1011744513820800", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "breakdown": [ - { - "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "1011744513820800" - } - ] - } - ] - }, - { - "address": "0xfba9f22d040e53e5fac36698080cee3dd3792262", - "balanceChanges": [ - { - "delta": "9491190601281153366106", - "asset": { - "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "type": "erc20", - "name": "Tax Token", - "symbol": "TAX", - "decimals": 2 - }, - "breakdown": [ - { - "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "9491190601281153366106" - } - ] - } - ] - }, - { - "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "balanceChanges": [ - { - "delta": "95870612134153064304", - "asset": { - "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "type": "erc20", - "name": "Tax Token", - "symbol": "TAX", - "decimals": 2 - }, - "breakdown": [ - { - "counterparty": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "amount": "95870612134153064304" - } - ] - } - ] - }, - { - "address": "0xf527a5ee2155fad99a5bbb23c9e52b0a11b99dd4", - "balanceChanges": [ - { - "delta": "-1012435575212160", - "asset": { - "address": "0x0000000000000000000000000000000000000000", - "type": "eth", - "name": "Ether", - "symbol": "ETH", - "decimals": 18 - }, - "breakdown": [ - { - "counterparty": "0x0000000000000000000000000000000000000000", - "amount": "-691061391360" - }, - { - "counterparty": "0x4675c7e5baafbffbca748158becba61ef3b0a263", - "amount": "-1011744513820800" - } - ] - }, - { - "delta": "-9587061213415306430410", - "asset": { - "address": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "type": "erc20", - "name": "Tax Token", - "symbol": "TAX", - "decimals": 2 - }, - "breakdown": [ - { - "counterparty": "0xfba9f22d040e53e5fac36698080cee3dd3792262", - "amount": "-9491190601281153366106" - }, - { - "counterparty": "0xc3761eb917cd790b30dad99f6cc5b4ff93c4f9ea", - "amount": "-95870612134153064304" - } - ] - } - ] - } - ] - } -} - \ No newline at end of file