diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba6c21c97c..b3ef706bac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: go mod edit -replace github.com/ava-labs/avalanchego=./avalanchego go mod tidy go clean -modcache # avoid conflicts with the golangci-lint-action cache - - run: ./scripts/lint_allowed_geth_imports.sh + - run: ./scripts/lint_allowed_eth_imports.sh shell: bash - name: golangci-lint uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc #v3 @@ -102,6 +102,12 @@ jobs: go generate -run "go.uber.org/mock/mockgen" ./... git add --intent-to-add --all git diff --exit-code + - name: fjl/gencodec generated files are up to date + run: | + grep -lr -E '^// Code generated by github\.com\/fjl\/gencodec\. DO NOT EDIT\.$' . | xargs -r rm + go generate -run "github.com/fjl/gencodec" ./... + git add --intent-to-add --all + git diff --exit-code - run: ./scripts/build.sh evm shell: bash - run: ./scripts/build_test.sh @@ -127,7 +133,7 @@ jobs: with: go-version-file: "go.mod" - name: Run e2e tests - uses: ava-labs/avalanchego/.github/actions/run-monitored-tmpnet-cmd@6c72dfc4254a3d157bba5c9c45135cb563b813e7 + uses: ava-labs/avalanchego/.github/actions/run-monitored-tmpnet-cmd@3a6bfac46f43ac2d7cc1e3fc8576ff6a8594bafa with: run: ./scripts/tests.e2e.sh run_env: E2E_SERIAL=1 diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go index 1a6e224090..cb924a0189 100644 --- a/accounts/abi/abi.go +++ b/accounts/abi/abi.go @@ -34,8 +34,8 @@ import ( "io" "math/big" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" ) // The ABI holds information about a contract's context and available diff --git a/accounts/abi/abi_extra_test.go b/accounts/abi/abi_extra_test.go index 52bce1b0a4..32d3c2d0b5 100644 --- a/accounts/abi/abi_extra_test.go +++ b/accounts/abi/abi_extra_test.go @@ -9,7 +9,7 @@ import ( "strings" "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/require" ) diff --git a/accounts/abi/abi_test.go b/accounts/abi/abi_test.go index 023ff5cc4e..ee46105203 100644 --- a/accounts/abi/abi_test.go +++ b/accounts/abi/abi_test.go @@ -36,9 +36,9 @@ import ( "strings" "testing" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/assert" ) diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go index cdce77d0d8..a724adb174 100644 --- a/accounts/abi/bind/auth.go +++ b/accounts/abi/bind/auth.go @@ -33,13 +33,13 @@ import ( "io" "math/big" - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/accounts/external" - "github.com/ava-labs/coreth/accounts/keystore" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/accounts" + "github.com/ava-labs/libevm/accounts/external" + "github.com/ava-labs/libevm/accounts/keystore" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" ) // ErrNoChainID is returned whenever the user failed to specify a chain id. diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index 4cd21c399b..f9ce3be9ab 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -31,9 +31,9 @@ import ( "errors" "math/big" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/common" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) var ( @@ -64,7 +64,7 @@ type ContractCaller interface { // CallContract executes an Ethereum contract call with the specified data as the // input. - CallContract(ctx context.Context, call interfaces.CallMsg, blockNumber *big.Int) ([]byte, error) + CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) } // AcceptedContractCaller defines methods to perform contract calls on the pending state. @@ -75,7 +75,7 @@ type AcceptedContractCaller interface { AcceptedCodeAt(ctx context.Context, contract common.Address) ([]byte, error) // AcceptedCallContract executes an Ethereum contract call against the accepted state. - AcceptedCallContract(ctx context.Context, call interfaces.CallMsg) ([]byte, error) + AcceptedCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) } // BlockHashContractCaller defines methods to perform contract calls on a specific block hash. @@ -86,7 +86,7 @@ type BlockHashContractCaller interface { CodeAtHash(ctx context.Context, contract common.Address, blockHash common.Hash) ([]byte, error) // CallContractAtHash executes an Ethereum contract call against the state at the specified block hash. - CallContractAtHash(ctx context.Context, call interfaces.CallMsg, blockHash common.Hash) ([]byte, error) + CallContractAtHash(ctx context.Context, call ethereum.CallMsg, blockHash common.Hash) ([]byte, error) } // ContractTransactor defines the methods needed to allow operating with a contract @@ -94,10 +94,10 @@ type BlockHashContractCaller interface { // used when the user does not provide some needed values, but rather leaves it up // to the transactor to decide. type ContractTransactor interface { - interfaces.GasEstimator - interfaces.GasPricer - interfaces.GasPricer1559 - interfaces.TransactionSender + ethereum.GasEstimator + ethereum.GasPricer + ethereum.GasPricer1559 + ethereum.TransactionSender // HeaderByNumber returns a block header from the current canonical chain. If // number is nil, the latest known header is returned. @@ -119,7 +119,7 @@ type DeployBackend interface { // ContractFilterer defines the methods needed to access log events using one-off // queries or continuous event subscriptions. type ContractFilterer interface { - interfaces.LogFilterer + ethereum.LogFilterer } // ContractBackend defines the methods needed to work with contracts on a read-write basis. diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index f1594e525b..0b2cb40da1 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -30,10 +30,11 @@ import ( "context" "github.com/ava-labs/coreth/accounts/abi/bind" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/ethclient/simulated" "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/common" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // Verify that SimulatedBackend implements required interfaces @@ -42,14 +43,14 @@ var ( _ bind.ContractBackend = (*SimulatedBackend)(nil) _ bind.DeployBackend = (*SimulatedBackend)(nil) - _ interfaces.ChainReader = (*SimulatedBackend)(nil) - _ interfaces.ChainStateReader = (*SimulatedBackend)(nil) - _ interfaces.TransactionReader = (*SimulatedBackend)(nil) - _ interfaces.TransactionSender = (*SimulatedBackend)(nil) - _ interfaces.ContractCaller = (*SimulatedBackend)(nil) - _ interfaces.GasEstimator = (*SimulatedBackend)(nil) - _ interfaces.GasPricer = (*SimulatedBackend)(nil) - _ interfaces.LogFilterer = (*SimulatedBackend)(nil) + _ ethereum.ChainReader = (*SimulatedBackend)(nil) + _ ethereum.ChainStateReader = (*SimulatedBackend)(nil) + _ ethereum.TransactionReader = (*SimulatedBackend)(nil) + _ ethereum.TransactionSender = (*SimulatedBackend)(nil) + _ ethereum.ContractCaller = (*SimulatedBackend)(nil) + _ ethereum.GasEstimator = (*SimulatedBackend)(nil) + _ ethereum.GasPricer = (*SimulatedBackend)(nil) + _ ethereum.LogFilterer = (*SimulatedBackend)(nil) _ interfaces.AcceptedStateReader = (*SimulatedBackend)(nil) _ interfaces.AcceptedContractCaller = (*SimulatedBackend)(nil) ) diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 34f60300e4..c638e94148 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -35,13 +35,13 @@ import ( "sync" "github.com/ava-labs/coreth/accounts/abi" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/interfaces" + "github.com/ava-labs/coreth/nativeasset" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/event" ) const basefeeWiggleMultiplier = 2 @@ -197,7 +197,7 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri return err } var ( - msg = interfaces.CallMsg{From: opts.From, To: &c.address, Data: input} + msg = ethereum.CallMsg{From: opts.From, To: &c.address, Data: input} ctx = ensureContext(opts.Context) code []byte output []byte @@ -308,14 +308,14 @@ func wrapNativeAssetCall(opts *TransactOpts, contract *common.Address, input []b return nil, nil, errNativeAssetDeployContract } // wrap input with native asset call params - input = vm.PackNativeAssetCallInput( + input = nativeasset.PackNativeAssetCallInput( *contract, opts.NativeAssetCall.AssetID, opts.NativeAssetCall.AssetAmount, input, ) // target addr is now precompile - contract = &vm.NativeAssetCallAddr + contract = &nativeasset.NativeAssetCallAddr } return contract, input, nil } @@ -424,7 +424,7 @@ func (c *BoundContract) estimateGasLimit(opts *TransactOpts, contract *common.Ad return 0, ErrNoCode } } - msg := interfaces.CallMsg{ + msg := ethereum.CallMsg{ From: opts.From, To: contract, GasPrice: gasPrice, @@ -513,7 +513,7 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int // Start the background filtering logs := make(chan types.Log, 128) - config := interfaces.FilterQuery{ + config := ethereum.FilterQuery{ Addresses: []common.Address{c.address}, Topics: topics, FromBlock: new(big.Int).SetUint64(opts.Start), @@ -562,7 +562,7 @@ func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]inter // Start the background filtering logs := make(chan types.Log, 128) - config := interfaces.FilterQuery{ + config := ethereum.FilterQuery{ Addresses: []common.Address{c.address}, Topics: topics, } diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index aa750dc208..8e08d24408 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -37,13 +37,13 @@ import ( "github.com/ava-labs/coreth/accounts/abi" "github.com/ava-labs/coreth/accounts/abi/bind" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/coreth/nativeasset" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" "github.com/stretchr/testify/assert" ) @@ -79,7 +79,7 @@ func (mt *mockTransactor) SuggestGasTipCap(ctx context.Context) (*big.Int, error return mt.gasTipCap, nil } -func (mt *mockTransactor) EstimateGas(ctx context.Context, call interfaces.CallMsg) (gas uint64, err error) { +func (mt *mockTransactor) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) { return 0, nil } @@ -101,7 +101,7 @@ func (mc *mockCaller) CodeAt(ctx context.Context, contract common.Address, block return mc.codeAtBytes, mc.codeAtErr } -func (mc *mockCaller) CallContract(ctx context.Context, call interfaces.CallMsg, blockNumber *big.Int) ([]byte, error) { +func (mc *mockCaller) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { mc.callContractBlockNumber = blockNumber return mc.callContractBytes, mc.callContractErr } @@ -121,7 +121,7 @@ func (mc *mockAcceptedCaller) AcceptedCodeAt(ctx context.Context, contract commo return mc.acceptedCodeAtBytes, mc.acceptedCodeAtErr } -func (mc *mockAcceptedCaller) AcceptedCallContract(ctx context.Context, call interfaces.CallMsg) ([]byte, error) { +func (mc *mockAcceptedCaller) AcceptedCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { mc.acceptedCallContractCalled = true return mc.acceptedCallContractBytes, mc.acceptedCallContractErr } @@ -141,7 +141,7 @@ func (mc *mockBlockHashCaller) CodeAtHash(ctx context.Context, contract common.A return mc.codeAtHashBytes, mc.codeAtHashErr } -func (mc *mockBlockHashCaller) CallContractAtHash(ctx context.Context, call interfaces.CallMsg, hash common.Hash) ([]byte, error) { +func (mc *mockBlockHashCaller) CallContractAtHash(ctx context.Context, call ethereum.CallMsg, hash common.Hash) ([]byte, error) { mc.callContractAtHashCalled = true return mc.callContractAtHashBytes, mc.callContractAtHashErr } @@ -404,8 +404,8 @@ func TestTransactNativeAssetCall(t *testing.T) { nativeCallTx, err := bc.Transact(opts, methodName, arg1, arg2) assert.Nil(err) // verify transformations - assert.Equal(vm.NativeAssetCallAddr, *nativeCallTx.To()) - unpackedAddr, unpackedAssetID, unpackedAssetAmount, unpackedData, err := vm.UnpackNativeAssetCallInput(nativeCallTx.Data()) + assert.Equal(nativeasset.NativeAssetCallAddr, *nativeCallTx.To()) + unpackedAddr, unpackedAssetID, unpackedAssetAmount, unpackedData, err := nativeasset.UnpackNativeAssetCallInput(nativeCallTx.Data()) assert.Nil(err) assert.NotEmpty(unpackedData) assert.Equal(unpackedData, normalCallTx.Data()) diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go index 3dfbb6d243..4347ba8169 100644 --- a/accounts/abi/bind/bind.go +++ b/accounts/abi/bind/bind.go @@ -40,7 +40,7 @@ import ( "unicode" "github.com/ava-labs/coreth/accounts/abi" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) // Lang is a target programming language selector to generate bindings for. diff --git a/accounts/abi/bind/bind_extra_test.go b/accounts/abi/bind/bind_extra_test.go new file mode 100644 index 0000000000..25c5a68e62 --- /dev/null +++ b/accounts/abi/bind/bind_extra_test.go @@ -0,0 +1,107 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package bind_test + +import ( + "bytes" + "math/big" + "testing" + + "github.com/ava-labs/coreth/accounts/abi" + "github.com/ava-labs/coreth/accounts/abi/bind" + "github.com/ava-labs/coreth/accounts/abi/bind/backends" + "github.com/ava-labs/coreth/eth/ethconfig" + "github.com/ava-labs/coreth/ethclient/simulated" + "github.com/ava-labs/coreth/node" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/stretchr/testify/require" +) + +// TestGetSenderNativeAssetCall checks that the NativeAssetCall proxies the +// caller address This behavior is disabled on the network and is only to test +// previous behavior. Note the test uses [params.TestApricotPhase2Config]. +func TestGetSenderNativeAssetCall(t *testing.T) { + // pragma solidity >=0.8.0 <0.9.0; + // contract GetSenderNativeAssetCall { + // address _sender; + // function getSender() public view returns (address){ + // return _sender; + // } + // function setSender() public { + // _sender = msg.sender; + // } + // } + const rawABI = `[ + { + "inputs": [], + "name": "getSender", + "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "setSender", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ]` + bytecode := common.FromHex(`6080604052348015600f57600080fd5b506101608061001f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806350c36a521461003b5780635e01eb5a14610045575b600080fd5b610043610063565b005b61004d6100a5565b60405161005a919061010f565b60405180910390f35b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100f9826100ce565b9050919050565b610109816100ee565b82525050565b60006020820190506101246000830184610100565b9291505056fea26469706673582212209023ce54f38e749b58f44e8da750354578080ce16df95037b7305ed7e480c36d64736f6c634300081b0033`) + const setSenderMethodName = "setSender" + const getSenderMethodName = "getSender" + + parsedABI, err := abi.JSON(bytes.NewReader([]byte(rawABI))) + require.NoError(t, err, "Failed to parse ABI") + + // Generate a new random account and a funded simulator + key, err := crypto.GenerateKey() + require.NoError(t, err, "Failed to generate key") + auth, err := bind.NewKeyedTransactorWithChainID(key, big.NewInt(1337)) + require.NoError(t, err, "Failed to create transactor") + alloc := types.GenesisAlloc{auth.From: {Balance: big.NewInt(1000000000000000000)}} + atApricotPhase2 := func(nodeConf *node.Config, ethConf *ethconfig.Config) { + chainConfig := *params.TestApricotPhase2Config + chainConfig.ChainID = big.NewInt(1337) + ethConf.Genesis.Config = &chainConfig + } + b := simulated.NewBackend(alloc, simulated.WithBlockGasLimit(10000000), atApricotPhase2) + sim := &backends.SimulatedBackend{ + Backend: b, + Client: b.Client(), + } + t.Cleanup(func() { + err = sim.Close() + require.NoError(t, err, "Failed to close simulator") + }) + + // Deploy the get/setSender contract + _, _, interactor, err := bind.DeployContract(auth, parsedABI, bytecode, sim) + require.NoError(t, err, "Failed to deploy interactor contract") + sim.Commit(false) + + // Setting NativeAssetCall in the transact opts will proxy the call through + // the NativeAssetCall precompile + opts := &bind.TransactOpts{ + From: auth.From, + Signer: auth.Signer, + NativeAssetCall: &bind.NativeAssetCallOpts{ + AssetAmount: big.NewInt(0), + }, + } + _, err = interactor.Transact(opts, setSenderMethodName) + require.NoError(t, err, "Failed to set sender") + sim.Commit(true) + + var results []any + err = interactor.Call(nil, &results, getSenderMethodName) + require.NoError(t, err, "Failed to get sender") + require.Len(t, results, 1) + addr, ok := results[0].(common.Address) + require.Truef(t, ok, "Expected %T, got %T", common.Address{}, results[0]) + require.Equal(t, addr, auth.From, "Address mismatch") +} diff --git a/accounts/abi/bind/bind_test.go b/accounts/abi/bind/bind_test.go index f20a336b82..162180c3f7 100644 --- a/accounts/abi/bind/bind_test.go +++ b/accounts/abi/bind/bind_test.go @@ -35,7 +35,7 @@ import ( "strings" "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) var bindTests = []struct { @@ -56,7 +56,7 @@ var bindTests = []struct { `contract NilContract {}`, []string{`606060405260068060106000396000f3606060405200`}, []string{`[]`}, - `"github.com/ethereum/go-ethereum/common"`, + `"github.com/ava-labs/libevm/common"`, ` if b, err := NewEmpty(common.Address{}, nil); b == nil || err != nil { t.Fatalf("combined binding (%v) nil or error (%v) not nil", b, nil) @@ -79,7 +79,7 @@ var bindTests = []struct { `https://ethereum.org/token`, []string{`60606040526040516107fd3803806107fd83398101604052805160805160a05160c051929391820192909101600160a060020a0333166000908152600360209081526040822086905581548551838052601f6002600019610100600186161502019093169290920482018390047f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56390810193919290918801908390106100e857805160ff19168380011785555b506101189291505b8082111561017157600081556001016100b4565b50506002805460ff19168317905550505050610658806101a56000396000f35b828001600101855582156100ac579182015b828111156100ac5782518260005055916020019190600101906100fa565b50508060016000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017557805160ff19168380011785555b506100c89291506100b4565b5090565b82800160010185558215610165579182015b8281111561016557825182600050559160200191906001019061018756606060405236156100775760e060020a600035046306fdde03811461007f57806323b872dd146100dc578063313ce5671461010e57806370a082311461011a57806395d89b4114610132578063a9059cbb1461018e578063cae9ca51146101bd578063dc3080f21461031c578063dd62ed3e14610341575b610365610002565b61036760008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b6103d5600435602435604435600160a060020a038316600090815260036020526040812054829010156104f357610002565b6103e760025460ff1681565b6103d560043560036020526000908152604090205481565b610367600180546020600282841615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156104eb5780601f106104c0576101008083540402835291602001916104eb565b610365600435602435600160a060020a033316600090815260036020526040902054819010156103f157610002565b60806020604435600481810135601f8101849004909302840160405260608381526103d5948235946024803595606494939101919081908382808284375094965050505050505060006000836004600050600033600160a060020a03168152602001908152602001600020600050600087600160a060020a031681526020019081526020016000206000508190555084905080600160a060020a0316638f4ffcb1338630876040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156102f25780820380516001836020036101000a031916815260200191505b50955050505050506000604051808303816000876161da5a03f11561000257505050509392505050565b6005602090815260043560009081526040808220909252602435815220546103d59081565b60046020818152903560009081526040808220909252602435815220546103d59081565b005b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103c75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a03821660009081526040902054808201101561041357610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b820191906000526020600020905b8154815290600101906020018083116104ce57829003601f168201915b505050505081565b600160a060020a03831681526040812054808301101561051257610002565b600160a060020a0380851680835260046020908152604080852033949094168086529382528085205492855260058252808520938552929052908220548301111561055c57610002565b816003600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816003600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816005600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054019250508190555082600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3939250505056`}, []string{`[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"},{"name":"_extraData","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"success","type":"bool"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"spentAllowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"inputs":[{"name":"initialSupply","type":"uint256"},{"name":"tokenName","type":"string"},{"name":"decimalUnits","type":"uint8"},{"name":"tokenSymbol","type":"string"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]`}, - `"github.com/ethereum/go-ethereum/common"`, + `"github.com/ava-labs/libevm/common"`, ` if b, err := NewToken(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -95,7 +95,7 @@ var bindTests = []struct { `https://ethereum.org/crowdsale`, []string{`606060408190526007805460ff1916905560a0806105a883396101006040529051608051915160c05160e05160008054600160a060020a03199081169095178155670de0b6b3a7640000958602600155603c9093024201600355930260045560058054909216909217905561052f90819061007990396000f36060604052361561006c5760e060020a600035046301cb3b20811461008257806329dcb0cf1461014457806338af3eed1461014d5780636e66f6e91461015f5780637a3a0e84146101715780637b3e5e7b1461017a578063a035b1fe14610183578063dc0d3dff1461018c575b61020060075460009060ff161561032357610002565b61020060035460009042106103205760025460015490106103cb576002548154600160a060020a0316908290606082818181858883f150915460025460408051600160a060020a039390931683526020830191909152818101869052517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6945090819003909201919050a15b60405160008054600160a060020a039081169230909116319082818181858883f150506007805460ff1916600117905550505050565b6103a160035481565b6103ab600054600160a060020a031681565b6103ab600554600160a060020a031681565b6103a160015481565b6103a160025481565b6103a160045481565b6103be60043560068054829081101561000257506000526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f8101547ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d409190910154600160a060020a03919091169082565b005b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a815481600160a060020a030219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a9004600160a060020a0316600160a060020a031663a9059cbb3360046000505484046040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505060408051600160a060020a03331681526020810184905260018183015290517fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf692509081900360600190a15b50565b5060a0604052336060908152346080819052600680546001810180835592939282908280158290116102025760020281600202836000526020600020918201910161020291905b8082111561039d57805473ffffffffffffffffffffffffffffffffffffffff19168155600060019190910190815561036a565b5090565b6060908152602090f35b600160a060020a03166060908152602090f35b6060918252608052604090f35b5b60065481101561010e576006805482908110156100025760009182526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600680549254600160a060020a0316928490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460405190915082818181858883f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf660066000508281548110156100025760008290526002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f01548154600160a060020a039190911691908490811015610002576002027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40015460408051600160a060020a0394909416845260208401919091526000838201525191829003606001919050a16001016103cc56`}, []string{`[{"constant":false,"inputs":[],"name":"checkGoalReached","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"deadline","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"beneficiary","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"tokenReward","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":true,"inputs":[],"name":"fundingGoal","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"amountRaised","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"price","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"funders","outputs":[{"name":"addr","type":"address"},{"name":"amount","type":"uint256"}],"type":"function"},{"inputs":[{"name":"ifSuccessfulSendTo","type":"address"},{"name":"fundingGoalInEthers","type":"uint256"},{"name":"durationInMinutes","type":"uint256"},{"name":"etherCostOfEachToken","type":"uint256"},{"name":"addressOfTokenUsedAsReward","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"backer","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"isContribution","type":"bool"}],"name":"FundTransfer","type":"event"}]`}, - `"github.com/ethereum/go-ethereum/common"`, + `"github.com/ava-labs/libevm/common"`, ` if b, err := NewCrowdsale(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -111,7 +111,7 @@ var bindTests = []struct { `https://ethereum.org/dao`, []string{`606060405260405160808061145f833960e06040529051905160a05160c05160008054600160a060020a03191633179055600184815560028490556003839055600780549182018082558280158290116100b8576003028160030283600052602060002091820191016100b891906101c8565b50506060919091015160029190910155600160a060020a0381166000146100a65760008054600160a060020a031916821790555b505050506111f18061026e6000396000f35b505060408051608081018252600080825260208281018290528351908101845281815292820192909252426060820152600780549194509250811015610002579081527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6889050815181546020848101517401000000000000000000000000000000000000000002600160a060020a03199290921690921760a060020a60ff021916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f9081018390048201949192919091019083901061023e57805160ff19168380011785555b50610072929150610226565b5050600060028201556001015b8082111561023a578054600160a860020a031916815560018181018054600080835592600290821615610100026000190190911604601f81901061020c57506101bb565b601f0160209004906000526020600020908101906101bb91905b8082111561023a5760008155600101610226565b5090565b828001600101855582156101af579182015b828111156101af57825182600050559160200191906001019061025056606060405236156100b95760e060020a6000350463013cf08b81146100bb578063237e9492146101285780633910682114610281578063400e3949146102995780635daf08ca146102a257806369bd34361461032f5780638160f0b5146103385780638da5cb5b146103415780639644fcbd14610353578063aa02a90f146103be578063b1050da5146103c7578063bcca1fd3146104b5578063d3c0715b146104dc578063eceb29451461058d578063f2fde38b1461067b575b005b61069c6004356004805482908110156100025790600052602060002090600a02016000506005810154815460018301546003840154600485015460068601546007870154600160a060020a03959095169750929560020194919360ff828116946101009093041692919089565b60408051602060248035600481810135601f81018590048502860185019096528585526107759581359591946044949293909201918190840183828082843750949650505050505050600060006004600050848154811015610002575090527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e600a8402908101547f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b909101904210806101e65750600481015460ff165b8061026757508060000160009054906101000a9004600160a060020a03168160010160005054846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816007016000505414155b8061027757506001546005820154105b1561109257610002565b61077560043560066020526000908152604090205481565b61077560055481565b61078760043560078054829081101561000257506000526003026000805160206111d18339815191528101547fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a820154600160a060020a0382169260a060020a90920460ff16917fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c689019084565b61077560025481565b61077560015481565b610830600054600160a060020a031681565b604080516020604435600481810135601f81018490048402850184019095528484526100b9948135946024803595939460649492939101918190840183828082843750949650505050505050600080548190600160a060020a03908116339091161461084d57610002565b61077560035481565b604080516020604435600481810135601f8101849004840285018401909552848452610775948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976084979196506024909101945090925082915084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806104ab5750604081205460078054909190811015610002579082526003026000805160206111d1833981519152015460a060020a900460ff16155b15610ce557610002565b6100b960043560243560443560005433600160a060020a03908116911614610b1857610002565b604080516020604435600481810135601f810184900484028501840190955284845261077594813594602480359593946064949293910191819084018382808284375094965050505050505033600160a060020a031660009081526006602052604081205481908114806105835750604081205460078054909190811015610002579082526003026000805160206111d18339815191520181505460a060020a900460ff16155b15610f1d57610002565b604080516020606435600481810135601f81018490048402850184019095528484526107759481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600460005086815481101561000257908252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01815090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005054149150610cdc565b6100b960043560005433600160a060020a03908116911614610f0857610002565b604051808a600160a060020a031681526020018981526020018060200188815260200187815260200186815260200185815260200184815260200183815260200182810382528981815460018160011615610100020316600290048152602001915080546001816001161561010002031660029004801561075e5780601f106107335761010080835404028352916020019161075e565b820191906000526020600020905b81548152906001019060200180831161074157829003601f168201915b50509a505050505050505050505060405180910390f35b60408051918252519081900360200190f35b60408051600160a060020a038616815260208101859052606081018390526080918101828152845460026001821615610100026000190190911604928201839052909160a08301908590801561081e5780601f106107f35761010080835404028352916020019161081e565b820191906000526020600020905b81548152906001019060200180831161080157829003601f168201915b50509550505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b600160a060020a03851660009081526006602052604081205414156108a957604060002060078054918290556001820180825582801582901161095c5760030281600302836000526020600020918201910161095c9190610a4f565b600160a060020a03851660009081526006602052604090205460078054919350908390811015610002575060005250600381026000805160206111d183398151915201805474ff0000000000000000000000000000000000000000191660a060020a85021781555b60408051600160a060020a03871681526020810186905281517f27b022af4a8347100c7a041ce5ccf8e14d644ff05de696315196faae8cd50c9b929181900390910190a15050505050565b505050915081506080604051908101604052808681526020018581526020018481526020014281526020015060076000508381548110156100025790600052602060002090600302016000508151815460208481015160a060020a02600160a060020a03199290921690921774ff00000000000000000000000000000000000000001916178255604083015180516001848101805460008281528690209195600293821615610100026000190190911692909204601f90810183900482019491929190910190839010610ad357805160ff19168380011785555b50610b03929150610abb565b5050600060028201556001015b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610aa15750610a42565b601f016020900490600052602060002090810190610a4291905b80821115610acf5760008155600101610abb565b5090565b82800160010185558215610a36579182015b82811115610a36578251826000505591602001919060010190610ae5565b50506060919091015160029190910155610911565b600183905560028290556003819055604080518481526020810184905280820183905290517fa439d3fa452be5e0e1e24a8145e715f4fd8b9c08c96a42fd82a855a85e5d57de9181900360600190a1505050565b50508585846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160070160005081905550600260005054603c024201816003016000508190555060008160040160006101000a81548160ff0219169083021790555060008160040160016101000a81548160ff02191690830217905550600081600501600050819055507f646fec02522b41e7125cfc859a64fd4f4cefd5dc3b6237ca0abe251ded1fa881828787876040518085815260200184600160a060020a03168152602001838152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610cc45780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1600182016005555b50949350505050565b6004805460018101808355909190828015829011610d1c57600a0281600a028360005260206000209182019101610d1c9190610db8565b505060048054929450918491508110156100025790600052602060002090600a02016000508054600160a060020a031916871781556001818101879055855160028381018054600082815260209081902096975091959481161561010002600019011691909104601f90810182900484019391890190839010610ed857805160ff19168380011785555b50610b6c929150610abb565b50506001015b80821115610acf578054600160a060020a03191681556000600182810182905560028381018054848255909281161561010002600019011604601f819010610e9c57505b5060006003830181905560048301805461ffff191690556005830181905560068301819055600783018190556008830180548282559082526020909120610db2916002028101905b80821115610acf57805474ffffffffffffffffffffffffffffffffffffffffff1916815560018181018054600080835592600290821615610100026000190190911604601f819010610eba57505b5050600101610e44565b601f016020900490600052602060002090810190610dfc9190610abb565b601f016020900490600052602060002090810190610e929190610abb565b82800160010185558215610da6579182015b82811115610da6578251826000505591602001919060010190610eea565b60008054600160a060020a0319168217905550565b600480548690811015610002576000918252600a027f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b01905033600160a060020a0316600090815260098201602052604090205490915060ff1660011415610f8457610002565b33600160a060020a031660009081526009820160205260409020805460ff1916600190811790915560058201805490910190558315610fcd576006810180546001019055610fda565b6006810180546000190190555b7fc34f869b7ff431b034b7b9aea9822dac189a685e0b015c7d1be3add3f89128e8858533866040518085815260200184815260200183600160a060020a03168152602001806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561107a5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b6006810154600354901315611158578060000160009054906101000a9004600160a060020a0316600160a060020a03168160010160005054670de0b6b3a76400000284604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111225780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f15050505060048101805460ff191660011761ff00191661010017905561116d565b60048101805460ff191660011761ff00191690555b60068101546005820154600483015460408051888152602081019490945283810192909252610100900460ff166060830152517fd220b7272a8b6d0d7d6bcdace67b936a8f175e6d5c1b3ee438b72256b32ab3af9181900360800190a1509291505056a66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688`}, []string{`[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"proposals","outputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"},{"name":"description","type":"string"},{"name":"votingDeadline","type":"uint256"},{"name":"executed","type":"bool"},{"name":"proposalPassed","type":"bool"},{"name":"numberOfVotes","type":"uint256"},{"name":"currentResult","type":"int256"},{"name":"proposalHash","type":"bytes32"}],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"executeProposal","outputs":[{"name":"result","type":"int256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"memberId","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"numProposals","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"members","outputs":[{"name":"member","type":"address"},{"name":"canVote","type":"bool"},{"name":"name","type":"string"},{"name":"memberSince","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"debatingPeriodInMinutes","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"minimumQuorum","outputs":[{"name":"","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"type":"function"},{"constant":false,"inputs":[{"name":"targetMember","type":"address"},{"name":"canVote","type":"bool"},{"name":"memberName","type":"string"}],"name":"changeMembership","outputs":[],"type":"function"},{"constant":true,"inputs":[],"name":"majorityMargin","outputs":[{"name":"","type":"int256"}],"type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"JobDescription","type":"string"},{"name":"transactionBytecode","type":"bytes"}],"name":"newProposal","outputs":[{"name":"proposalID","type":"uint256"}],"type":"function"},{"constant":false,"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"}],"name":"changeVotingRules","outputs":[],"type":"function"},{"constant":false,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"supportsProposal","type":"bool"},{"name":"justificationText","type":"string"}],"name":"vote","outputs":[{"name":"voteID","type":"uint256"}],"type":"function"},{"constant":true,"inputs":[{"name":"proposalNumber","type":"uint256"},{"name":"beneficiary","type":"address"},{"name":"etherAmount","type":"uint256"},{"name":"transactionBytecode","type":"bytes"}],"name":"checkProposalCode","outputs":[{"name":"codeChecksOut","type":"bool"}],"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"type":"function"},{"inputs":[{"name":"minimumQuorumForProposals","type":"uint256"},{"name":"minutesForDebate","type":"uint256"},{"name":"marginOfVotesForMajority","type":"int256"},{"name":"congressLeader","type":"address"}],"type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"recipient","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"description","type":"string"}],"name":"ProposalAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"position","type":"bool"},{"indexed":false,"name":"voter","type":"address"},{"indexed":false,"name":"justification","type":"string"}],"name":"Voted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"proposalID","type":"uint256"},{"indexed":false,"name":"result","type":"int256"},{"indexed":false,"name":"quorum","type":"uint256"},{"indexed":false,"name":"active","type":"bool"}],"name":"ProposalTallied","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"member","type":"address"},{"indexed":false,"name":"isMember","type":"bool"}],"name":"MembershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"minimumQuorum","type":"uint256"},{"indexed":false,"name":"debatingPeriodInMinutes","type":"uint256"},{"indexed":false,"name":"majorityMargin","type":"int256"}],"name":"ChangeOfRules","type":"event"}]`}, - `"github.com/ethereum/go-ethereum/common"`, + `"github.com/ava-labs/libevm/common"`, ` if b, err := NewDAO(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -138,7 +138,7 @@ var bindTests = []struct { ` "fmt" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" `, `if b, err := NewInputChecker(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -176,7 +176,7 @@ var bindTests = []struct { ` "fmt" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" `, `if b, err := NewOutputChecker(common.Address{}, nil); b == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", b, nil) @@ -217,7 +217,7 @@ var bindTests = []struct { "math/big" "reflect" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" `, `if e, err := NewEventChecker(common.Address{}, nil); e == nil || err != nil { t.Fatalf("binding (%v) nil or error (%v) not nil", e, nil) @@ -299,8 +299,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -355,8 +355,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -401,8 +401,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -458,9 +458,9 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -507,8 +507,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -574,8 +574,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -619,8 +619,8 @@ var bindTests = []struct { ` "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" `, ` // Create a simulator and wrap a non-deployed contract @@ -658,8 +658,8 @@ var bindTests = []struct { ` "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" `, ` // Create a simulator and wrap a non-deployed contract @@ -706,8 +706,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -755,9 +755,9 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -831,8 +831,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -924,9 +924,9 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/common" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -1115,8 +1115,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -1250,8 +1250,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` @@ -1392,8 +1392,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -1458,8 +1458,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Initialize test accounts @@ -1567,8 +1567,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/core/types" `, ` // Initialize test accounts @@ -1630,8 +1630,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/core/types" `, ` key, _ := crypto.GenerateKey() @@ -1692,8 +1692,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` // Generate a new random account and a funded simulator @@ -1753,8 +1753,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` key, _ := crypto.GenerateKey() @@ -1841,8 +1841,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` var ( @@ -1911,8 +1911,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, ` var ( @@ -1963,8 +1963,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, tester: ` var ( @@ -2011,8 +2011,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, tester: ` var ( @@ -2052,8 +2052,8 @@ var bindTests = []struct { "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/accounts/abi/bind/backends" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" `, tester: ` var ( @@ -2088,7 +2088,7 @@ var bindTests = []struct { bytecode: []string{"0x6080604052348015600f57600080fd5b5060958061001e6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80639d993132146041578063d02767c7146049578063ffa02795146051575b600080fd5b60476059565b005b604f605b565b005b6057605d565b005b565b565b56fea26469706673582212200382ca602dff96a7e2ba54657985e2b4ac423a56abe4a1f0667bc635c4d4371f64736f6c63430008110033"}, abi: []string{`[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_param","type":"address"}],"name":"_1TestEvent","type":"event"},{"inputs":[],"name":"_1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__1test","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"__2test","outputs":[],"stateMutability":"pure","type":"function"}]`}, imports: ` - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" `, tester: ` if b, err := NewNumericMethodName(common.Address{}, nil); b == nil || err != nil { diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 22dca1e71d..496599813a 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -103,10 +103,10 @@ import ( "github.com/ava-labs/coreth/accounts/abi" "github.com/ava-labs/coreth/accounts/abi/bind" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/core/types" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/event" ) // Reference imports to suppress errors if they are not otherwise used. @@ -114,7 +114,7 @@ var ( _ = errors.New _ = big.NewInt _ = strings.NewReader - _ = interfaces.NotFound + _ = ethereum.NotFound _ = bind.Bind _ = common.Big1 _ = types.BloomLookup @@ -443,7 +443,7 @@ var ( event string // Event name to use for unpacking event data logs chan types.Log // Log channel receiving the found contract events - sub interfaces.Subscription // Subscription for errors, completion and termination + sub ethereum.Subscription // Subscription for errors, completion and termination done bool // Whether the subscription completed delivering logs fail error // Occurred error to stop iteration } diff --git a/accounts/abi/bind/util.go b/accounts/abi/bind/util.go index 378f7ef877..cf2fc2691f 100644 --- a/accounts/abi/bind/util.go +++ b/accounts/abi/bind/util.go @@ -31,10 +31,10 @@ import ( "errors" "time" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/log" ) // WaitMined waits for tx to be mined on the blockchain. @@ -50,7 +50,7 @@ func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*ty return receipt, nil } - if errors.Is(err, interfaces.NotFound) { + if errors.Is(err, ethereum.NotFound) { logger.Trace("Transaction not yet mined") } else { logger.Trace("Receipt retrieval failed", "err", err) diff --git a/accounts/abi/bind/util_test.go b/accounts/abi/bind/util_test.go index 6f7afa56d2..5de577c083 100644 --- a/accounts/abi/bind/util_test.go +++ b/accounts/abi/bind/util_test.go @@ -34,11 +34,11 @@ import ( "time" "github.com/ava-labs/coreth/accounts/abi/bind" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/ethclient/simulated" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" ) diff --git a/accounts/abi/error.go b/accounts/abi/error.go index a968fd20c0..46b056c052 100644 --- a/accounts/abi/error.go +++ b/accounts/abi/error.go @@ -31,8 +31,8 @@ import ( "fmt" "strings" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" ) type Error struct { diff --git a/accounts/abi/event.go b/accounts/abi/event.go index f4f0f5d92d..39b55bb62c 100644 --- a/accounts/abi/event.go +++ b/accounts/abi/event.go @@ -30,8 +30,8 @@ import ( "fmt" "strings" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" ) // Event is an event potentially triggered by the EVM's LOG mechanism. The Event diff --git a/accounts/abi/event_test.go b/accounts/abi/event_test.go index 4a254e9950..63f9fb2ffe 100644 --- a/accounts/abi/event_test.go +++ b/accounts/abi/event_test.go @@ -35,8 +35,8 @@ import ( "strings" "testing" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/accounts/abi/method.go b/accounts/abi/method.go index 1da260da2c..e437d8d2a9 100644 --- a/accounts/abi/method.go +++ b/accounts/abi/method.go @@ -30,7 +30,7 @@ import ( "fmt" "strings" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/crypto" ) // FunctionType represents different types of functions a contract might have. diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go index 9f9f2b23d5..830df0b390 100644 --- a/accounts/abi/pack.go +++ b/accounts/abi/pack.go @@ -32,8 +32,8 @@ import ( "math/big" "reflect" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" ) // packBytesSlice packs the given bytes as [L, V] as the canonical representation diff --git a/accounts/abi/pack_test.go b/accounts/abi/pack_test.go index b13de922a5..c76866c369 100644 --- a/accounts/abi/pack_test.go +++ b/accounts/abi/pack_test.go @@ -37,7 +37,7 @@ import ( "strings" "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // TestPack tests the general pack/unpack tests in packing_test.go diff --git a/accounts/abi/packing_test.go b/accounts/abi/packing_test.go index 8e876dcaef..0c2ee00745 100644 --- a/accounts/abi/packing_test.go +++ b/accounts/abi/packing_test.go @@ -29,7 +29,7 @@ package abi import ( "math/big" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) type packUnpackTest struct { diff --git a/accounts/abi/topics.go b/accounts/abi/topics.go index 03082f221e..0e3cb383ee 100644 --- a/accounts/abi/topics.go +++ b/accounts/abi/topics.go @@ -33,9 +33,9 @@ import ( "math/big" "reflect" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/crypto" ) // packTopic packs rule into the corresponding hash value for a log's topic diff --git a/accounts/abi/topics_test.go b/accounts/abi/topics_test.go index 53e4327bf6..cf9ca32b4f 100644 --- a/accounts/abi/topics_test.go +++ b/accounts/abi/topics_test.go @@ -32,8 +32,8 @@ import ( "reflect" "testing" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" ) func TestMakeTopics(t *testing.T) { diff --git a/accounts/abi/type.go b/accounts/abi/type.go index 75a6c15fd7..93678f5578 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -36,7 +36,7 @@ import ( "unicode" "unicode/utf8" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // Type enumerator diff --git a/accounts/abi/type_test.go b/accounts/abi/type_test.go index ad0daffe06..c55559167f 100644 --- a/accounts/abi/type_test.go +++ b/accounts/abi/type_test.go @@ -31,8 +31,8 @@ import ( "reflect" "testing" + "github.com/ava-labs/libevm/common" "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/common" ) // typeWithoutStringer is a alias for the Type type which simply doesn't implement diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go index b975cb8802..c161c81767 100644 --- a/accounts/abi/unpack.go +++ b/accounts/abi/unpack.go @@ -34,7 +34,7 @@ import ( "math/big" "reflect" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) var ( diff --git a/accounts/abi/unpack_test.go b/accounts/abi/unpack_test.go index d7f383a731..ae55cf3250 100644 --- a/accounts/abi/unpack_test.go +++ b/accounts/abi/unpack_test.go @@ -37,7 +37,7 @@ import ( "strings" "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/require" ) diff --git a/accounts/accounts.go b/accounts/accounts.go deleted file mode 100644 index acde6b436a..0000000000 --- a/accounts/accounts.go +++ /dev/null @@ -1,236 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package accounts implements high level Ethereum account management. -package accounts - -import ( - "fmt" - "math/big" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" - "golang.org/x/crypto/sha3" -) - -// Account represents an Ethereum account located at a specific location defined -// by the optional URL field. -type Account struct { - Address common.Address `json:"address"` // Ethereum account address derived from the key - URL URL `json:"url"` // Optional resource locator within a backend -} - -const ( - MimetypeDataWithValidator = "data/validator" - MimetypeTypedData = "data/typed" - MimetypeClique = "application/x-clique-header" - MimetypeTextPlain = "text/plain" -) - -// Wallet represents a software or hardware wallet that might contain one or more -// accounts (derived from the same seed). -type Wallet interface { - // URL retrieves the canonical path under which this wallet is reachable. It is - // used by upper layers to define a sorting order over all wallets from multiple - // backends. - URL() URL - - // Status returns a textual status to aid the user in the current state of the - // wallet. It also returns an error indicating any failure the wallet might have - // encountered. - Status() (string, error) - - // Open initializes access to a wallet instance. It is not meant to unlock or - // decrypt account keys, rather simply to establish a connection to hardware - // wallets and/or to access derivation seeds. - // - // The passphrase parameter may or may not be used by the implementation of a - // particular wallet instance. The reason there is no passwordless open method - // is to strive towards a uniform wallet handling, oblivious to the different - // backend providers. - // - // Please note, if you open a wallet, you must close it to release any allocated - // resources (especially important when working with hardware wallets). - Open(passphrase string) error - - // Close releases any resources held by an open wallet instance. - Close() error - - // Accounts retrieves the list of signing accounts the wallet is currently aware - // of. For hierarchical deterministic wallets, the list will not be exhaustive, - // rather only contain the accounts explicitly pinned during account derivation. - Accounts() []Account - - // Contains returns whether an account is part of this particular wallet or not. - Contains(account Account) bool - - // Derive attempts to explicitly derive a hierarchical deterministic account at - // the specified derivation path. If requested, the derived account will be added - // to the wallet's tracked account list. - Derive(path DerivationPath, pin bool) (Account, error) - - // SelfDerive sets a base account derivation path from which the wallet attempts - // to discover non zero accounts and automatically add them to list of tracked - // accounts. - // - // Note, self derivation will increment the last component of the specified path - // opposed to descending into a child path to allow discovering accounts starting - // from non zero components. - // - // Some hardware wallets switched derivation paths through their evolution, so - // this method supports providing multiple bases to discover old user accounts - // too. Only the last base will be used to derive the next empty account. - // - // You can disable automatic account discovery by calling SelfDerive with a nil - // chain state reader. - SelfDerive(bases []DerivationPath, chain interfaces.ChainStateReader) - - // SignData requests the wallet to sign the hash of the given data - // It looks up the account specified either solely via its address contained within, - // or optionally with the aid of any location metadata from the embedded URL field. - // - // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code to verify the transaction), - // an AuthNeededError instance will be returned, containing infos for the user - // about which fields or actions are needed. The user may retry by providing - // the needed details via SignDataWithPassphrase, or by other means (e.g. unlock - // the account in a keystore). - SignData(account Account, mimeType string, data []byte) ([]byte, error) - - // SignDataWithPassphrase is identical to SignData, but also takes a password - // NOTE: there's a chance that an erroneous call might mistake the two strings, and - // supply password in the mimetype field, or vice versa. Thus, an implementation - // should never echo the mimetype or return the mimetype in the error-response - SignDataWithPassphrase(account Account, passphrase, mimeType string, data []byte) ([]byte, error) - - // SignText requests the wallet to sign the hash of a given piece of data, prefixed - // by the Ethereum prefix scheme - // It looks up the account specified either solely via its address contained within, - // or optionally with the aid of any location metadata from the embedded URL field. - // - // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code to verify the transaction), - // an AuthNeededError instance will be returned, containing infos for the user - // about which fields or actions are needed. The user may retry by providing - // the needed details via SignTextWithPassphrase, or by other means (e.g. unlock - // the account in a keystore). - // - // This method should return the signature in 'canonical' format, with v 0 or 1. - SignText(account Account, text []byte) ([]byte, error) - - // SignTextWithPassphrase is identical to Signtext, but also takes a password - SignTextWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error) - - // SignTx requests the wallet to sign the given transaction. - // - // It looks up the account specified either solely via its address contained within, - // or optionally with the aid of any location metadata from the embedded URL field. - // - // If the wallet requires additional authentication to sign the request (e.g. - // a password to decrypt the account, or a PIN code to verify the transaction), - // an AuthNeededError instance will be returned, containing infos for the user - // about which fields or actions are needed. The user may retry by providing - // the needed details via SignTxWithPassphrase, or by other means (e.g. unlock - // the account in a keystore). - SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) - - // SignTxWithPassphrase is identical to SignTx, but also takes a password - SignTxWithPassphrase(account Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) -} - -// Backend is a "wallet provider" that may contain a batch of accounts they can -// sign transactions with and upon request, do so. -type Backend interface { - // Wallets retrieves the list of wallets the backend is currently aware of. - // - // The returned wallets are not opened by default. For software HD wallets this - // means that no base seeds are decrypted, and for hardware wallets that no actual - // connection is established. - // - // The resulting wallet list will be sorted alphabetically based on its internal - // URL assigned by the backend. Since wallets (especially hardware) may come and - // go, the same wallet might appear at a different positions in the list during - // subsequent retrievals. - Wallets() []Wallet - - // Subscribe creates an async subscription to receive notifications when the - // backend detects the arrival or departure of a wallet. - Subscribe(sink chan<- WalletEvent) event.Subscription -} - -// TextHash is a helper function that calculates a hash for the given message that can be -// safely used to calculate a signature from. -// -// The hash is calculated as -// -// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). -// -// This gives context to the signed message and prevents signing of transactions. -func TextHash(data []byte) []byte { - hash, _ := TextAndHash(data) - return hash -} - -// TextAndHash is a helper function that calculates a hash for the given message that can be -// safely used to calculate a signature from. -// -// The hash is calculated as -// -// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). -// -// This gives context to the signed message and prevents signing of transactions. -func TextAndHash(data []byte) ([]byte, string) { - msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), string(data)) - hasher := sha3.NewLegacyKeccak256() - hasher.Write([]byte(msg)) - return hasher.Sum(nil), msg -} - -// WalletEventType represents the different event types that can be fired by -// the wallet subscription subsystem. -type WalletEventType int - -const ( - // WalletArrived is fired when a new wallet is detected either via USB or via - // a filesystem event in the keystore. - WalletArrived WalletEventType = iota - - // WalletOpened is fired when a wallet is successfully opened with the purpose - // of starting any background processes such as automatic key derivation. - WalletOpened - - // WalletDropped - WalletDropped -) - -// WalletEvent is an event fired by an account backend when a wallet arrival or -// departure is detected. -type WalletEvent struct { - Wallet Wallet // Wallet instance arrived or departed - Kind WalletEventType // Event type that happened in the system -} diff --git a/accounts/accounts_test.go b/accounts/accounts_test.go deleted file mode 100644 index adf7c1b10f..0000000000 --- a/accounts/accounts_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -import ( - "bytes" - "testing" - - "github.com/ethereum/go-ethereum/common/hexutil" -) - -func TestTextHash(t *testing.T) { - t.Parallel() - hash := TextHash([]byte("Hello Joe")) - want := hexutil.MustDecode("0xa080337ae51c4e064c189e113edd0ba391df9206e2f49db658bb32cf2911730b") - if !bytes.Equal(hash, want) { - t.Fatalf("wrong hash: %x", hash) - } -} diff --git a/accounts/errors.go b/accounts/errors.go deleted file mode 100644 index f8000a5a02..0000000000 --- a/accounts/errors.go +++ /dev/null @@ -1,77 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -import ( - "errors" - "fmt" -) - -// ErrUnknownAccount is returned for any requested operation for which no backend -// provides the specified account. -var ErrUnknownAccount = errors.New("unknown account") - -// ErrUnknownWallet is returned for any requested operation for which no backend -// provides the specified wallet. -var ErrUnknownWallet = errors.New("unknown wallet") - -// ErrNotSupported is returned when an operation is requested from an account -// backend that it does not support. -var ErrNotSupported = errors.New("not supported") - -// ErrInvalidPassphrase is returned when a decryption operation receives a bad -// passphrase. -var ErrInvalidPassphrase = errors.New("invalid password") - -// ErrWalletAlreadyOpen is returned if a wallet is attempted to be opened the -// second time. -var ErrWalletAlreadyOpen = errors.New("wallet already open") - -// ErrWalletClosed is returned if a wallet is offline. -var ErrWalletClosed = errors.New("wallet closed") - -// AuthNeededError is returned by backends for signing requests where the user -// is required to provide further authentication before signing can succeed. -// -// This usually means either that a password needs to be supplied, or perhaps a -// one time PIN code displayed by some hardware device. -type AuthNeededError struct { - Needed string // Extra authentication the user needs to provide -} - -// NewAuthNeededError creates a new authentication error with the extra details -// about the needed fields set. -func NewAuthNeededError(needed string) error { - return &AuthNeededError{ - Needed: needed, - } -} - -// Error implements the standard error interface. -func (err *AuthNeededError) Error() string { - return fmt.Sprintf("authentication needed: %s", err.Needed) -} diff --git a/accounts/external/backend.go b/accounts/external/backend.go deleted file mode 100644 index 31f8d6804e..0000000000 --- a/accounts/external/backend.go +++ /dev/null @@ -1,280 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package external - -import ( - "errors" - "fmt" - "math/big" - "sync" - - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" - "github.com/ava-labs/coreth/rpc" - "github.com/ava-labs/coreth/signer/core/apitypes" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" -) - -type ExternalBackend struct { - signers []accounts.Wallet -} - -func (eb *ExternalBackend) Wallets() []accounts.Wallet { - return eb.signers -} - -func NewExternalBackend(endpoint string) (*ExternalBackend, error) { - signer, err := NewExternalSigner(endpoint) - if err != nil { - return nil, err - } - return &ExternalBackend{ - signers: []accounts.Wallet{signer}, - }, nil -} - -func (eb *ExternalBackend) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { - return event.NewSubscription(func(quit <-chan struct{}) error { - <-quit - return nil - }) -} - -// ExternalSigner provides an API to interact with an external signer (clef) -// It proxies request to the external signer while forwarding relevant -// request headers -type ExternalSigner struct { - client *rpc.Client - endpoint string - status string - cacheMu sync.RWMutex - cache []accounts.Account -} - -func NewExternalSigner(endpoint string) (*ExternalSigner, error) { - client, err := rpc.Dial(endpoint) - if err != nil { - return nil, err - } - extsigner := &ExternalSigner{ - client: client, - endpoint: endpoint, - } - // Check if reachable - version, err := extsigner.pingVersion() - if err != nil { - return nil, err - } - extsigner.status = fmt.Sprintf("ok [version=%v]", version) - return extsigner, nil -} - -func (api *ExternalSigner) URL() accounts.URL { - return accounts.URL{ - Scheme: "extapi", - Path: api.endpoint, - } -} - -func (api *ExternalSigner) Status() (string, error) { - return api.status, nil -} - -func (api *ExternalSigner) Open(passphrase string) error { - return errors.New("operation not supported on external signers") -} - -func (api *ExternalSigner) Close() error { - return errors.New("operation not supported on external signers") -} - -func (api *ExternalSigner) Accounts() []accounts.Account { - var accnts []accounts.Account - res, err := api.listAccounts() - if err != nil { - log.Error("account listing failed", "error", err) - return accnts - } - for _, addr := range res { - accnts = append(accnts, accounts.Account{ - URL: accounts.URL{ - Scheme: "extapi", - Path: api.endpoint, - }, - Address: addr, - }) - } - api.cacheMu.Lock() - api.cache = accnts - api.cacheMu.Unlock() - return accnts -} - -func (api *ExternalSigner) Contains(account accounts.Account) bool { - api.cacheMu.RLock() - defer api.cacheMu.RUnlock() - if api.cache == nil { - // If we haven't already fetched the accounts, it's time to do so now - api.cacheMu.RUnlock() - api.Accounts() - api.cacheMu.RLock() - } - for _, a := range api.cache { - if a.Address == account.Address && (account.URL == (accounts.URL{}) || account.URL == api.URL()) { - return true - } - } - return false -} - -func (api *ExternalSigner) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { - return accounts.Account{}, errors.New("operation not supported on external signers") -} - -func (api *ExternalSigner) SelfDerive(bases []accounts.DerivationPath, chain interfaces.ChainStateReader) { - log.Error("operation SelfDerive not supported on external signers") -} - -// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed -func (api *ExternalSigner) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { - var res hexutil.Bytes - var signAddress = common.NewMixedcaseAddress(account.Address) - if err := api.client.Call(&res, "account_signData", - mimeType, - &signAddress, // Need to use the pointer here, because of how MarshalJSON is defined - hexutil.Encode(data)); err != nil { - return nil, err - } - // If V is on 27/28-form, convert to 0/1 for Clique - if mimeType == accounts.MimetypeClique && (res[64] == 27 || res[64] == 28) { - res[64] -= 27 // Transform V from 27/28 to 0/1 for Clique use - } - return res, nil -} - -func (api *ExternalSigner) SignText(account accounts.Account, text []byte) ([]byte, error) { - var signature hexutil.Bytes - var signAddress = common.NewMixedcaseAddress(account.Address) - if err := api.client.Call(&signature, "account_signData", - accounts.MimetypeTextPlain, - &signAddress, // Need to use the pointer here, because of how MarshalJSON is defined - hexutil.Encode(text)); err != nil { - return nil, err - } - if signature[64] == 27 || signature[64] == 28 { - // If clef is used as a backend, it may already have transformed - // the signature to ethereum-type signature. - signature[64] -= 27 // Transform V from Ethereum-legacy to 0/1 - } - return signature, nil -} - -// signTransactionResult represents the signinig result returned by clef. -type signTransactionResult struct { - Raw hexutil.Bytes `json:"raw"` - Tx *types.Transaction `json:"tx"` -} - -// SignTx sends the transaction to the external signer. -// If chainID is nil, or tx.ChainID is zero, the chain ID will be assigned -// by the external signer. For non-legacy transactions, the chain ID of the -// transaction overrides the chainID parameter. -func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - data := hexutil.Bytes(tx.Data()) - var to *common.MixedcaseAddress - if tx.To() != nil { - t := common.NewMixedcaseAddress(*tx.To()) - to = &t - } - args := &apitypes.SendTxArgs{ - Data: &data, - Nonce: hexutil.Uint64(tx.Nonce()), - Value: hexutil.Big(*tx.Value()), - Gas: hexutil.Uint64(tx.Gas()), - To: to, - From: common.NewMixedcaseAddress(account.Address), - } - switch tx.Type() { - case types.LegacyTxType, types.AccessListTxType: - args.GasPrice = (*hexutil.Big)(tx.GasPrice()) - case types.DynamicFeeTxType: - args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) - args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) - default: - return nil, fmt.Errorf("unsupported tx type %d", tx.Type()) - } - // We should request the default chain id that we're operating with - // (the chain we're executing on) - if chainID != nil && chainID.Sign() != 0 { - args.ChainID = (*hexutil.Big)(chainID) - } - if tx.Type() != types.LegacyTxType { - // However, if the user asked for a particular chain id, then we should - // use that instead. - if tx.ChainId().Sign() != 0 { - args.ChainID = (*hexutil.Big)(tx.ChainId()) - } - accessList := tx.AccessList() - args.AccessList = &accessList - } - var res signTransactionResult - if err := api.client.Call(&res, "account_signTransaction", args); err != nil { - return nil, err - } - return res.Tx, nil -} - -func (api *ExternalSigner) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { - return []byte{}, errors.New("password-operations not supported on external signers") -} - -func (api *ExternalSigner) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - return nil, errors.New("password-operations not supported on external signers") -} -func (api *ExternalSigner) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { - return nil, errors.New("password-operations not supported on external signers") -} - -func (api *ExternalSigner) listAccounts() ([]common.Address, error) { - var res []common.Address - if err := api.client.Call(&res, "account_list"); err != nil { - return nil, err - } - return res, nil -} - -func (api *ExternalSigner) pingVersion() (string, error) { - var v string - if err := api.client.Call(&v, "account_version"); err != nil { - return "", err - } - return v, nil -} diff --git a/accounts/hd.go b/accounts/hd.go deleted file mode 100644 index 50f030fe24..0000000000 --- a/accounts/hd.go +++ /dev/null @@ -1,162 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -import ( - "encoding/json" - "errors" - "fmt" - "math" - "math/big" - "strings" -) - -// DefaultRootDerivationPath is the root path to which custom derivation endpoints -// are appended. As such, the first account will be at m/44'/60'/0'/0, the second -// at m/44'/60'/0'/1, etc. -var DefaultRootDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} - -// DefaultBaseDerivationPath is the base path from which custom derivation endpoints -// are incremented. As such, the first account will be at m/44'/60'/0'/0/0, the second -// at m/44'/60'/0'/0/1, etc. -var DefaultBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0} - -// LegacyLedgerBaseDerivationPath is the legacy base path from which custom derivation -// endpoints are incremented. As such, the first account will be at m/44'/60'/0'/0, the -// second at m/44'/60'/0'/1, etc. -var LegacyLedgerBaseDerivationPath = DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0} - -// DerivationPath represents the computer friendly version of a hierarchical -// deterministic wallet account derivation path. -// -// The BIP-32 spec https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki -// defines derivation paths to be of the form: -// -// m / purpose' / coin_type' / account' / change / address_index -// -// The BIP-44 spec https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki -// defines that the `purpose` be 44' (or 0x8000002C) for crypto currencies, and -// SLIP-44 https://github.com/satoshilabs/slips/blob/master/slip-0044.md assigns -// the `coin_type` 60' (or 0x8000003C) to Ethereum. -// -// The root path for Ethereum is m/44'/60'/0'/0 according to the specification -// from https://github.com/ethereum/EIPs/issues/84, albeit it's not set in stone -// yet whether accounts should increment the last component or the children of -// that. We will go with the simpler approach of incrementing the last component. -type DerivationPath []uint32 - -// ParseDerivationPath converts a user specified derivation path string to the -// internal binary representation. -// -// Full derivation paths need to start with the `m/` prefix, relative derivation -// paths (which will get appended to the default root path) must not have prefixes -// in front of the first element. Whitespace is ignored. -func ParseDerivationPath(path string) (DerivationPath, error) { - var result DerivationPath - - // Handle absolute or relative paths - components := strings.Split(path, "/") - switch { - case len(components) == 0: - return nil, errors.New("empty derivation path") - - case strings.TrimSpace(components[0]) == "": - return nil, errors.New("ambiguous path: use 'm/' prefix for absolute paths, or no leading '/' for relative ones") - - case strings.TrimSpace(components[0]) == "m": - components = components[1:] - - default: - result = append(result, DefaultRootDerivationPath...) - } - // All remaining components are relative, append one by one - if len(components) == 0 { - return nil, errors.New("empty derivation path") // Empty relative paths - } - for _, component := range components { - // Ignore any user added whitespace - component = strings.TrimSpace(component) - var value uint32 - - // Handle hardened paths - if strings.HasSuffix(component, "'") { - value = 0x80000000 - component = strings.TrimSpace(strings.TrimSuffix(component, "'")) - } - // Handle the non hardened component - bigval, ok := new(big.Int).SetString(component, 0) - if !ok { - return nil, fmt.Errorf("invalid component: %s", component) - } - max := math.MaxUint32 - value - if bigval.Sign() < 0 || bigval.Cmp(big.NewInt(int64(max))) > 0 { - if value == 0 { - return nil, fmt.Errorf("component %v out of allowed range [0, %d]", bigval, max) - } - return nil, fmt.Errorf("component %v out of allowed hardened range [0, %d]", bigval, max) - } - value += uint32(bigval.Uint64()) - - // Append and repeat - result = append(result, value) - } - return result, nil -} - -// String implements the stringer interface, converting a binary derivation path -// to its canonical representation. -func (path DerivationPath) String() string { - result := "m" - for _, component := range path { - var hardened bool - if component >= 0x80000000 { - component -= 0x80000000 - hardened = true - } - result = fmt.Sprintf("%s/%d", result, component) - if hardened { - result += "'" - } - } - return result -} - -// MarshalJSON turns a derivation path into its json-serialized string -func (path DerivationPath) MarshalJSON() ([]byte, error) { - return json.Marshal(path.String()) -} - -// UnmarshalJSON a json-serialized string back into a derivation path -func (path *DerivationPath) UnmarshalJSON(b []byte) error { - var dp string - var err error - if err = json.Unmarshal(b, &dp); err != nil { - return err - } - *path, err = ParseDerivationPath(dp) - return err -} diff --git a/accounts/hd_test.go b/accounts/hd_test.go deleted file mode 100644 index c025c2bcb3..0000000000 --- a/accounts/hd_test.go +++ /dev/null @@ -1,90 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -import ( - "reflect" - "testing" -) - -// Tests that HD derivation paths can be correctly parsed into our internal binary -// representation. -func TestHDPathParsing(t *testing.T) { - t.Parallel() - tests := []struct { - input string - output DerivationPath - }{ - // Plain absolute derivation paths - {"m/44'/60'/0'/0", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}}, - {"m/44'/60'/0'/128", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 128}}, - {"m/44'/60'/0'/0'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0x80000000 + 0}}, - {"m/44'/60'/0'/128'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0x80000000 + 128}}, - {"m/2147483692/2147483708/2147483648/0", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}}, - {"m/2147483692/2147483708/2147483648/2147483648", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0x80000000 + 0}}, - - // Plain relative derivation paths - {"0", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0}}, - {"128", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 128}}, - {"0'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0x80000000 + 0}}, - {"128'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0x80000000 + 128}}, - {"2147483648", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0x80000000 + 0}}, - - // Hexadecimal absolute derivation paths - {"m/0x2C'/0x3c'/0x00'/0x00", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}}, - {"m/0x2C'/0x3c'/0x00'/0x80", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 128}}, - {"m/0x2C'/0x3c'/0x00'/0x00'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0x80000000 + 0}}, - {"m/0x2C'/0x3c'/0x00'/0x80'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0x80000000 + 128}}, - {"m/0x8000002C/0x8000003c/0x80000000/0x00", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}}, - {"m/0x8000002C/0x8000003c/0x80000000/0x80000000", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0x80000000 + 0}}, - - // Hexadecimal relative derivation paths - {"0x00", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0}}, - {"0x80", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 128}}, - {"0x00'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0x80000000 + 0}}, - {"0x80'", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0x80000000 + 128}}, - {"0x80000000", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0, 0x80000000 + 0}}, - - // Weird inputs just to ensure they work - {" m / 44 '\n/\n 60 \n\n\t' /\n0 ' /\t\t 0", DerivationPath{0x80000000 + 44, 0x80000000 + 60, 0x80000000 + 0, 0}}, - - // Invalid derivation paths - {"", nil}, // Empty relative derivation path - {"m", nil}, // Empty absolute derivation path - {"m/", nil}, // Missing last derivation component - {"/44'/60'/0'/0", nil}, // Absolute path without m prefix, might be user error - {"m/2147483648'", nil}, // Overflows 32 bit integer - {"m/-1'", nil}, // Cannot contain negative number - } - for i, tt := range tests { - if path, err := ParseDerivationPath(tt.input); !reflect.DeepEqual(path, tt.output) { - t.Errorf("test %d: parse mismatch: have %v (%v), want %v", i, path, err, tt.output) - } else if path == nil && err == nil { - t.Errorf("test %d: nil path and error: %v", i, err) - } - } -} diff --git a/accounts/keystore/account_cache.go b/accounts/keystore/account_cache.go deleted file mode 100644 index 4284d29f47..0000000000 --- a/accounts/keystore/account_cache.go +++ /dev/null @@ -1,318 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "bufio" - "encoding/json" - "fmt" - "os" - "path/filepath" - "sort" - "strings" - "sync" - "time" - - "github.com/ava-labs/coreth/accounts" - mapset "github.com/deckarep/golang-set/v2" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "golang.org/x/exp/slices" -) - -// Minimum amount of time between cache reloads. This limit applies if the platform does -// not support change notifications. It also applies if the keystore directory does not -// exist yet, the code will attempt to create a watcher at most this often. -const minReloadInterval = 2 * time.Second - -// byURL defines the sorting order for accounts. -func byURL(a, b accounts.Account) int { - return a.URL.Cmp(b.URL) -} - -// AmbiguousAddrError is returned when attempting to unlock -// an address for which more than one file exists. -type AmbiguousAddrError struct { - Addr common.Address - Matches []accounts.Account -} - -func (err *AmbiguousAddrError) Error() string { - files := "" - for i, a := range err.Matches { - files += a.URL.Path - if i < len(err.Matches)-1 { - files += ", " - } - } - return fmt.Sprintf("multiple keys match address (%s)", files) -} - -// accountCache is a live index of all accounts in the keystore. -type accountCache struct { - keydir string - watcher *watcher - mu sync.Mutex - all []accounts.Account - byAddr map[common.Address][]accounts.Account - throttle *time.Timer - notify chan struct{} - fileC fileCache -} - -func newAccountCache(keydir string) (*accountCache, chan struct{}) { - ac := &accountCache{ - keydir: keydir, - byAddr: make(map[common.Address][]accounts.Account), - notify: make(chan struct{}, 1), - fileC: fileCache{all: mapset.NewThreadUnsafeSet[string]()}, - } - ac.watcher = newWatcher(ac) - return ac, ac.notify -} - -func (ac *accountCache) accounts() []accounts.Account { - ac.maybeReload() - ac.mu.Lock() - defer ac.mu.Unlock() - cpy := make([]accounts.Account, len(ac.all)) - copy(cpy, ac.all) - return cpy -} - -func (ac *accountCache) hasAddress(addr common.Address) bool { - ac.maybeReload() - ac.mu.Lock() - defer ac.mu.Unlock() - return len(ac.byAddr[addr]) > 0 -} - -func (ac *accountCache) add(newAccount accounts.Account) { - ac.mu.Lock() - defer ac.mu.Unlock() - - i := sort.Search(len(ac.all), func(i int) bool { return ac.all[i].URL.Cmp(newAccount.URL) >= 0 }) - if i < len(ac.all) && ac.all[i] == newAccount { - return - } - // newAccount is not in the cache. - ac.all = append(ac.all, accounts.Account{}) - copy(ac.all[i+1:], ac.all[i:]) - ac.all[i] = newAccount - ac.byAddr[newAccount.Address] = append(ac.byAddr[newAccount.Address], newAccount) -} - -// note: removed needs to be unique here (i.e. both File and Address must be set). -func (ac *accountCache) delete(removed accounts.Account) { - ac.mu.Lock() - defer ac.mu.Unlock() - - ac.all = removeAccount(ac.all, removed) - if ba := removeAccount(ac.byAddr[removed.Address], removed); len(ba) == 0 { - delete(ac.byAddr, removed.Address) - } else { - ac.byAddr[removed.Address] = ba - } -} - -// deleteByFile removes an account referenced by the given path. -func (ac *accountCache) deleteByFile(path string) { - ac.mu.Lock() - defer ac.mu.Unlock() - i := sort.Search(len(ac.all), func(i int) bool { return ac.all[i].URL.Path >= path }) - - if i < len(ac.all) && ac.all[i].URL.Path == path { - removed := ac.all[i] - ac.all = append(ac.all[:i], ac.all[i+1:]...) - if ba := removeAccount(ac.byAddr[removed.Address], removed); len(ba) == 0 { - delete(ac.byAddr, removed.Address) - } else { - ac.byAddr[removed.Address] = ba - } - } -} - -// watcherStarted returns true if the watcher loop started running (even if it -// has since also ended). -func (ac *accountCache) watcherStarted() bool { - ac.mu.Lock() - defer ac.mu.Unlock() - return ac.watcher.running || ac.watcher.runEnded -} - -func removeAccount(slice []accounts.Account, elem accounts.Account) []accounts.Account { - for i := range slice { - if slice[i] == elem { - return append(slice[:i], slice[i+1:]...) - } - } - return slice -} - -// find returns the cached account for address if there is a unique match. -// The exact matching rules are explained by the documentation of accounts.Account. -// Callers must hold ac.mu. -func (ac *accountCache) find(a accounts.Account) (accounts.Account, error) { - // Limit search to address candidates if possible. - matches := ac.all - if (a.Address != common.Address{}) { - matches = ac.byAddr[a.Address] - } - if a.URL.Path != "" { - // If only the basename is specified, complete the path. - if !strings.ContainsRune(a.URL.Path, filepath.Separator) { - a.URL.Path = filepath.Join(ac.keydir, a.URL.Path) - } - for i := range matches { - if matches[i].URL == a.URL { - return matches[i], nil - } - } - if (a.Address == common.Address{}) { - return accounts.Account{}, ErrNoMatch - } - } - switch len(matches) { - case 1: - return matches[0], nil - case 0: - return accounts.Account{}, ErrNoMatch - default: - err := &AmbiguousAddrError{Addr: a.Address, Matches: make([]accounts.Account, len(matches))} - copy(err.Matches, matches) - slices.SortFunc(err.Matches, byURL) - return accounts.Account{}, err - } -} - -func (ac *accountCache) maybeReload() { - ac.mu.Lock() - - if ac.watcher.running { - ac.mu.Unlock() - return // A watcher is running and will keep the cache up-to-date. - } - if ac.throttle == nil { - ac.throttle = time.NewTimer(0) - } else { - select { - case <-ac.throttle.C: - default: - ac.mu.Unlock() - return // The cache was reloaded recently. - } - } - // No watcher running, start it. - ac.watcher.start() - ac.throttle.Reset(minReloadInterval) - ac.mu.Unlock() - ac.scanAccounts() -} - -func (ac *accountCache) close() { - ac.mu.Lock() - ac.watcher.close() - if ac.throttle != nil { - ac.throttle.Stop() - } - if ac.notify != nil { - close(ac.notify) - ac.notify = nil - } - ac.mu.Unlock() -} - -// scanAccounts checks if any changes have occurred on the filesystem, and -// updates the account cache accordingly -func (ac *accountCache) scanAccounts() error { - // Scan the entire folder metadata for file changes - creates, deletes, updates, err := ac.fileC.scan(ac.keydir) - if err != nil { - log.Debug("Failed to reload keystore contents", "err", err) - return err - } - if creates.Cardinality() == 0 && deletes.Cardinality() == 0 && updates.Cardinality() == 0 { - return nil - } - // Create a helper method to scan the contents of the key files - var ( - buf = new(bufio.Reader) - key struct { - Address string `json:"address"` - } - ) - readAccount := func(path string) *accounts.Account { - fd, err := os.Open(path) - if err != nil { - log.Trace("Failed to open keystore file", "path", path, "err", err) - return nil - } - defer fd.Close() - buf.Reset(fd) - // Parse the address. - key.Address = "" - err = json.NewDecoder(buf).Decode(&key) - addr := common.HexToAddress(key.Address) - switch { - case err != nil: - log.Debug("Failed to decode keystore key", "path", path, "err", err) - case addr == common.Address{}: - log.Debug("Failed to decode keystore key", "path", path, "err", "missing or zero address") - default: - return &accounts.Account{ - Address: addr, - URL: accounts.URL{Scheme: KeyStoreScheme, Path: path}, - } - } - return nil - } - // Process all the file diffs - start := time.Now() - - for _, path := range creates.ToSlice() { - if a := readAccount(path); a != nil { - ac.add(*a) - } - } - for _, path := range deletes.ToSlice() { - ac.deleteByFile(path) - } - for _, path := range updates.ToSlice() { - ac.deleteByFile(path) - if a := readAccount(path); a != nil { - ac.add(*a) - } - } - end := time.Now() - - select { - case ac.notify <- struct{}{}: - default: - } - log.Trace("Handled keystore changes", "time", end.Sub(start)) - return nil -} diff --git a/accounts/keystore/account_cache_test.go b/accounts/keystore/account_cache_test.go deleted file mode 100644 index 32c2ae3330..0000000000 --- a/accounts/keystore/account_cache_test.go +++ /dev/null @@ -1,419 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "errors" - "fmt" - "math/rand" - "os" - "path/filepath" - "reflect" - "testing" - "time" - - "github.com/ava-labs/coreth/accounts" - "github.com/cespare/cp" - "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/common" - "golang.org/x/exp/slices" -) - -var ( - cachetestDir, _ = filepath.Abs(filepath.Join("testdata", "keystore")) - cachetestAccounts = []accounts.Account{ - { - Address: common.HexToAddress("7ef5a6135f1fd6a02593eedc869c6d41d934aef8"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(cachetestDir, "UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8")}, - }, - { - Address: common.HexToAddress("f466859ead1932d743d622cb74fc058882e8648a"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(cachetestDir, "aaa")}, - }, - { - Address: common.HexToAddress("289d485d9771714cce91d3393d764e1311907acc"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(cachetestDir, "zzz")}, - }, - } -) - -// waitWatcherStart waits up to 1s for the keystore watcher to start. -func waitWatcherStart(ks *KeyStore) bool { - // On systems where file watch is not supported, just return "ok". - if !ks.cache.watcher.enabled() { - return true - } - // The watcher should start, and then exit. - for t0 := time.Now(); time.Since(t0) < 1*time.Second; time.Sleep(100 * time.Millisecond) { - if ks.cache.watcherStarted() { - return true - } - } - return false -} - -func waitForAccounts(wantAccounts []accounts.Account, ks *KeyStore) error { - var list []accounts.Account - for t0 := time.Now(); time.Since(t0) < 5*time.Second; time.Sleep(100 * time.Millisecond) { - list = ks.Accounts() - if reflect.DeepEqual(list, wantAccounts) { - // ks should have also received change notifications - select { - case <-ks.changes: - default: - return errors.New("wasn't notified of new accounts") - } - return nil - } - } - return fmt.Errorf("\ngot %v\nwant %v", list, wantAccounts) -} - -func TestWatchNewFile(t *testing.T) { - t.Parallel() - - dir, ks := tmpKeyStore(t, false) - - // Ensure the watcher is started before adding any files. - ks.Accounts() - if !waitWatcherStart(ks) { - t.Fatal("keystore watcher didn't start in time") - } - // Move in the files. - wantAccounts := make([]accounts.Account, len(cachetestAccounts)) - for i := range cachetestAccounts { - wantAccounts[i] = accounts.Account{ - Address: cachetestAccounts[i].Address, - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(dir, filepath.Base(cachetestAccounts[i].URL.Path))}, - } - if err := cp.CopyFile(wantAccounts[i].URL.Path, cachetestAccounts[i].URL.Path); err != nil { - t.Fatal(err) - } - } - - // ks should see the accounts. - if err := waitForAccounts(wantAccounts, ks); err != nil { - t.Error(err) - } -} - -func TestWatchNoDir(t *testing.T) { - t.Parallel() - // Create ks but not the directory that it watches. - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watchnodir-test-%d-%d", os.Getpid(), rand.Int())) - ks := NewKeyStore(dir, LightScryptN, LightScryptP) - list := ks.Accounts() - if len(list) > 0 { - t.Error("initial account list not empty:", list) - } - // The watcher should start, and then exit. - if !waitWatcherStart(ks) { - t.Fatal("keystore watcher didn't start in time") - } - // Create the directory and copy a key file into it. - os.MkdirAll(dir, 0700) - defer os.RemoveAll(dir) - file := filepath.Join(dir, "aaa") - if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil { - t.Fatal(err) - } - - // ks should see the account. - wantAccounts := []accounts.Account{cachetestAccounts[0]} - wantAccounts[0].URL = accounts.URL{Scheme: KeyStoreScheme, Path: file} - for d := 200 * time.Millisecond; d < 8*time.Second; d *= 2 { - list = ks.Accounts() - if reflect.DeepEqual(list, wantAccounts) { - // ks should have also received change notifications - select { - case <-ks.changes: - default: - t.Fatalf("wasn't notified of new accounts") - } - return - } - time.Sleep(d) - } - t.Errorf("\ngot %v\nwant %v", list, wantAccounts) -} - -func TestCacheInitialReload(t *testing.T) { - t.Parallel() - cache, _ := newAccountCache(cachetestDir) - accounts := cache.accounts() - if !reflect.DeepEqual(accounts, cachetestAccounts) { - t.Fatalf("got initial accounts: %swant %s", spew.Sdump(accounts), spew.Sdump(cachetestAccounts)) - } -} - -func TestCacheAddDeleteOrder(t *testing.T) { - t.Parallel() - cache, _ := newAccountCache("testdata/no-such-dir") - cache.watcher.running = true // prevent unexpected reloads - - accs := []accounts.Account{ - { - Address: common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: "-309830980"}, - }, - { - Address: common.HexToAddress("2cac1adea150210703ba75ed097ddfe24e14f213"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: "ggg"}, - }, - { - Address: common.HexToAddress("8bda78331c916a08481428e4b07c96d3e916d165"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: "zzzzzz-the-very-last-one.keyXXX"}, - }, - { - Address: common.HexToAddress("d49ff4eeb0b2686ed89c0fc0f2b6ea533ddbbd5e"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: "SOMETHING.key"}, - }, - { - Address: common.HexToAddress("7ef5a6135f1fd6a02593eedc869c6d41d934aef8"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: "UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8"}, - }, - { - Address: common.HexToAddress("f466859ead1932d743d622cb74fc058882e8648a"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: "aaa"}, - }, - { - Address: common.HexToAddress("289d485d9771714cce91d3393d764e1311907acc"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: "zzz"}, - }, - } - for _, a := range accs { - cache.add(a) - } - // Add some of them twice to check that they don't get reinserted. - cache.add(accs[0]) - cache.add(accs[2]) - - // Check that the account list is sorted by filename. - wantAccounts := make([]accounts.Account, len(accs)) - copy(wantAccounts, accs) - slices.SortFunc(wantAccounts, byURL) - list := cache.accounts() - if !reflect.DeepEqual(list, wantAccounts) { - t.Fatalf("got accounts: %s\nwant %s", spew.Sdump(accs), spew.Sdump(wantAccounts)) - } - for _, a := range accs { - if !cache.hasAddress(a.Address) { - t.Errorf("expected hasAccount(%x) to return true", a.Address) - } - } - if cache.hasAddress(common.HexToAddress("fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e")) { - t.Errorf("expected hasAccount(%x) to return false", common.HexToAddress("fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e")) - } - - // Delete a few keys from the cache. - for i := 0; i < len(accs); i += 2 { - cache.delete(wantAccounts[i]) - } - cache.delete(accounts.Account{Address: common.HexToAddress("fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e"), URL: accounts.URL{Scheme: KeyStoreScheme, Path: "something"}}) - - // Check content again after deletion. - wantAccountsAfterDelete := []accounts.Account{ - wantAccounts[1], - wantAccounts[3], - wantAccounts[5], - } - list = cache.accounts() - if !reflect.DeepEqual(list, wantAccountsAfterDelete) { - t.Fatalf("got accounts after delete: %s\nwant %s", spew.Sdump(list), spew.Sdump(wantAccountsAfterDelete)) - } - for _, a := range wantAccountsAfterDelete { - if !cache.hasAddress(a.Address) { - t.Errorf("expected hasAccount(%x) to return true", a.Address) - } - } - if cache.hasAddress(wantAccounts[0].Address) { - t.Errorf("expected hasAccount(%x) to return false", wantAccounts[0].Address) - } -} - -func TestCacheFind(t *testing.T) { - t.Parallel() - dir := filepath.Join("testdata", "dir") - cache, _ := newAccountCache(dir) - cache.watcher.running = true // prevent unexpected reloads - - accs := []accounts.Account{ - { - Address: common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(dir, "a.key")}, - }, - { - Address: common.HexToAddress("2cac1adea150210703ba75ed097ddfe24e14f213"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(dir, "b.key")}, - }, - { - Address: common.HexToAddress("d49ff4eeb0b2686ed89c0fc0f2b6ea533ddbbd5e"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(dir, "c.key")}, - }, - { - Address: common.HexToAddress("d49ff4eeb0b2686ed89c0fc0f2b6ea533ddbbd5e"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(dir, "c2.key")}, - }, - } - for _, a := range accs { - cache.add(a) - } - - nomatchAccount := accounts.Account{ - Address: common.HexToAddress("f466859ead1932d743d622cb74fc058882e8648a"), - URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Join(dir, "something")}, - } - tests := []struct { - Query accounts.Account - WantResult accounts.Account - WantError error - }{ - // by address - {Query: accounts.Account{Address: accs[0].Address}, WantResult: accs[0]}, - // by file - {Query: accounts.Account{URL: accs[0].URL}, WantResult: accs[0]}, - // by basename - {Query: accounts.Account{URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Base(accs[0].URL.Path)}}, WantResult: accs[0]}, - // by file and address - {Query: accs[0], WantResult: accs[0]}, - // ambiguous address, tie resolved by file - {Query: accs[2], WantResult: accs[2]}, - // ambiguous address error - { - Query: accounts.Account{Address: accs[2].Address}, - WantError: &AmbiguousAddrError{ - Addr: accs[2].Address, - Matches: []accounts.Account{accs[2], accs[3]}, - }, - }, - // no match error - {Query: nomatchAccount, WantError: ErrNoMatch}, - {Query: accounts.Account{URL: nomatchAccount.URL}, WantError: ErrNoMatch}, - {Query: accounts.Account{URL: accounts.URL{Scheme: KeyStoreScheme, Path: filepath.Base(nomatchAccount.URL.Path)}}, WantError: ErrNoMatch}, - {Query: accounts.Account{Address: nomatchAccount.Address}, WantError: ErrNoMatch}, - } - for i, test := range tests { - a, err := cache.find(test.Query) - if !reflect.DeepEqual(err, test.WantError) { - t.Errorf("test %d: error mismatch for query %v\ngot %q\nwant %q", i, test.Query, err, test.WantError) - continue - } - if a != test.WantResult { - t.Errorf("test %d: result mismatch for query %v\ngot %v\nwant %v", i, test.Query, a, test.WantResult) - continue - } - } -} - -// TestUpdatedKeyfileContents tests that updating the contents of a keystore file -// is noticed by the watcher, and the account cache is updated accordingly -func TestUpdatedKeyfileContents(t *testing.T) { - t.Parallel() - - // Create a temporary keystore to test with - dir := filepath.Join(os.TempDir(), fmt.Sprintf("eth-keystore-watch-test-%d-%d", os.Getpid(), rand.Int())) - ks := NewKeyStore(dir, LightScryptN, LightScryptP) - - list := ks.Accounts() - if len(list) > 0 { - t.Error("initial account list not empty:", list) - } - if !waitWatcherStart(ks) { - t.Fatal("keystore watcher didn't start in time") - } - // Create the directory and copy a key file into it. - os.MkdirAll(dir, 0700) - defer os.RemoveAll(dir) - file := filepath.Join(dir, "aaa") - - // Place one of our testfiles in there - if err := cp.CopyFile(file, cachetestAccounts[0].URL.Path); err != nil { - t.Fatal(err) - } - - // ks should see the account. - wantAccounts := []accounts.Account{cachetestAccounts[0]} - wantAccounts[0].URL = accounts.URL{Scheme: KeyStoreScheme, Path: file} - if err := waitForAccounts(wantAccounts, ks); err != nil { - t.Error(err) - return - } - // needed so that modTime of `file` will be greater than its current value after forceCopyFile - time.Sleep(time.Second) - - // Now replace file contents - if err := forceCopyFile(file, cachetestAccounts[1].URL.Path); err != nil { - t.Fatal(err) - return - } - wantAccounts = []accounts.Account{cachetestAccounts[1]} - wantAccounts[0].URL = accounts.URL{Scheme: KeyStoreScheme, Path: file} - if err := waitForAccounts(wantAccounts, ks); err != nil { - t.Errorf("First replacement failed") - t.Error(err) - return - } - - // needed so that modTime of `file` will be greater than its current value after forceCopyFile - time.Sleep(time.Second) - - // Now replace file contents again - if err := forceCopyFile(file, cachetestAccounts[2].URL.Path); err != nil { - t.Fatal(err) - return - } - wantAccounts = []accounts.Account{cachetestAccounts[2]} - wantAccounts[0].URL = accounts.URL{Scheme: KeyStoreScheme, Path: file} - if err := waitForAccounts(wantAccounts, ks); err != nil { - t.Errorf("Second replacement failed") - t.Error(err) - return - } - - // needed so that modTime of `file` will be greater than its current value after os.WriteFile - time.Sleep(time.Second) - - // Now replace file contents with crap - if err := os.WriteFile(file, []byte("foo"), 0600); err != nil { - t.Fatal(err) - return - } - if err := waitForAccounts([]accounts.Account{}, ks); err != nil { - t.Errorf("Emptying account file failed") - t.Error(err) - return - } -} - -// forceCopyFile is like cp.CopyFile, but doesn't complain if the destination exists. -func forceCopyFile(dst, src string) error { - data, err := os.ReadFile(src) - if err != nil { - return err - } - return os.WriteFile(dst, data, 0644) -} diff --git a/accounts/keystore/file_cache.go b/accounts/keystore/file_cache.go deleted file mode 100644 index ab24b5c59d..0000000000 --- a/accounts/keystore/file_cache.go +++ /dev/null @@ -1,115 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "os" - "path/filepath" - "strings" - "sync" - "time" - - mapset "github.com/deckarep/golang-set/v2" - "github.com/ethereum/go-ethereum/log" -) - -// fileCache is a cache of files seen during scan of keystore. -type fileCache struct { - all mapset.Set[string] // Set of all files from the keystore folder - lastMod time.Time // Last time instance when a file was modified - mu sync.Mutex -} - -// scan performs a new scan on the given directory, compares against the already -// cached filenames, and returns file sets: creates, deletes, updates. -func (fc *fileCache) scan(keyDir string) (mapset.Set[string], mapset.Set[string], mapset.Set[string], error) { - t0 := time.Now() - - // List all the files from the keystore folder - files, err := os.ReadDir(keyDir) - if err != nil { - return nil, nil, nil, err - } - t1 := time.Now() - - fc.mu.Lock() - defer fc.mu.Unlock() - - // Iterate all the files and gather their metadata - all := mapset.NewThreadUnsafeSet[string]() - mods := mapset.NewThreadUnsafeSet[string]() - - var newLastMod time.Time - for _, fi := range files { - path := filepath.Join(keyDir, fi.Name()) - // Skip any non-key files from the folder - if nonKeyFile(fi) { - log.Trace("Ignoring file on account scan", "path", path) - continue - } - // Gather the set of all and freshly modified files - all.Add(path) - - info, err := fi.Info() - if err != nil { - return nil, nil, nil, err - } - modified := info.ModTime() - if modified.After(fc.lastMod) { - mods.Add(path) - } - if modified.After(newLastMod) { - newLastMod = modified - } - } - t2 := time.Now() - - // Update the tracked files and return the three sets - deletes := fc.all.Difference(all) // Deletes = previous - current - creates := all.Difference(fc.all) // Creates = current - previous - updates := mods.Difference(creates) // Updates = modified - creates - - fc.all, fc.lastMod = all, newLastMod - t3 := time.Now() - - // Report on the scanning stats and return - log.Debug("FS scan times", "list", t1.Sub(t0), "set", t2.Sub(t1), "diff", t3.Sub(t2)) - return creates, deletes, updates, nil -} - -// nonKeyFile ignores editor backups, hidden files and folders/symlinks. -func nonKeyFile(fi os.DirEntry) bool { - // Skip editor backups and UNIX-style hidden files. - if strings.HasSuffix(fi.Name(), "~") || strings.HasPrefix(fi.Name(), ".") { - return true - } - // Skip misc special files, directories (yes, symlinks too). - if fi.IsDir() || !fi.Type().IsRegular() { - return true - } - return false -} diff --git a/accounts/keystore/key.go b/accounts/keystore/key.go deleted file mode 100644 index 23b39fa584..0000000000 --- a/accounts/keystore/key.go +++ /dev/null @@ -1,251 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "bytes" - "crypto/ecdsa" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - "strings" - "time" - - "github.com/ava-labs/coreth/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/google/uuid" -) - -const ( - version = 3 -) - -type Key struct { - Id uuid.UUID // Version 4 "random" for unique id not derived from key data - // to simplify lookups we also store the address - Address common.Address - // we only store privkey as pubkey/address can be derived from it - // privkey in this struct is always in plaintext - PrivateKey *ecdsa.PrivateKey -} - -type keyStore interface { - // Loads and decrypts the key from disk. - GetKey(addr common.Address, filename string, auth string) (*Key, error) - // Writes and encrypts the key. - StoreKey(filename string, k *Key, auth string) error - // Joins filename with the key directory unless it is already absolute. - JoinPath(filename string) string -} - -type plainKeyJSON struct { - Address string `json:"address"` - PrivateKey string `json:"privatekey"` - Id string `json:"id"` - Version int `json:"version"` -} - -type encryptedKeyJSONV3 struct { - Address string `json:"address"` - Crypto CryptoJSON `json:"crypto"` - Id string `json:"id"` - Version int `json:"version"` -} - -type encryptedKeyJSONV1 struct { - Address string `json:"address"` - Crypto CryptoJSON `json:"crypto"` - Id string `json:"id"` - Version string `json:"version"` -} - -type CryptoJSON struct { - Cipher string `json:"cipher"` - CipherText string `json:"ciphertext"` - CipherParams cipherparamsJSON `json:"cipherparams"` - KDF string `json:"kdf"` - KDFParams map[string]interface{} `json:"kdfparams"` - MAC string `json:"mac"` -} - -type cipherparamsJSON struct { - IV string `json:"iv"` -} - -func (k *Key) MarshalJSON() (j []byte, err error) { - jStruct := plainKeyJSON{ - hex.EncodeToString(k.Address[:]), - hex.EncodeToString(crypto.FromECDSA(k.PrivateKey)), - k.Id.String(), - version, - } - j, err = json.Marshal(jStruct) - return j, err -} - -func (k *Key) UnmarshalJSON(j []byte) (err error) { - keyJSON := new(plainKeyJSON) - err = json.Unmarshal(j, &keyJSON) - if err != nil { - return err - } - - u := new(uuid.UUID) - *u, err = uuid.Parse(keyJSON.Id) - if err != nil { - return err - } - k.Id = *u - addr, err := hex.DecodeString(keyJSON.Address) - if err != nil { - return err - } - privkey, err := crypto.HexToECDSA(keyJSON.PrivateKey) - if err != nil { - return err - } - - k.Address = common.BytesToAddress(addr) - k.PrivateKey = privkey - - return nil -} - -func NewKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key { - return newKeyFromECDSA(privateKeyECDSA) -} - -func newKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key { - id, err := uuid.NewRandom() - if err != nil { - panic(fmt.Sprintf("Could not create random uuid: %v", err)) - } - key := &Key{ - Id: id, - Address: crypto.PubkeyToAddress(privateKeyECDSA.PublicKey), - PrivateKey: privateKeyECDSA, - } - return key -} - -// NewKeyForDirectICAP generates a key whose address fits into < 155 bits so it can fit -// into the Direct ICAP spec. for simplicity and easier compatibility with other libs, we -// retry until the first byte is 0. -func NewKeyForDirectICAP(rand io.Reader) *Key { - randBytes := make([]byte, 64) - _, err := rand.Read(randBytes) - if err != nil { - panic("key generation: could not read from random source: " + err.Error()) - } - reader := bytes.NewReader(randBytes) - privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), reader) - if err != nil { - panic("key generation: ecdsa.GenerateKey failed: " + err.Error()) - } - key := newKeyFromECDSA(privateKeyECDSA) - if !strings.HasPrefix(key.Address.Hex(), "0x00") { - return NewKeyForDirectICAP(rand) - } - return key -} - -func NewKey(rand io.Reader) (*Key, error) { - privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand) - if err != nil { - return nil, err - } - return newKeyFromECDSA(privateKeyECDSA), nil -} - -func storeNewKey(ks keyStore, rand io.Reader, auth string) (*Key, accounts.Account, error) { - key, err := NewKey(rand) - if err != nil { - return nil, accounts.Account{}, err - } - a := accounts.Account{ - Address: key.Address, - URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.JoinPath(keyFileName(key.Address))}, - } - if err := ks.StoreKey(a.URL.Path, key, auth); err != nil { - zeroKey(key.PrivateKey) - return nil, a, err - } - return key, a, err -} - -func writeTemporaryKeyFile(file string, content []byte) (string, error) { - // Create the keystore directory with appropriate permissions - // in case it is not present yet. - const dirPerm = 0700 - if err := os.MkdirAll(filepath.Dir(file), dirPerm); err != nil { - return "", err - } - // Atomic write: create a temporary hidden file first - // then move it into place. TempFile assigns mode 0600. - f, err := os.CreateTemp(filepath.Dir(file), "."+filepath.Base(file)+".tmp") - if err != nil { - return "", err - } - if _, err := f.Write(content); err != nil { - f.Close() - os.Remove(f.Name()) - return "", err - } - f.Close() - return f.Name(), nil -} - -func writeKeyFile(file string, content []byte) error { - name, err := writeTemporaryKeyFile(file, content) - if err != nil { - return err - } - return os.Rename(name, file) -} - -// keyFileName implements the naming convention for keyfiles: -// UTC---
-func keyFileName(keyAddr common.Address) string { - ts := time.Now().UTC() - return fmt.Sprintf("UTC--%s--%s", toISO8601(ts), hex.EncodeToString(keyAddr[:])) -} - -func toISO8601(t time.Time) string { - var tz string - name, offset := t.Zone() - if name == "UTC" { - tz = "Z" - } else { - tz = fmt.Sprintf("%03d00", offset/3600) - } - return fmt.Sprintf("%04d-%02d-%02dT%02d-%02d-%02d.%09d%s", - t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), tz) -} diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go deleted file mode 100644 index fb72f0eb14..0000000000 --- a/accounts/keystore/keystore.go +++ /dev/null @@ -1,525 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package keystore implements encrypted storage of secp256k1 private keys. -// -// Keys are stored as encrypted JSON files according to the Web3 Secret Storage specification. -// See https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition for more information. -package keystore - -import ( - "crypto/ecdsa" - crand "crypto/rand" - "errors" - "math/big" - "os" - "path/filepath" - "reflect" - "runtime" - "sync" - "time" - - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" -) - -var ( - ErrLocked = accounts.NewAuthNeededError("password or unlock") - ErrNoMatch = errors.New("no key for given address or file") - ErrDecrypt = errors.New("could not decrypt key with given password") - - // ErrAccountAlreadyExists is returned if an account attempted to import is - // already present in the keystore. - ErrAccountAlreadyExists = errors.New("account already exists") -) - -// KeyStoreType is the reflect type of a keystore backend. -var KeyStoreType = reflect.TypeOf(&KeyStore{}) - -// KeyStoreScheme is the protocol scheme prefixing account and wallet URLs. -const KeyStoreScheme = "keystore" - -// Maximum time between wallet refreshes (if filesystem notifications don't work). -const walletRefreshCycle = 3 * time.Second - -// KeyStore manages a key storage directory on disk. -type KeyStore struct { - storage keyStore // Storage backend, might be cleartext or encrypted - cache *accountCache // In-memory account cache over the filesystem storage - changes chan struct{} // Channel receiving change notifications from the cache - unlocked map[common.Address]*unlocked // Currently unlocked account (decrypted private keys) - - wallets []accounts.Wallet // Wallet wrappers around the individual key files - updateFeed event.Feed // Event feed to notify wallet additions/removals - updateScope event.SubscriptionScope // Subscription scope tracking current live listeners - updating bool // Whether the event notification loop is running - - mu sync.RWMutex - importMu sync.Mutex // Import Mutex locks the import to prevent two insertions from racing -} - -type unlocked struct { - *Key - abort chan struct{} -} - -// NewKeyStore creates a keystore for the given directory. -func NewKeyStore(keydir string, scryptN, scryptP int) *KeyStore { - keydir, _ = filepath.Abs(keydir) - ks := &KeyStore{storage: &keyStorePassphrase{keydir, scryptN, scryptP, false}} - ks.init(keydir) - return ks -} - -// NewPlaintextKeyStore creates a keystore for the given directory. -// Deprecated: Use NewKeyStore. -func NewPlaintextKeyStore(keydir string) *KeyStore { - keydir, _ = filepath.Abs(keydir) - ks := &KeyStore{storage: &keyStorePlain{keydir}} - ks.init(keydir) - return ks -} - -func (ks *KeyStore) init(keydir string) { - // Lock the mutex since the account cache might call back with events - ks.mu.Lock() - defer ks.mu.Unlock() - - // Initialize the set of unlocked keys and the account cache - ks.unlocked = make(map[common.Address]*unlocked) - ks.cache, ks.changes = newAccountCache(keydir) - - // TODO: In order for this finalizer to work, there must be no references - // to ks. addressCache doesn't keep a reference but unlocked keys do, - // so the finalizer will not trigger until all timed unlocks have expired. - runtime.SetFinalizer(ks, func(m *KeyStore) { - m.cache.close() - }) - // Create the initial list of wallets from the cache - accs := ks.cache.accounts() - ks.wallets = make([]accounts.Wallet, len(accs)) - for i := 0; i < len(accs); i++ { - ks.wallets[i] = &keystoreWallet{account: accs[i], keystore: ks} - } -} - -// Wallets implements accounts.Backend, returning all single-key wallets from the -// keystore directory. -func (ks *KeyStore) Wallets() []accounts.Wallet { - // Make sure the list of wallets is in sync with the account cache - ks.refreshWallets() - - ks.mu.RLock() - defer ks.mu.RUnlock() - - cpy := make([]accounts.Wallet, len(ks.wallets)) - copy(cpy, ks.wallets) - return cpy -} - -// refreshWallets retrieves the current account list and based on that does any -// necessary wallet refreshes. -func (ks *KeyStore) refreshWallets() { - // Retrieve the current list of accounts - ks.mu.Lock() - accs := ks.cache.accounts() - - // Transform the current list of wallets into the new one - var ( - wallets = make([]accounts.Wallet, 0, len(accs)) - events []accounts.WalletEvent - ) - - for _, account := range accs { - // Drop wallets while they were in front of the next account - for len(ks.wallets) > 0 && ks.wallets[0].URL().Cmp(account.URL) < 0 { - events = append(events, accounts.WalletEvent{Wallet: ks.wallets[0], Kind: accounts.WalletDropped}) - ks.wallets = ks.wallets[1:] - } - // If there are no more wallets or the account is before the next, wrap new wallet - if len(ks.wallets) == 0 || ks.wallets[0].URL().Cmp(account.URL) > 0 { - wallet := &keystoreWallet{account: account, keystore: ks} - - events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived}) - wallets = append(wallets, wallet) - continue - } - // If the account is the same as the first wallet, keep it - if ks.wallets[0].Accounts()[0] == account { - wallets = append(wallets, ks.wallets[0]) - ks.wallets = ks.wallets[1:] - continue - } - } - // Drop any leftover wallets and set the new batch - for _, wallet := range ks.wallets { - events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) - } - ks.wallets = wallets - ks.mu.Unlock() - - // Fire all wallet events and return - for _, event := range events { - ks.updateFeed.Send(event) - } -} - -// Subscribe implements accounts.Backend, creating an async subscription to -// receive notifications on the addition or removal of keystore wallets. -func (ks *KeyStore) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { - // We need the mutex to reliably start/stop the update loop - ks.mu.Lock() - defer ks.mu.Unlock() - - // Subscribe the caller and track the subscriber count - sub := ks.updateScope.Track(ks.updateFeed.Subscribe(sink)) - - // Subscribers require an active notification loop, start it - if !ks.updating { - ks.updating = true - go ks.updater() - } - return sub -} - -// updater is responsible for maintaining an up-to-date list of wallets stored in -// the keystore, and for firing wallet addition/removal events. It listens for -// account change events from the underlying account cache, and also periodically -// forces a manual refresh (only triggers for systems where the filesystem notifier -// is not running). -func (ks *KeyStore) updater() { - for { - // Wait for an account update or a refresh timeout - select { - case <-ks.changes: - case <-time.After(walletRefreshCycle): - } - // Run the wallet refresher - ks.refreshWallets() - - // If all our subscribers left, stop the updater - ks.mu.Lock() - if ks.updateScope.Count() == 0 { - ks.updating = false - ks.mu.Unlock() - return - } - ks.mu.Unlock() - } -} - -// HasAddress reports whether a key with the given address is present. -func (ks *KeyStore) HasAddress(addr common.Address) bool { - return ks.cache.hasAddress(addr) -} - -// Accounts returns all key files present in the directory. -func (ks *KeyStore) Accounts() []accounts.Account { - return ks.cache.accounts() -} - -// Delete deletes the key matched by account if the passphrase is correct. -// If the account contains no filename, the address must match a unique key. -func (ks *KeyStore) Delete(a accounts.Account, passphrase string) error { - // Decrypting the key isn't really necessary, but we do - // it anyway to check the password and zero out the key - // immediately afterwards. - a, key, err := ks.getDecryptedKey(a, passphrase) - if key != nil { - zeroKey(key.PrivateKey) - } - if err != nil { - return err - } - // The order is crucial here. The key is dropped from the - // cache after the file is gone so that a reload happening in - // between won't insert it into the cache again. - err = os.Remove(a.URL.Path) - if err == nil { - ks.cache.delete(a) - ks.refreshWallets() - } - return err -} - -// SignHash calculates a ECDSA signature for the given hash. The produced -// signature is in the [R || S || V] format where V is 0 or 1. -func (ks *KeyStore) SignHash(a accounts.Account, hash []byte) ([]byte, error) { - // Look up the key to sign with and abort if it cannot be found - ks.mu.RLock() - defer ks.mu.RUnlock() - - unlockedKey, found := ks.unlocked[a.Address] - if !found { - return nil, ErrLocked - } - // Sign the hash using plain ECDSA operations - return crypto.Sign(hash, unlockedKey.PrivateKey) -} - -// SignTx signs the given transaction with the requested account. -func (ks *KeyStore) SignTx(a accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - // Look up the key to sign with and abort if it cannot be found - ks.mu.RLock() - defer ks.mu.RUnlock() - - unlockedKey, found := ks.unlocked[a.Address] - if !found { - return nil, ErrLocked - } - // Depending on the presence of the chain ID, sign with 2718 or homestead - signer := types.LatestSignerForChainID(chainID) - return types.SignTx(tx, signer, unlockedKey.PrivateKey) -} - -// SignHashWithPassphrase signs hash if the private key matching the given address -// can be decrypted with the given passphrase. The produced signature is in the -// [R || S || V] format where V is 0 or 1. -func (ks *KeyStore) SignHashWithPassphrase(a accounts.Account, passphrase string, hash []byte) (signature []byte, err error) { - _, key, err := ks.getDecryptedKey(a, passphrase) - if err != nil { - return nil, err - } - defer zeroKey(key.PrivateKey) - return crypto.Sign(hash, key.PrivateKey) -} - -// SignTxWithPassphrase signs the transaction if the private key matching the -// given address can be decrypted with the given passphrase. -func (ks *KeyStore) SignTxWithPassphrase(a accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - _, key, err := ks.getDecryptedKey(a, passphrase) - if err != nil { - return nil, err - } - defer zeroKey(key.PrivateKey) - // Depending on the presence of the chain ID, sign with or without replay protection. - signer := types.LatestSignerForChainID(chainID) - return types.SignTx(tx, signer, key.PrivateKey) -} - -// Unlock unlocks the given account indefinitely. -func (ks *KeyStore) Unlock(a accounts.Account, passphrase string) error { - return ks.TimedUnlock(a, passphrase, 0) -} - -// Lock removes the private key with the given address from memory. -func (ks *KeyStore) Lock(addr common.Address) error { - ks.mu.Lock() - if unl, found := ks.unlocked[addr]; found { - ks.mu.Unlock() - ks.expire(addr, unl, time.Duration(0)*time.Nanosecond) - } else { - ks.mu.Unlock() - } - return nil -} - -// TimedUnlock unlocks the given account with the passphrase. The account -// stays unlocked for the duration of timeout. A timeout of 0 unlocks the account -// until the program exits. The account must match a unique key file. -// -// If the account address is already unlocked for a duration, TimedUnlock extends or -// shortens the active unlock timeout. If the address was previously unlocked -// indefinitely the timeout is not altered. -func (ks *KeyStore) TimedUnlock(a accounts.Account, passphrase string, timeout time.Duration) error { - a, key, err := ks.getDecryptedKey(a, passphrase) - if err != nil { - return err - } - - ks.mu.Lock() - defer ks.mu.Unlock() - u, found := ks.unlocked[a.Address] - if found { - if u.abort == nil { - // The address was unlocked indefinitely, so unlocking - // it with a timeout would be confusing. - zeroKey(key.PrivateKey) - return nil - } - // Terminate the expire goroutine and replace it below. - close(u.abort) - } - if timeout > 0 { - u = &unlocked{Key: key, abort: make(chan struct{})} - go ks.expire(a.Address, u, timeout) - } else { - u = &unlocked{Key: key} - } - ks.unlocked[a.Address] = u - return nil -} - -// Find resolves the given account into a unique entry in the keystore. -func (ks *KeyStore) Find(a accounts.Account) (accounts.Account, error) { - ks.cache.maybeReload() - ks.cache.mu.Lock() - a, err := ks.cache.find(a) - ks.cache.mu.Unlock() - return a, err -} - -func (ks *KeyStore) getDecryptedKey(a accounts.Account, auth string) (accounts.Account, *Key, error) { - a, err := ks.Find(a) - if err != nil { - return a, nil, err - } - key, err := ks.storage.GetKey(a.Address, a.URL.Path, auth) - return a, key, err -} - -func (ks *KeyStore) expire(addr common.Address, u *unlocked, timeout time.Duration) { - t := time.NewTimer(timeout) - defer t.Stop() - select { - case <-u.abort: - // just quit - case <-t.C: - ks.mu.Lock() - // only drop if it's still the same key instance that dropLater - // was launched with. we can check that using pointer equality - // because the map stores a new pointer every time the key is - // unlocked. - if ks.unlocked[addr] == u { - zeroKey(u.PrivateKey) - delete(ks.unlocked, addr) - } - ks.mu.Unlock() - } -} - -// NewAccount generates a new key and stores it into the key directory, -// encrypting it with the passphrase. -func (ks *KeyStore) NewAccount(passphrase string) (accounts.Account, error) { - _, account, err := storeNewKey(ks.storage, crand.Reader, passphrase) - if err != nil { - return accounts.Account{}, err - } - // Add the account to the cache immediately rather - // than waiting for file system notifications to pick it up. - ks.cache.add(account) - ks.refreshWallets() - return account, nil -} - -// Export exports as a JSON key, encrypted with newPassphrase. -func (ks *KeyStore) Export(a accounts.Account, passphrase, newPassphrase string) (keyJSON []byte, err error) { - _, key, err := ks.getDecryptedKey(a, passphrase) - if err != nil { - return nil, err - } - var N, P int - if store, ok := ks.storage.(*keyStorePassphrase); ok { - N, P = store.scryptN, store.scryptP - } else { - N, P = StandardScryptN, StandardScryptP - } - return EncryptKey(key, newPassphrase, N, P) -} - -// Import stores the given encrypted JSON key into the key directory. -func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (accounts.Account, error) { - key, err := DecryptKey(keyJSON, passphrase) - if key != nil && key.PrivateKey != nil { - defer zeroKey(key.PrivateKey) - } - if err != nil { - return accounts.Account{}, err - } - ks.importMu.Lock() - defer ks.importMu.Unlock() - - if ks.cache.hasAddress(key.Address) { - return accounts.Account{ - Address: key.Address, - }, ErrAccountAlreadyExists - } - return ks.importKey(key, newPassphrase) -} - -// ImportECDSA stores the given key into the key directory, encrypting it with the passphrase. -func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) { - ks.importMu.Lock() - defer ks.importMu.Unlock() - - key := newKeyFromECDSA(priv) - if ks.cache.hasAddress(key.Address) { - return accounts.Account{ - Address: key.Address, - }, ErrAccountAlreadyExists - } - return ks.importKey(key, passphrase) -} - -func (ks *KeyStore) importKey(key *Key, passphrase string) (accounts.Account, error) { - a := accounts.Account{Address: key.Address, URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.storage.JoinPath(keyFileName(key.Address))}} - if err := ks.storage.StoreKey(a.URL.Path, key, passphrase); err != nil { - return accounts.Account{}, err - } - ks.cache.add(a) - ks.refreshWallets() - return a, nil -} - -// Update changes the passphrase of an existing account. -func (ks *KeyStore) Update(a accounts.Account, passphrase, newPassphrase string) error { - a, key, err := ks.getDecryptedKey(a, passphrase) - if err != nil { - return err - } - return ks.storage.StoreKey(a.URL.Path, key, newPassphrase) -} - -// ImportPreSaleKey decrypts the given Ethereum presale wallet and stores -// a key file in the key directory. The key file is encrypted with the same passphrase. -func (ks *KeyStore) ImportPreSaleKey(keyJSON []byte, passphrase string) (accounts.Account, error) { - a, _, err := importPreSaleKey(ks.storage, keyJSON, passphrase) - if err != nil { - return a, err - } - ks.cache.add(a) - ks.refreshWallets() - return a, nil -} - -// isUpdating returns whether the event notification loop is running. -// This method is mainly meant for tests. -func (ks *KeyStore) isUpdating() bool { - ks.mu.RLock() - defer ks.mu.RUnlock() - return ks.updating -} - -// zeroKey zeroes a private key in memory. -func zeroKey(k *ecdsa.PrivateKey) { - b := k.D.Bits() - for i := range b { - b[i] = 0 - } -} diff --git a/accounts/keystore/keystore_test.go b/accounts/keystore/keystore_test.go deleted file mode 100644 index 25dc517c6b..0000000000 --- a/accounts/keystore/keystore_test.go +++ /dev/null @@ -1,477 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "math/rand" - "os" - "runtime" - "strings" - "sync" - "sync/atomic" - "testing" - "time" - - "github.com/ava-labs/coreth/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" - "golang.org/x/exp/slices" -) - -var testSigData = make([]byte, 32) - -func TestKeyStore(t *testing.T) { - t.Parallel() - dir, ks := tmpKeyStore(t, true) - - a, err := ks.NewAccount("foo") - if err != nil { - t.Fatal(err) - } - if !strings.HasPrefix(a.URL.Path, dir) { - t.Errorf("account file %s doesn't have dir prefix", a.URL) - } - stat, err := os.Stat(a.URL.Path) - if err != nil { - t.Fatalf("account file %s doesn't exist (%v)", a.URL, err) - } - if runtime.GOOS != "windows" && stat.Mode() != 0600 { - t.Fatalf("account file has wrong mode: got %o, want %o", stat.Mode(), 0600) - } - if !ks.HasAddress(a.Address) { - t.Errorf("HasAccount(%x) should've returned true", a.Address) - } - if err := ks.Update(a, "foo", "bar"); err != nil { - t.Errorf("Update error: %v", err) - } - if err := ks.Delete(a, "bar"); err != nil { - t.Errorf("Delete error: %v", err) - } - if common.FileExist(a.URL.Path) { - t.Errorf("account file %s should be gone after Delete", a.URL) - } - if ks.HasAddress(a.Address) { - t.Errorf("HasAccount(%x) should've returned true after Delete", a.Address) - } -} - -func TestSign(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, true) - - pass := "" // not used but required by API - a1, err := ks.NewAccount(pass) - if err != nil { - t.Fatal(err) - } - if err := ks.Unlock(a1, ""); err != nil { - t.Fatal(err) - } - if _, err := ks.SignHash(accounts.Account{Address: a1.Address}, testSigData); err != nil { - t.Fatal(err) - } -} - -func TestSignWithPassphrase(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, true) - - pass := "passwd" - acc, err := ks.NewAccount(pass) - if err != nil { - t.Fatal(err) - } - - if _, unlocked := ks.unlocked[acc.Address]; unlocked { - t.Fatal("expected account to be locked") - } - - _, err = ks.SignHashWithPassphrase(acc, pass, testSigData) - if err != nil { - t.Fatal(err) - } - - if _, unlocked := ks.unlocked[acc.Address]; unlocked { - t.Fatal("expected account to be locked") - } - - if _, err = ks.SignHashWithPassphrase(acc, "invalid passwd", testSigData); err == nil { - t.Fatal("expected SignHashWithPassphrase to fail with invalid password") - } -} - -func TestTimedUnlock(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, true) - - pass := "foo" - a1, err := ks.NewAccount(pass) - if err != nil { - t.Fatal(err) - } - - // Signing without passphrase fails because account is locked - _, err = ks.SignHash(accounts.Account{Address: a1.Address}, testSigData) - if err != ErrLocked { - t.Fatal("Signing should've failed with ErrLocked before unlocking, got ", err) - } - - // Signing with passphrase works - if err = ks.TimedUnlock(a1, pass, 100*time.Millisecond); err != nil { - t.Fatal(err) - } - - // Signing without passphrase works because account is temp unlocked - _, err = ks.SignHash(accounts.Account{Address: a1.Address}, testSigData) - if err != nil { - t.Fatal("Signing shouldn't return an error after unlocking, got ", err) - } - - // Signing fails again after automatic locking - time.Sleep(250 * time.Millisecond) - _, err = ks.SignHash(accounts.Account{Address: a1.Address}, testSigData) - if err != ErrLocked { - t.Fatal("Signing should've failed with ErrLocked timeout expired, got ", err) - } -} - -func TestOverrideUnlock(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, false) - - pass := "foo" - a1, err := ks.NewAccount(pass) - if err != nil { - t.Fatal(err) - } - - // Unlock indefinitely. - if err = ks.TimedUnlock(a1, pass, 5*time.Minute); err != nil { - t.Fatal(err) - } - - // Signing without passphrase works because account is temp unlocked - _, err = ks.SignHash(accounts.Account{Address: a1.Address}, testSigData) - if err != nil { - t.Fatal("Signing shouldn't return an error after unlocking, got ", err) - } - - // reset unlock to a shorter period, invalidates the previous unlock - if err = ks.TimedUnlock(a1, pass, 100*time.Millisecond); err != nil { - t.Fatal(err) - } - - // Signing without passphrase still works because account is temp unlocked - _, err = ks.SignHash(accounts.Account{Address: a1.Address}, testSigData) - if err != nil { - t.Fatal("Signing shouldn't return an error after unlocking, got ", err) - } - - // Signing fails again after automatic locking - time.Sleep(250 * time.Millisecond) - _, err = ks.SignHash(accounts.Account{Address: a1.Address}, testSigData) - if err != ErrLocked { - t.Fatal("Signing should've failed with ErrLocked timeout expired, got ", err) - } -} - -// This test should fail under -race if signing races the expiration goroutine. -func TestSignRace(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, false) - - // Create a test account. - a1, err := ks.NewAccount("") - if err != nil { - t.Fatal("could not create the test account", err) - } - - if err := ks.TimedUnlock(a1, "", 15*time.Millisecond); err != nil { - t.Fatal("could not unlock the test account", err) - } - end := time.Now().Add(500 * time.Millisecond) - for time.Now().Before(end) { - if _, err := ks.SignHash(accounts.Account{Address: a1.Address}, testSigData); err == ErrLocked { - return - } else if err != nil { - t.Errorf("Sign error: %v", err) - return - } - time.Sleep(1 * time.Millisecond) - } - t.Errorf("Account did not lock within the timeout") -} - -// waitForKsUpdating waits until the updating-status of the ks reaches the -// desired wantStatus. -// It waits for a maximum time of maxTime, and returns false if it does not -// finish in time -func waitForKsUpdating(t *testing.T, ks *KeyStore, wantStatus bool, maxTime time.Duration) bool { - t.Helper() - // Wait max 250 ms, then return false - for t0 := time.Now(); time.Since(t0) < maxTime; { - if ks.isUpdating() == wantStatus { - return true - } - time.Sleep(25 * time.Millisecond) - } - return false -} - -// Tests that the wallet notifier loop starts and stops correctly based on the -// addition and removal of wallet event subscriptions. -func TestWalletNotifierLifecycle(t *testing.T) { - t.Parallel() - // Create a temporary keystore to test with - _, ks := tmpKeyStore(t, false) - - // Ensure that the notification updater is not running yet - time.Sleep(250 * time.Millisecond) - - if ks.isUpdating() { - t.Errorf("wallet notifier running without subscribers") - } - // Subscribe to the wallet feed and ensure the updater boots up - updates := make(chan accounts.WalletEvent) - - subs := make([]event.Subscription, 2) - for i := 0; i < len(subs); i++ { - // Create a new subscription - subs[i] = ks.Subscribe(updates) - if !waitForKsUpdating(t, ks, true, 250*time.Millisecond) { - t.Errorf("sub %d: wallet notifier not running after subscription", i) - } - } - // Close all but one sub - for i := 0; i < len(subs)-1; i++ { - // Close an existing subscription - subs[i].Unsubscribe() - } - // Check that it is still running - time.Sleep(250 * time.Millisecond) - - if !ks.isUpdating() { - t.Fatal("event notifier stopped prematurely") - } - // Unsubscribe the last one and ensure the updater terminates eventually. - subs[len(subs)-1].Unsubscribe() - if !waitForKsUpdating(t, ks, false, 4*time.Second) { - t.Errorf("wallet notifier didn't terminate after unsubscribe") - } -} - -type walletEvent struct { - accounts.WalletEvent - a accounts.Account -} - -// Tests that wallet notifications and correctly fired when accounts are added -// or deleted from the keystore. -func TestWalletNotifications(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, false) - - // Subscribe to the wallet feed and collect events. - var ( - events []walletEvent - updates = make(chan accounts.WalletEvent) - sub = ks.Subscribe(updates) - ) - defer sub.Unsubscribe() - go func() { - for { - select { - case ev := <-updates: - events = append(events, walletEvent{ev, ev.Wallet.Accounts()[0]}) - case <-sub.Err(): - close(updates) - return - } - } - }() - - // Randomly add and remove accounts. - var ( - live = make(map[common.Address]accounts.Account) - wantEvents []walletEvent - ) - for i := 0; i < 1024; i++ { - if create := len(live) == 0 || rand.Int()%4 > 0; create { - // Add a new account and ensure wallet notifications arrives - account, err := ks.NewAccount("") - if err != nil { - t.Fatalf("failed to create test account: %v", err) - } - live[account.Address] = account - wantEvents = append(wantEvents, walletEvent{accounts.WalletEvent{Kind: accounts.WalletArrived}, account}) - } else { - // Delete a random account. - var account accounts.Account - for _, a := range live { - account = a - break - } - if err := ks.Delete(account, ""); err != nil { - t.Fatalf("failed to delete test account: %v", err) - } - delete(live, account.Address) - wantEvents = append(wantEvents, walletEvent{accounts.WalletEvent{Kind: accounts.WalletDropped}, account}) - } - } - - // Shut down the event collector and check events. - sub.Unsubscribe() - for ev := range updates { - events = append(events, walletEvent{ev, ev.Wallet.Accounts()[0]}) - } - checkAccounts(t, live, ks.Wallets()) - checkEvents(t, wantEvents, events) -} - -// TestImportExport tests the import functionality of a keystore. -func TestImportECDSA(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, true) - key, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("failed to generate key: %v", key) - } - if _, err = ks.ImportECDSA(key, "old"); err != nil { - t.Errorf("importing failed: %v", err) - } - if _, err = ks.ImportECDSA(key, "old"); err == nil { - t.Errorf("importing same key twice succeeded") - } - if _, err = ks.ImportECDSA(key, "new"); err == nil { - t.Errorf("importing same key twice succeeded") - } -} - -// TestImportECDSA tests the import and export functionality of a keystore. -func TestImportExport(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, true) - acc, err := ks.NewAccount("old") - if err != nil { - t.Fatalf("failed to create account: %v", acc) - } - json, err := ks.Export(acc, "old", "new") - if err != nil { - t.Fatalf("failed to export account: %v", acc) - } - _, ks2 := tmpKeyStore(t, true) - if _, err = ks2.Import(json, "old", "old"); err == nil { - t.Errorf("importing with invalid password succeeded") - } - acc2, err := ks2.Import(json, "new", "new") - if err != nil { - t.Errorf("importing failed: %v", err) - } - if acc.Address != acc2.Address { - t.Error("imported account does not match exported account") - } - if _, err = ks2.Import(json, "new", "new"); err == nil { - t.Errorf("importing a key twice succeeded") - } -} - -// TestImportRace tests the keystore on races. -// This test should fail under -race if importing races. -func TestImportRace(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStore(t, true) - acc, err := ks.NewAccount("old") - if err != nil { - t.Fatalf("failed to create account: %v", acc) - } - json, err := ks.Export(acc, "old", "new") - if err != nil { - t.Fatalf("failed to export account: %v", acc) - } - _, ks2 := tmpKeyStore(t, true) - var atom atomic.Uint32 - var wg sync.WaitGroup - wg.Add(2) - for i := 0; i < 2; i++ { - go func() { - defer wg.Done() - if _, err := ks2.Import(json, "new", "new"); err != nil { - atom.Add(1) - } - }() - } - wg.Wait() - if atom.Load() != 1 { - t.Errorf("Import is racy") - } -} - -// checkAccounts checks that all known live accounts are present in the wallet list. -func checkAccounts(t *testing.T, live map[common.Address]accounts.Account, wallets []accounts.Wallet) { - if len(live) != len(wallets) { - t.Errorf("wallet list doesn't match required accounts: have %d, want %d", len(wallets), len(live)) - return - } - liveList := make([]accounts.Account, 0, len(live)) - for _, account := range live { - liveList = append(liveList, account) - } - slices.SortFunc(liveList, byURL) - for j, wallet := range wallets { - if accs := wallet.Accounts(); len(accs) != 1 { - t.Errorf("wallet %d: contains invalid number of accounts: have %d, want 1", j, len(accs)) - } else if accs[0] != liveList[j] { - t.Errorf("wallet %d: account mismatch: have %v, want %v", j, accs[0], liveList[j]) - } - } -} - -// checkEvents checks that all events in 'want' are present in 'have'. Events may be present multiple times. -func checkEvents(t *testing.T, want []walletEvent, have []walletEvent) { - for _, wantEv := range want { - nmatch := 0 - for ; len(have) > 0; nmatch++ { - if have[0].Kind != wantEv.Kind || have[0].a != wantEv.a { - break - } - have = have[1:] - } - if nmatch == 0 { - t.Fatalf("can't find event with Kind=%v for %x", wantEv.Kind, wantEv.a.Address) - } - } -} - -func tmpKeyStore(t *testing.T, encrypted bool) (string, *KeyStore) { - d := t.TempDir() - newKs := NewPlaintextKeyStore - if encrypted { - newKs = func(kd string) *KeyStore { return NewKeyStore(kd, veryLightScryptN, veryLightScryptP) } - } - return d, newKs(d) -} diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go deleted file mode 100644 index 73318da4ff..0000000000 --- a/accounts/keystore/passphrase.go +++ /dev/null @@ -1,378 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -/* - -This key store behaves as KeyStorePlain with the difference that -the private key is encrypted and on disk uses another JSON encoding. - -The crypto is documented at https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition - -*/ - -package keystore - -import ( - "bytes" - "crypto/aes" - "crypto/rand" - "crypto/sha256" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "os" - "path/filepath" - - "github.com/ava-labs/coreth/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/google/uuid" - "golang.org/x/crypto/pbkdf2" - "golang.org/x/crypto/scrypt" -) - -const ( - keyHeaderKDF = "scrypt" - - // StandardScryptN is the N parameter of Scrypt encryption algorithm, using 256MB - // memory and taking approximately 1s CPU time on a modern processor. - StandardScryptN = 1 << 18 - - // StandardScryptP is the P parameter of Scrypt encryption algorithm, using 256MB - // memory and taking approximately 1s CPU time on a modern processor. - StandardScryptP = 1 - - // LightScryptN is the N parameter of Scrypt encryption algorithm, using 4MB - // memory and taking approximately 100ms CPU time on a modern processor. - LightScryptN = 1 << 12 - - // LightScryptP is the P parameter of Scrypt encryption algorithm, using 4MB - // memory and taking approximately 100ms CPU time on a modern processor. - LightScryptP = 6 - - scryptR = 8 - scryptDKLen = 32 -) - -type keyStorePassphrase struct { - keysDirPath string - scryptN int - scryptP int - // skipKeyFileVerification disables the security-feature which does - // reads and decrypts any newly created keyfiles. This should be 'false' in all - // cases except tests -- setting this to 'true' is not recommended. - skipKeyFileVerification bool -} - -func (ks keyStorePassphrase) GetKey(addr common.Address, filename, auth string) (*Key, error) { - // Load the key from the keystore and decrypt its contents - keyjson, err := os.ReadFile(filename) - if err != nil { - return nil, err - } - key, err := DecryptKey(keyjson, auth) - if err != nil { - return nil, err - } - // Make sure we're really operating on the requested key (no swap attacks) - if key.Address != addr { - return nil, fmt.Errorf("key content mismatch: have account %x, want %x", key.Address, addr) - } - return key, nil -} - -// StoreKey generates a key, encrypts with 'auth' and stores in the given directory -func StoreKey(dir, auth string, scryptN, scryptP int) (accounts.Account, error) { - _, a, err := storeNewKey(&keyStorePassphrase{dir, scryptN, scryptP, false}, rand.Reader, auth) - return a, err -} - -func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) error { - keyjson, err := EncryptKey(key, auth, ks.scryptN, ks.scryptP) - if err != nil { - return err - } - // Write into temporary file - tmpName, err := writeTemporaryKeyFile(filename, keyjson) - if err != nil { - return err - } - if !ks.skipKeyFileVerification { - // Verify that we can decrypt the file with the given password. - _, err = ks.GetKey(key.Address, tmpName, auth) - if err != nil { - msg := "An error was encountered when saving and verifying the keystore file. \n" + - "This indicates that the keystore is corrupted. \n" + - "The corrupted file is stored at \n%v\n" + - "Please file a ticket at:\n\n" + - "https://github.com/ethereum/go-ethereum/issues." + - "The error was : %s" - //lint:ignore ST1005 This is a message for the user - return fmt.Errorf(msg, tmpName, err) - } - } - return os.Rename(tmpName, filename) -} - -func (ks keyStorePassphrase) JoinPath(filename string) string { - if filepath.IsAbs(filename) { - return filename - } - return filepath.Join(ks.keysDirPath, filename) -} - -// EncryptDataV3 encrypts the data given as 'data' with the password 'auth'. -func EncryptDataV3(data, auth []byte, scryptN, scryptP int) (CryptoJSON, error) { - salt := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, salt); err != nil { - panic("reading from crypto/rand failed: " + err.Error()) - } - derivedKey, err := scrypt.Key(auth, salt, scryptN, scryptR, scryptP, scryptDKLen) - if err != nil { - return CryptoJSON{}, err - } - encryptKey := derivedKey[:16] - - iv := make([]byte, aes.BlockSize) // 16 - if _, err := io.ReadFull(rand.Reader, iv); err != nil { - panic("reading from crypto/rand failed: " + err.Error()) - } - cipherText, err := aesCTRXOR(encryptKey, data, iv) - if err != nil { - return CryptoJSON{}, err - } - mac := crypto.Keccak256(derivedKey[16:32], cipherText) - - scryptParamsJSON := make(map[string]interface{}, 5) - scryptParamsJSON["n"] = scryptN - scryptParamsJSON["r"] = scryptR - scryptParamsJSON["p"] = scryptP - scryptParamsJSON["dklen"] = scryptDKLen - scryptParamsJSON["salt"] = hex.EncodeToString(salt) - cipherParamsJSON := cipherparamsJSON{ - IV: hex.EncodeToString(iv), - } - - cryptoStruct := CryptoJSON{ - Cipher: "aes-128-ctr", - CipherText: hex.EncodeToString(cipherText), - CipherParams: cipherParamsJSON, - KDF: keyHeaderKDF, - KDFParams: scryptParamsJSON, - MAC: hex.EncodeToString(mac), - } - return cryptoStruct, nil -} - -// EncryptKey encrypts a key using the specified scrypt parameters into a json -// blob that can be decrypted later on. -func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) { - keyBytes := math.PaddedBigBytes(key.PrivateKey.D, 32) - cryptoStruct, err := EncryptDataV3(keyBytes, []byte(auth), scryptN, scryptP) - if err != nil { - return nil, err - } - encryptedKeyJSONV3 := encryptedKeyJSONV3{ - hex.EncodeToString(key.Address[:]), - cryptoStruct, - key.Id.String(), - version, - } - return json.Marshal(encryptedKeyJSONV3) -} - -// DecryptKey decrypts a key from a json blob, returning the private key itself. -func DecryptKey(keyjson []byte, auth string) (*Key, error) { - // Parse the json into a simple map to fetch the key version - m := make(map[string]interface{}) - if err := json.Unmarshal(keyjson, &m); err != nil { - return nil, err - } - // Depending on the version try to parse one way or another - var ( - keyBytes, keyId []byte - err error - ) - if version, ok := m["version"].(string); ok && version == "1" { - k := new(encryptedKeyJSONV1) - if err := json.Unmarshal(keyjson, k); err != nil { - return nil, err - } - keyBytes, keyId, err = decryptKeyV1(k, auth) - } else { - k := new(encryptedKeyJSONV3) - if err := json.Unmarshal(keyjson, k); err != nil { - return nil, err - } - keyBytes, keyId, err = decryptKeyV3(k, auth) - } - // Handle any decryption errors and return the key - if err != nil { - return nil, err - } - key, err := crypto.ToECDSA(keyBytes) - if err != nil { - return nil, fmt.Errorf("invalid key: %w", err) - } - id, err := uuid.FromBytes(keyId) - if err != nil { - return nil, fmt.Errorf("invalid UUID: %w", err) - } - return &Key{ - Id: id, - Address: crypto.PubkeyToAddress(key.PublicKey), - PrivateKey: key, - }, nil -} - -func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) { - if cryptoJson.Cipher != "aes-128-ctr" { - return nil, fmt.Errorf("cipher not supported: %v", cryptoJson.Cipher) - } - mac, err := hex.DecodeString(cryptoJson.MAC) - if err != nil { - return nil, err - } - - iv, err := hex.DecodeString(cryptoJson.CipherParams.IV) - if err != nil { - return nil, err - } - - cipherText, err := hex.DecodeString(cryptoJson.CipherText) - if err != nil { - return nil, err - } - - derivedKey, err := getKDFKey(cryptoJson, auth) - if err != nil { - return nil, err - } - - calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText) - if !bytes.Equal(calculatedMAC, mac) { - return nil, ErrDecrypt - } - - plainText, err := aesCTRXOR(derivedKey[:16], cipherText, iv) - if err != nil { - return nil, err - } - return plainText, err -} - -func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) { - if keyProtected.Version != version { - return nil, nil, fmt.Errorf("version not supported: %v", keyProtected.Version) - } - keyUUID, err := uuid.Parse(keyProtected.Id) - if err != nil { - return nil, nil, err - } - keyId = keyUUID[:] - plainText, err := DecryptDataV3(keyProtected.Crypto, auth) - if err != nil { - return nil, nil, err - } - return plainText, keyId, err -} - -func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byte, keyId []byte, err error) { - keyUUID, err := uuid.Parse(keyProtected.Id) - if err != nil { - return nil, nil, err - } - keyId = keyUUID[:] - mac, err := hex.DecodeString(keyProtected.Crypto.MAC) - if err != nil { - return nil, nil, err - } - - iv, err := hex.DecodeString(keyProtected.Crypto.CipherParams.IV) - if err != nil { - return nil, nil, err - } - - cipherText, err := hex.DecodeString(keyProtected.Crypto.CipherText) - if err != nil { - return nil, nil, err - } - - derivedKey, err := getKDFKey(keyProtected.Crypto, auth) - if err != nil { - return nil, nil, err - } - - calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText) - if !bytes.Equal(calculatedMAC, mac) { - return nil, nil, ErrDecrypt - } - - plainText, err := aesCBCDecrypt(crypto.Keccak256(derivedKey[:16])[:16], cipherText, iv) - if err != nil { - return nil, nil, err - } - return plainText, keyId, err -} - -func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) { - authArray := []byte(auth) - salt, err := hex.DecodeString(cryptoJSON.KDFParams["salt"].(string)) - if err != nil { - return nil, err - } - dkLen := ensureInt(cryptoJSON.KDFParams["dklen"]) - - if cryptoJSON.KDF == keyHeaderKDF { - n := ensureInt(cryptoJSON.KDFParams["n"]) - r := ensureInt(cryptoJSON.KDFParams["r"]) - p := ensureInt(cryptoJSON.KDFParams["p"]) - return scrypt.Key(authArray, salt, n, r, p, dkLen) - } else if cryptoJSON.KDF == "pbkdf2" { - c := ensureInt(cryptoJSON.KDFParams["c"]) - prf := cryptoJSON.KDFParams["prf"].(string) - if prf != "hmac-sha256" { - return nil, fmt.Errorf("unsupported PBKDF2 PRF: %s", prf) - } - key := pbkdf2.Key(authArray, salt, c, dkLen, sha256.New) - return key, nil - } - - return nil, fmt.Errorf("unsupported KDF: %s", cryptoJSON.KDF) -} - -// TODO: can we do without this when unmarshalling dynamic JSON? -// why do integers in KDF params end up as float64 and not int after -// unmarshal? -func ensureInt(x interface{}) int { - res, ok := x.(int) - if !ok { - res = int(x.(float64)) - } - return res -} diff --git a/accounts/keystore/passphrase_test.go b/accounts/keystore/passphrase_test.go deleted file mode 100644 index 179e7d0883..0000000000 --- a/accounts/keystore/passphrase_test.go +++ /dev/null @@ -1,71 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "os" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -const ( - veryLightScryptN = 2 - veryLightScryptP = 1 -) - -// Tests that a json key file can be decrypted and encrypted in multiple rounds. -func TestKeyEncryptDecrypt(t *testing.T) { - t.Parallel() - keyjson, err := os.ReadFile("testdata/very-light-scrypt.json") - if err != nil { - t.Fatal(err) - } - password := "" - address := common.HexToAddress("45dea0fb0bba44f4fcf290bba71fd57d7117cbb8") - - // Do a few rounds of decryption and encryption - for i := 0; i < 3; i++ { - // Try a bad password first - if _, err := DecryptKey(keyjson, password+"bad"); err == nil { - t.Errorf("test %d: json key decrypted with bad password", i) - } - // Decrypt with the correct password - key, err := DecryptKey(keyjson, password) - if err != nil { - t.Fatalf("test %d: json key failed to decrypt: %v", i, err) - } - if key.Address != address { - t.Errorf("test %d: key address mismatch: have %x, want %x", i, key.Address, address) - } - // Recrypt with a new password and start over - password += "new data appended" // nolint: gosec - if keyjson, err = EncryptKey(key, password, veryLightScryptN, veryLightScryptP); err != nil { - t.Errorf("test %d: failed to re-encrypt key %v", i, err) - } - } -} diff --git a/accounts/keystore/plain.go b/accounts/keystore/plain.go deleted file mode 100644 index 181eeb2ec0..0000000000 --- a/accounts/keystore/plain.go +++ /dev/null @@ -1,71 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - - "github.com/ethereum/go-ethereum/common" -) - -type keyStorePlain struct { - keysDirPath string -} - -func (ks keyStorePlain) GetKey(addr common.Address, filename, auth string) (*Key, error) { - fd, err := os.Open(filename) - if err != nil { - return nil, err - } - defer fd.Close() - key := new(Key) - if err := json.NewDecoder(fd).Decode(key); err != nil { - return nil, err - } - if key.Address != addr { - return nil, fmt.Errorf("key content mismatch: have address %x, want %x", key.Address, addr) - } - return key, nil -} - -func (ks keyStorePlain) StoreKey(filename string, key *Key, auth string) error { - content, err := json.Marshal(key) - if err != nil { - return err - } - return writeKeyFile(filename, content) -} - -func (ks keyStorePlain) JoinPath(filename string) string { - if filepath.IsAbs(filename) { - return filename - } - return filepath.Join(ks.keysDirPath, filename) -} diff --git a/accounts/keystore/plain_test.go b/accounts/keystore/plain_test.go deleted file mode 100644 index 7d19909fec..0000000000 --- a/accounts/keystore/plain_test.go +++ /dev/null @@ -1,228 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "crypto/rand" - "encoding/hex" - "fmt" - "path/filepath" - "reflect" - "strings" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func tmpKeyStoreIface(t *testing.T, encrypted bool) (dir string, ks keyStore) { - d := t.TempDir() - if encrypted { - ks = &keyStorePassphrase{d, veryLightScryptN, veryLightScryptP, true} - } else { - ks = &keyStorePlain{d} - } - return d, ks -} - -func TestKeyStorePlain(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStoreIface(t, false) - - pass := "" // not used but required by API - k1, account, err := storeNewKey(ks, rand.Reader, pass) - if err != nil { - t.Fatal(err) - } - k2, err := ks.GetKey(k1.Address, account.URL.Path, pass) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(k1.Address, k2.Address) { - t.Fatal(err) - } - if !reflect.DeepEqual(k1.PrivateKey, k2.PrivateKey) { - t.Fatal(err) - } -} - -func TestKeyStorePassphrase(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStoreIface(t, true) - - pass := "foo" - k1, account, err := storeNewKey(ks, rand.Reader, pass) - if err != nil { - t.Fatal(err) - } - k2, err := ks.GetKey(k1.Address, account.URL.Path, pass) - if err != nil { - t.Fatal(err) - } - if !reflect.DeepEqual(k1.Address, k2.Address) { - t.Fatal(err) - } - if !reflect.DeepEqual(k1.PrivateKey, k2.PrivateKey) { - t.Fatal(err) - } -} - -func TestKeyStorePassphraseDecryptionFail(t *testing.T) { - t.Parallel() - _, ks := tmpKeyStoreIface(t, true) - - pass := "foo" - k1, account, err := storeNewKey(ks, rand.Reader, pass) - if err != nil { - t.Fatal(err) - } - if _, err = ks.GetKey(k1.Address, account.URL.Path, "bar"); err != ErrDecrypt { - t.Fatalf("wrong error for invalid password\ngot %q\nwant %q", err, ErrDecrypt) - } -} - -func TestImportPreSaleKey(t *testing.T) { - t.Parallel() - dir, ks := tmpKeyStoreIface(t, true) - - // file content of a presale key file generated with: - // python pyethsaletool.py genwallet - // with password "foo" - fileContent := "{\"encseed\": \"26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba\", \"ethaddr\": \"d4584b5f6229b7be90727b0fc8c6b91bb427821f\", \"email\": \"gustav.simonsson@gmail.com\", \"btcaddr\": \"1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx\"}" - pass := "foo" - account, _, err := importPreSaleKey(ks, []byte(fileContent), pass) - if err != nil { - t.Fatal(err) - } - if account.Address != common.HexToAddress("d4584b5f6229b7be90727b0fc8c6b91bb427821f") { - t.Errorf("imported account has wrong address %x", account.Address) - } - if !strings.HasPrefix(account.URL.Path, dir) { - t.Errorf("imported account file not in keystore directory: %q", account.URL) - } -} - -// Test and utils for the key store tests in the Ethereum JSON tests; -// testdataKeyStoreTests/basic_tests.json -type KeyStoreTestV3 struct { - Json encryptedKeyJSONV3 - Password string - Priv string -} - -type KeyStoreTestV1 struct { - Json encryptedKeyJSONV1 - Password string - Priv string -} - -func TestV3_PBKDF2_1(t *testing.T) { - t.Parallel() - tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t) - testDecryptV3(tests["wikipage_test_vector_pbkdf2"], t) -} - -var testsSubmodule = filepath.Join("..", "..", "tests", "testdata", "KeyStoreTests") - -func skipIfSubmoduleMissing(t *testing.T) { - if !common.FileExist(testsSubmodule) { - t.Skipf("can't find JSON tests from submodule at %s", testsSubmodule) - } -} - -func TestV3_PBKDF2_2(t *testing.T) { - skipIfSubmoduleMissing(t) - t.Parallel() - tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t) - testDecryptV3(tests["test1"], t) -} - -func TestV3_PBKDF2_3(t *testing.T) { - skipIfSubmoduleMissing(t) - t.Parallel() - tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t) - testDecryptV3(tests["python_generated_test_with_odd_iv"], t) -} - -func TestV3_PBKDF2_4(t *testing.T) { - skipIfSubmoduleMissing(t) - t.Parallel() - tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t) - testDecryptV3(tests["evilnonce"], t) -} - -func TestV3_Scrypt_1(t *testing.T) { - t.Parallel() - tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t) - testDecryptV3(tests["wikipage_test_vector_scrypt"], t) -} - -func TestV3_Scrypt_2(t *testing.T) { - skipIfSubmoduleMissing(t) - t.Parallel() - tests := loadKeyStoreTestV3(filepath.Join(testsSubmodule, "basic_tests.json"), t) - testDecryptV3(tests["test2"], t) -} - -func testDecryptV3(test KeyStoreTestV3, t *testing.T) { - privBytes, _, err := decryptKeyV3(&test.Json, test.Password) - if err != nil { - t.Fatal(err) - } - privHex := hex.EncodeToString(privBytes) - if test.Priv != privHex { - t.Fatal(fmt.Errorf("Decrypted bytes not equal to test, expected %v have %v", test.Priv, privHex)) - } -} - -func loadKeyStoreTestV3(file string, t *testing.T) map[string]KeyStoreTestV3 { - tests := make(map[string]KeyStoreTestV3) - err := common.LoadJSON(file, &tests) - if err != nil { - t.Fatal(err) - } - return tests -} - -func TestKeyForDirectICAP(t *testing.T) { - t.Parallel() - key := NewKeyForDirectICAP(rand.Reader) - if !strings.HasPrefix(key.Address.Hex(), "0x00") { - t.Errorf("Expected first address byte to be zero, have: %s", key.Address.Hex()) - } -} - -func TestV3_31_Byte_Key(t *testing.T) { - t.Parallel() - tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t) - testDecryptV3(tests["31_byte_key"], t) -} - -func TestV3_30_Byte_Key(t *testing.T) { - t.Parallel() - tests := loadKeyStoreTestV3("testdata/v3_test_vector.json", t) - testDecryptV3(tests["30_byte_key"], t) -} diff --git a/accounts/keystore/presale.go b/accounts/keystore/presale.go deleted file mode 100644 index 1dfbd9c2a9..0000000000 --- a/accounts/keystore/presale.go +++ /dev/null @@ -1,160 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/sha256" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - - "github.com/ava-labs/coreth/accounts" - "github.com/ethereum/go-ethereum/crypto" - "github.com/google/uuid" - "golang.org/x/crypto/pbkdf2" -) - -// creates a Key and stores that in the given KeyStore by decrypting a presale key JSON -func importPreSaleKey(keyStore keyStore, keyJSON []byte, password string) (accounts.Account, *Key, error) { - key, err := decryptPreSaleKey(keyJSON, password) - if err != nil { - return accounts.Account{}, nil, err - } - key.Id, err = uuid.NewRandom() - if err != nil { - return accounts.Account{}, nil, err - } - a := accounts.Account{ - Address: key.Address, - URL: accounts.URL{ - Scheme: KeyStoreScheme, - Path: keyStore.JoinPath(keyFileName(key.Address)), - }, - } - err = keyStore.StoreKey(a.URL.Path, key, password) - return a, key, err -} - -func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error) { - preSaleKeyStruct := struct { - EncSeed string - EthAddr string - Email string - BtcAddr string - }{} - err = json.Unmarshal(fileContent, &preSaleKeyStruct) - if err != nil { - return nil, err - } - encSeedBytes, err := hex.DecodeString(preSaleKeyStruct.EncSeed) - if err != nil { - return nil, errors.New("invalid hex in encSeed") - } - if len(encSeedBytes) < 16 { - return nil, errors.New("invalid encSeed, too short") - } - iv := encSeedBytes[:16] - cipherText := encSeedBytes[16:] - /* - See https://github.com/ethereum/pyethsaletool - - pyethsaletool generates the encryption key from password by - 2000 rounds of PBKDF2 with HMAC-SHA-256 using password as salt (:(). - 16 byte key length within PBKDF2 and resulting key is used as AES key - */ - passBytes := []byte(password) - derivedKey := pbkdf2.Key(passBytes, passBytes, 2000, 16, sha256.New) - plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv) - if err != nil { - return nil, err - } - ethPriv := crypto.Keccak256(plainText) - ecKey := crypto.ToECDSAUnsafe(ethPriv) - - key = &Key{ - Id: uuid.UUID{}, - Address: crypto.PubkeyToAddress(ecKey.PublicKey), - PrivateKey: ecKey, - } - derivedAddr := hex.EncodeToString(key.Address.Bytes()) // needed because .Hex() gives leading "0x" - expectedAddr := preSaleKeyStruct.EthAddr - if derivedAddr != expectedAddr { - err = fmt.Errorf("decrypted addr '%s' not equal to expected addr '%s'", derivedAddr, expectedAddr) - } - return key, err -} - -func aesCTRXOR(key, inText, iv []byte) ([]byte, error) { - // AES-128 is selected due to size of encryptKey. - aesBlock, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - stream := cipher.NewCTR(aesBlock, iv) - outText := make([]byte, len(inText)) - stream.XORKeyStream(outText, inText) - return outText, err -} - -func aesCBCDecrypt(key, cipherText, iv []byte) ([]byte, error) { - aesBlock, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - decrypter := cipher.NewCBCDecrypter(aesBlock, iv) - paddedPlaintext := make([]byte, len(cipherText)) - decrypter.CryptBlocks(paddedPlaintext, cipherText) - plaintext := pkcs7Unpad(paddedPlaintext) - if plaintext == nil { - return nil, ErrDecrypt - } - return plaintext, err -} - -// From https://leanpub.com/gocrypto/read#leanpub-auto-block-cipher-modes -func pkcs7Unpad(in []byte) []byte { - if len(in) == 0 { - return nil - } - - padding := in[len(in)-1] - if int(padding) > len(in) || padding > aes.BlockSize { - return nil - } else if padding == 0 { - return nil - } - - for i := len(in) - 1; i > len(in)-int(padding)-1; i-- { - if in[i] != padding { - return nil - } - } - return in[:len(in)-int(padding)] -} diff --git a/accounts/keystore/testdata/dupes/1 b/accounts/keystore/testdata/dupes/1 deleted file mode 100644 index a3868ec6d5..0000000000 --- a/accounts/keystore/testdata/dupes/1 +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/dupes/2 b/accounts/keystore/testdata/dupes/2 deleted file mode 100644 index a3868ec6d5..0000000000 --- a/accounts/keystore/testdata/dupes/2 +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/dupes/foo b/accounts/keystore/testdata/dupes/foo deleted file mode 100644 index c57060aea0..0000000000 --- a/accounts/keystore/testdata/dupes/foo +++ /dev/null @@ -1 +0,0 @@ -{"address":"7ef5a6135f1fd6a02593eedc869c6d41d934aef8","crypto":{"cipher":"aes-128-ctr","ciphertext":"1d0839166e7a15b9c1333fc865d69858b22df26815ccf601b28219b6192974e1","cipherparams":{"iv":"8df6caa7ff1b00c4e871f002cb7921ed"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"e5e6ef3f4ea695f496b643ebd3f75c0aa58ef4070e90c80c5d3fb0241bf1595c"},"mac":"6d16dfde774845e4585357f24bce530528bc69f4f84e1e22880d34fa45c273e5"},"id":"950077c7-71e3-4c44-a4a1-143919141ed4","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/keystore/.hiddenfile b/accounts/keystore/testdata/keystore/.hiddenfile deleted file mode 100644 index d91faccdeb..0000000000 --- a/accounts/keystore/testdata/keystore/.hiddenfile +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} diff --git a/accounts/keystore/testdata/keystore/README b/accounts/keystore/testdata/keystore/README deleted file mode 100644 index 6af9ac3f1b..0000000000 --- a/accounts/keystore/testdata/keystore/README +++ /dev/null @@ -1,21 +0,0 @@ -This directory contains accounts for testing. -The password that unlocks them is "foobar". - -The "good" key files which are supposed to be loadable are: - -- File: UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 - Address: 0x7ef5a6135f1fd6a02593eedc869c6d41d934aef8 -- File: aaa - Address: 0xf466859ead1932d743d622cb74fc058882e8648a -- File: zzz - Address: 0x289d485d9771714cce91d3393d764e1311907acc - -The other files (including this README) are broken in various ways -and should not be picked up by package accounts: - -- File: no-address (missing address field, otherwise same as "aaa") -- File: garbage (file with random data) -- File: empty (file with no content) -- File: swapfile~ (should be skipped) -- File: .hiddenfile (should be skipped) -- File: foo/... (should be skipped because it is a directory) diff --git a/accounts/keystore/testdata/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 b/accounts/keystore/testdata/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 deleted file mode 100644 index c57060aea0..0000000000 --- a/accounts/keystore/testdata/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8 +++ /dev/null @@ -1 +0,0 @@ -{"address":"7ef5a6135f1fd6a02593eedc869c6d41d934aef8","crypto":{"cipher":"aes-128-ctr","ciphertext":"1d0839166e7a15b9c1333fc865d69858b22df26815ccf601b28219b6192974e1","cipherparams":{"iv":"8df6caa7ff1b00c4e871f002cb7921ed"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"e5e6ef3f4ea695f496b643ebd3f75c0aa58ef4070e90c80c5d3fb0241bf1595c"},"mac":"6d16dfde774845e4585357f24bce530528bc69f4f84e1e22880d34fa45c273e5"},"id":"950077c7-71e3-4c44-a4a1-143919141ed4","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/keystore/aaa b/accounts/keystore/testdata/keystore/aaa deleted file mode 100644 index a3868ec6d5..0000000000 --- a/accounts/keystore/testdata/keystore/aaa +++ /dev/null @@ -1 +0,0 @@ -{"address":"f466859ead1932d743d622cb74fc058882e8648a","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/keystore/empty b/accounts/keystore/testdata/keystore/empty deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accounts/keystore/testdata/keystore/foo/fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e b/accounts/keystore/testdata/keystore/foo/fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e deleted file mode 100644 index 309841e524..0000000000 --- a/accounts/keystore/testdata/keystore/foo/fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e +++ /dev/null @@ -1 +0,0 @@ -{"address":"fd9bd350f08ee3c0c19b85a8e16114a11a60aa4e","crypto":{"cipher":"aes-128-ctr","ciphertext":"8124d5134aa4a927c79fd852989e4b5419397566f04b0936a1eb1d168c7c68a5","cipherparams":{"iv":"e2febe17176414dd2cda28287947eb2f"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":4096,"p":6,"r":8,"salt":"44b415ede89f3bdd6830390a21b78965f571b347a589d1d943029f016c5e8bd5"},"mac":"5e149ff25bfd9dd45746a84bb2bcd2f015f2cbca2b6d25c5de8c29617f71fe5b"},"id":"d6ac5452-2b2c-4d3c-ad80-4bf0327d971c","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/keystore/garbage b/accounts/keystore/testdata/keystore/garbage deleted file mode 100644 index ff45091e71..0000000000 Binary files a/accounts/keystore/testdata/keystore/garbage and /dev/null differ diff --git a/accounts/keystore/testdata/keystore/no-address b/accounts/keystore/testdata/keystore/no-address deleted file mode 100644 index ad51269ead..0000000000 --- a/accounts/keystore/testdata/keystore/no-address +++ /dev/null @@ -1 +0,0 @@ -{"crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/keystore/zero b/accounts/keystore/testdata/keystore/zero deleted file mode 100644 index b52617f8ae..0000000000 --- a/accounts/keystore/testdata/keystore/zero +++ /dev/null @@ -1 +0,0 @@ -{"address":"0000000000000000000000000000000000000000","crypto":{"cipher":"aes-128-ctr","ciphertext":"cb664472deacb41a2e995fa7f96fe29ce744471deb8d146a0e43c7898c9ddd4d","cipherparams":{"iv":"dfd9ee70812add5f4b8f89d0811c9158"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"0d6769bf016d45c479213990d6a08d938469c4adad8a02ce507b4a4e7b7739f1"},"mac":"bac9af994b15a45dd39669fc66f9aa8a3b9dd8c22cb16e4d8d7ea089d0f1a1a9"},"id":"472e8b3d-afb6-45b5-8111-72c89895099a","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/keystore/zzz b/accounts/keystore/testdata/keystore/zzz deleted file mode 100644 index cfd8a47017..0000000000 --- a/accounts/keystore/testdata/keystore/zzz +++ /dev/null @@ -1 +0,0 @@ -{"address":"289d485d9771714cce91d3393d764e1311907acc","crypto":{"cipher":"aes-128-ctr","ciphertext":"faf32ca89d286b107f5e6d842802e05263c49b78d46eac74e6109e9a963378ab","cipherparams":{"iv":"558833eec4a665a8c55608d7d503407d"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":8,"p":16,"r":8,"salt":"d571fff447ffb24314f9513f5160246f09997b857ac71348b73e785aab40dc04"},"mac":"21edb85ff7d0dab1767b9bf498f2c3cb7be7609490756bd32300bb213b59effe"},"id":"3279afcf-55ba-43ff-8997-02dcc46a6525","version":3} \ No newline at end of file diff --git a/accounts/keystore/testdata/v1/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e b/accounts/keystore/testdata/v1/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e deleted file mode 100644 index 498d8131e8..0000000000 --- a/accounts/keystore/testdata/v1/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e/cb61d5a9c4896fb9658090b597ef0e7be6f7b67e +++ /dev/null @@ -1 +0,0 @@ -{"address":"cb61d5a9c4896fb9658090b597ef0e7be6f7b67e","Crypto":{"cipher":"aes-128-cbc","ciphertext":"6143d3192db8b66eabd693d9c4e414dcfaee52abda451af79ccf474dafb35f1bfc7ea013aa9d2ee35969a1a2e8d752d0","cipherparams":{"iv":"35337770fc2117994ecdcad026bccff4"},"kdf":"scrypt","kdfparams":{"n":262144,"r":8,"p":1,"dklen":32,"salt":"9afcddebca541253a2f4053391c673ff9fe23097cd8555d149d929e4ccf1257f"},"mac":"3f3d5af884b17a100b0b3232c0636c230a54dc2ac8d986227219b0dd89197644","version":"1"},"id":"e25f7c1f-d318-4f29-b62c-687190d4d299","version":"1"} \ No newline at end of file diff --git a/accounts/keystore/testdata/v1_test_vector.json b/accounts/keystore/testdata/v1_test_vector.json deleted file mode 100644 index 3d09b55b5e..0000000000 --- a/accounts/keystore/testdata/v1_test_vector.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "test1": { - "json": { - "Crypto": { - "cipher": "aes-128-cbc", - "cipherparams": { - "iv": "35337770fc2117994ecdcad026bccff4" - }, - "ciphertext": "6143d3192db8b66eabd693d9c4e414dcfaee52abda451af79ccf474dafb35f1bfc7ea013aa9d2ee35969a1a2e8d752d0", - "kdf": "scrypt", - "kdfparams": { - "dklen": 32, - "n": 262144, - "p": 1, - "r": 8, - "salt": "9afcddebca541253a2f4053391c673ff9fe23097cd8555d149d929e4ccf1257f" - }, - "mac": "3f3d5af884b17a100b0b3232c0636c230a54dc2ac8d986227219b0dd89197644", - "version": "1" - }, - "address": "cb61d5a9c4896fb9658090b597ef0e7be6f7b67e", - "id": "e25f7c1f-d318-4f29-b62c-687190d4d299", - "version": "1" - }, - "password": "g", - "priv": "d1b1178d3529626a1a93e073f65028370d14c7eb0936eb42abef05db6f37ad7d" - } -} diff --git a/accounts/keystore/testdata/v3_test_vector.json b/accounts/keystore/testdata/v3_test_vector.json deleted file mode 100644 index 1e7f790c05..0000000000 --- a/accounts/keystore/testdata/v3_test_vector.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "wikipage_test_vector_scrypt": { - "json": { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - }, - "password": "testpassword", - "priv": "7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d" - }, - "wikipage_test_vector_pbkdf2": { - "json": { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "6087dab2f9fdbbfaddc31a909735c1e6" - }, - "ciphertext" : "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46", - "kdf" : "pbkdf2", - "kdfparams" : { - "c" : 262144, - "dklen" : 32, - "prf" : "hmac-sha256", - "salt" : "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd" - }, - "mac" : "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - }, - "password": "testpassword", - "priv": "7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d" - }, - "31_byte_key": { - "json": { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "e0c41130a323adc1446fc82f724bca2f" - }, - "ciphertext" : "9517cd5bdbe69076f9bf5057248c6c050141e970efa36ce53692d5d59a3984", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 2, - "r" : 8, - "p" : 1, - "salt" : "711f816911c92d649fb4c84b047915679933555030b3552c1212609b38208c63" - }, - "mac" : "d5e116151c6aa71470e67a7d42c9620c75c4d23229847dcc127794f0732b0db5" - }, - "id" : "fecfc4ce-e956-48fd-953b-30f8b52ed66c", - "version" : 3 - }, - "password": "foo", - "priv": "fa7b3db73dc7dfdf8c5fbdb796d741e4488628c41fc4febd9160a866ba0f35" - }, - "30_byte_key": { - "json": { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "3ca92af36ad7c2cd92454c59cea5ef00" - }, - "ciphertext" : "108b7d34f3442fc26ab1ab90ca91476ba6bfa8c00975a49ef9051dc675aa", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 2, - "r" : 8, - "p" : 1, - "salt" : "d0769e608fb86cda848065642a9c6fa046845c928175662b8e356c77f914cd3b" - }, - "mac" : "75d0e6759f7b3cefa319c3be41680ab6beea7d8328653474bd06706d4cc67420" - }, - "id" : "a37e1559-5955-450d-8075-7b8931b392b2", - "version" : 3 - }, - "password": "foo", - "priv": "81c29e8142bb6a81bef5a92bda7a8328a5c85bb2f9542e76f9b0f94fc018" - } -} diff --git a/accounts/keystore/testdata/very-light-scrypt.json b/accounts/keystore/testdata/very-light-scrypt.json deleted file mode 100644 index d23b9b2b91..0000000000 --- a/accounts/keystore/testdata/very-light-scrypt.json +++ /dev/null @@ -1 +0,0 @@ -{"address":"45dea0fb0bba44f4fcf290bba71fd57d7117cbb8","crypto":{"cipher":"aes-128-ctr","ciphertext":"b87781948a1befd247bff51ef4063f716cf6c2d3481163e9a8f42e1f9bb74145","cipherparams":{"iv":"dc4926b48a105133d2f16b96833abf1e"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":2,"p":1,"r":8,"salt":"004244bbdc51cadda545b1cfa43cff9ed2ae88e08c61f1479dbb45410722f8f0"},"mac":"39990c1684557447940d4c69e06b1b82b2aceacb43f284df65c956daf3046b85"},"id":"ce541d8d-c79b-40f8-9f8c-20f59616faba","version":3} diff --git a/accounts/keystore/wallet.go b/accounts/keystore/wallet.go deleted file mode 100644 index 7193526399..0000000000 --- a/accounts/keystore/wallet.go +++ /dev/null @@ -1,160 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package keystore - -import ( - "math/big" - - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/crypto" -) - -// keystoreWallet implements the accounts.Wallet interface for the original -// keystore. -type keystoreWallet struct { - account accounts.Account // Single account contained in this wallet - keystore *KeyStore // Keystore where the account originates from -} - -// URL implements accounts.Wallet, returning the URL of the account within. -func (w *keystoreWallet) URL() accounts.URL { - return w.account.URL -} - -// Status implements accounts.Wallet, returning whether the account held by the -// keystore wallet is unlocked or not. -func (w *keystoreWallet) Status() (string, error) { - w.keystore.mu.RLock() - defer w.keystore.mu.RUnlock() - - if _, ok := w.keystore.unlocked[w.account.Address]; ok { - return "Unlocked", nil - } - return "Locked", nil -} - -// Open implements accounts.Wallet, but is a noop for plain wallets since there -// is no connection or decryption step necessary to access the list of accounts. -func (w *keystoreWallet) Open(passphrase string) error { return nil } - -// Close implements accounts.Wallet, but is a noop for plain wallets since there -// is no meaningful open operation. -func (w *keystoreWallet) Close() error { return nil } - -// Accounts implements accounts.Wallet, returning an account list consisting of -// a single account that the plain keystore wallet contains. -func (w *keystoreWallet) Accounts() []accounts.Account { - return []accounts.Account{w.account} -} - -// Contains implements accounts.Wallet, returning whether a particular account is -// or is not wrapped by this wallet instance. -func (w *keystoreWallet) Contains(account accounts.Account) bool { - return account.Address == w.account.Address && (account.URL == (accounts.URL{}) || account.URL == w.account.URL) -} - -// Derive implements accounts.Wallet, but is a noop for plain wallets since there -// is no notion of hierarchical account derivation for plain keystore accounts. -func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { - return accounts.Account{}, accounts.ErrNotSupported -} - -// SelfDerive implements accounts.Wallet, but is a noop for plain wallets since -// there is no notion of hierarchical account derivation for plain keystore accounts. -func (w *keystoreWallet) SelfDerive(bases []accounts.DerivationPath, chain interfaces.ChainStateReader) { -} - -// signHash attempts to sign the given hash with -// the given account. If the wallet does not wrap this particular account, an -// error is returned to avoid account leakage (even though in theory we may be -// able to sign via our shared keystore backend). -func (w *keystoreWallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { - // Make sure the requested account is contained within - if !w.Contains(account) { - return nil, accounts.ErrUnknownAccount - } - // Account seems valid, request the keystore to sign - return w.keystore.SignHash(account, hash) -} - -// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed. -func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { - return w.signHash(account, crypto.Keccak256(data)) -} - -// SignDataWithPassphrase signs keccak256(data). The mimetype parameter describes the type of data being signed. -func (w *keystoreWallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { - // Make sure the requested account is contained within - if !w.Contains(account) { - return nil, accounts.ErrUnknownAccount - } - // Account seems valid, request the keystore to sign - return w.keystore.SignHashWithPassphrase(account, passphrase, crypto.Keccak256(data)) -} - -// SignText implements accounts.Wallet, attempting to sign the hash of -// the given text with the given account. -func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) { - return w.signHash(account, accounts.TextHash(text)) -} - -// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the -// hash of the given text with the given account using passphrase as extra authentication. -func (w *keystoreWallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { - // Make sure the requested account is contained within - if !w.Contains(account) { - return nil, accounts.ErrUnknownAccount - } - // Account seems valid, request the keystore to sign - return w.keystore.SignHashWithPassphrase(account, passphrase, accounts.TextHash(text)) -} - -// SignTx implements accounts.Wallet, attempting to sign the given transaction -// with the given account. If the wallet does not wrap this particular account, -// an error is returned to avoid account leakage (even though in theory we may -// be able to sign via our shared keystore backend). -func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - // Make sure the requested account is contained within - if !w.Contains(account) { - return nil, accounts.ErrUnknownAccount - } - // Account seems valid, request the keystore to sign - return w.keystore.SignTx(account, tx, chainID) -} - -// SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given -// transaction with the given account using passphrase as extra authentication. -func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - // Make sure the requested account is contained within - if !w.Contains(account) { - return nil, accounts.ErrUnknownAccount - } - // Account seems valid, request the keystore to sign - return w.keystore.SignTxWithPassphrase(account, passphrase, tx, chainID) -} diff --git a/accounts/keystore/watch.go b/accounts/keystore/watch.go deleted file mode 100644 index 156424c97b..0000000000 --- a/accounts/keystore/watch.go +++ /dev/null @@ -1,144 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build (darwin && !ios && cgo) || freebsd || (linux && !arm64) || netbsd || solaris -// +build darwin,!ios,cgo freebsd linux,!arm64 netbsd solaris - -package keystore - -import ( - "os" - "time" - - "github.com/ethereum/go-ethereum/log" - "github.com/fsnotify/fsnotify" -) - -type watcher struct { - ac *accountCache - running bool // set to true when runloop begins - runEnded bool // set to true when runloop ends - starting bool // set to true prior to runloop starting - quit chan struct{} -} - -func newWatcher(ac *accountCache) *watcher { - return &watcher{ - ac: ac, - quit: make(chan struct{}), - } -} - -// enabled returns false on systems not supported. -func (*watcher) enabled() bool { return true } - -// starts the watcher loop in the background. -// Start a watcher in the background if that's not already in progress. -// The caller must hold w.ac.mu. -func (w *watcher) start() { - if w.starting || w.running { - return - } - w.starting = true - go w.loop() -} - -func (w *watcher) close() { - close(w.quit) -} - -func (w *watcher) loop() { - defer func() { - w.ac.mu.Lock() - w.running = false - w.starting = false - w.runEnded = true - w.ac.mu.Unlock() - }() - logger := log.New("path", w.ac.keydir) - - // Create new watcher. - watcher, err := fsnotify.NewWatcher() - if err != nil { - log.Error("Failed to start filesystem watcher", "err", err) - return - } - defer watcher.Close() - if err := watcher.Add(w.ac.keydir); err != nil { - if !os.IsNotExist(err) { - logger.Warn("Failed to watch keystore folder", "err", err) - } - return - } - - logger.Trace("Started watching keystore folder", "folder", w.ac.keydir) - defer logger.Trace("Stopped watching keystore folder") - - w.ac.mu.Lock() - w.running = true - w.ac.mu.Unlock() - - // Wait for file system events and reload. - // When an event occurs, the reload call is delayed a bit so that - // multiple events arriving quickly only cause a single reload. - var ( - debounceDuration = 500 * time.Millisecond - rescanTriggered = false - debounce = time.NewTimer(0) - ) - // Ignore initial trigger - if !debounce.Stop() { - <-debounce.C - } - defer debounce.Stop() - for { - select { - case <-w.quit: - return - case _, ok := <-watcher.Events: - if !ok { - return - } - // Trigger the scan (with delay), if not already triggered - if !rescanTriggered { - debounce.Reset(debounceDuration) - rescanTriggered = true - } - // The fsnotify library does provide more granular event-info, it - // would be possible to refresh individual affected files instead - // of scheduling a full rescan. For most cases though, the - // full rescan is quick and obviously simplest. - case err, ok := <-watcher.Errors: - if !ok { - return - } - log.Info("Filesystem watcher error", "err", err) - case <-debounce.C: - w.ac.scanAccounts() - rescanTriggered = false - } - } -} diff --git a/accounts/keystore/watch_fallback.go b/accounts/keystore/watch_fallback.go deleted file mode 100644 index 520ff41993..0000000000 --- a/accounts/keystore/watch_fallback.go +++ /dev/null @@ -1,45 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -//go:build (darwin && !cgo) || ios || (linux && arm64) || windows || (!darwin && !freebsd && !linux && !netbsd && !solaris) -// +build darwin,!cgo ios linux,arm64 windows !darwin,!freebsd,!linux,!netbsd,!solaris - -// This is the fallback implementation of directory watching. -// It is used on unsupported platforms. - -package keystore - -type watcher struct { - running bool - runEnded bool -} - -func newWatcher(*accountCache) *watcher { return new(watcher) } -func (*watcher) start() {} -func (*watcher) close() {} - -// enabled returns false on systems not supported. -func (*watcher) enabled() bool { return false } diff --git a/accounts/manager.go b/accounts/manager.go deleted file mode 100644 index c2220ce71e..0000000000 --- a/accounts/manager.go +++ /dev/null @@ -1,285 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -import ( - "reflect" - "sort" - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" -) - -// managerSubBufferSize determines how many incoming wallet events -// the manager will buffer in its channel. -const managerSubBufferSize = 50 - -// Config contains the settings of the global account manager. -// -// TODO(rjl493456442, karalabe, holiman): Get rid of this when account management -// is removed in favor of Clef. -type Config struct { - InsecureUnlockAllowed bool // Whether account unlocking in insecure environment is allowed -} - -// newBackendEvent lets the manager know it should -// track the given backend for wallet updates. -type newBackendEvent struct { - backend Backend - processed chan struct{} // Informs event emitter that backend has been integrated -} - -// Manager is an overarching account manager that can communicate with various -// backends for signing transactions. -type Manager struct { - config *Config // Global account manager configurations - backends map[reflect.Type][]Backend // Index of backends currently registered - updaters []event.Subscription // Wallet update subscriptions for all backends - updates chan WalletEvent // Subscription sink for backend wallet changes - newBackends chan newBackendEvent // Incoming backends to be tracked by the manager - wallets []Wallet // Cache of all wallets from all registered backends - - feed event.Feed // Wallet feed notifying of arrivals/departures - - quit chan chan error - term chan struct{} // Channel is closed upon termination of the update loop - lock sync.RWMutex -} - -// NewManager creates a generic account manager to sign transaction via various -// supported backends. -func NewManager(config *Config, backends ...Backend) *Manager { - // Retrieve the initial list of wallets from the backends and sort by URL - var wallets []Wallet - for _, backend := range backends { - wallets = merge(wallets, backend.Wallets()...) - } - // Subscribe to wallet notifications from all backends - updates := make(chan WalletEvent, managerSubBufferSize) - - subs := make([]event.Subscription, len(backends)) - for i, backend := range backends { - subs[i] = backend.Subscribe(updates) - } - // Assemble the account manager and return - am := &Manager{ - config: config, - backends: make(map[reflect.Type][]Backend), - updaters: subs, - updates: updates, - newBackends: make(chan newBackendEvent), - wallets: wallets, - quit: make(chan chan error), - term: make(chan struct{}), - } - for _, backend := range backends { - kind := reflect.TypeOf(backend) - am.backends[kind] = append(am.backends[kind], backend) - } - go am.update() - - return am -} - -// Close terminates the account manager's internal notification processes. -func (am *Manager) Close() error { - for _, w := range am.wallets { - w.Close() - } - errc := make(chan error) - am.quit <- errc - return <-errc -} - -// Config returns the configuration of account manager. -func (am *Manager) Config() *Config { - return am.config -} - -// AddBackend starts the tracking of an additional backend for wallet updates. -// cmd/geth assumes once this func returns the backends have been already integrated. -func (am *Manager) AddBackend(backend Backend) { - done := make(chan struct{}) - am.newBackends <- newBackendEvent{backend, done} - <-done -} - -// update is the wallet event loop listening for notifications from the backends -// and updating the cache of wallets. -func (am *Manager) update() { - // Close all subscriptions when the manager terminates - defer func() { - am.lock.Lock() - for _, sub := range am.updaters { - sub.Unsubscribe() - } - am.updaters = nil - am.lock.Unlock() - }() - - // Loop until termination - for { - select { - case event := <-am.updates: - // Wallet event arrived, update local cache - am.lock.Lock() - switch event.Kind { - case WalletArrived: - am.wallets = merge(am.wallets, event.Wallet) - case WalletDropped: - am.wallets = drop(am.wallets, event.Wallet) - } - am.lock.Unlock() - - // Notify any listeners of the event - am.feed.Send(event) - case event := <-am.newBackends: - am.lock.Lock() - // Update caches - backend := event.backend - am.wallets = merge(am.wallets, backend.Wallets()...) - am.updaters = append(am.updaters, backend.Subscribe(am.updates)) - kind := reflect.TypeOf(backend) - am.backends[kind] = append(am.backends[kind], backend) - am.lock.Unlock() - close(event.processed) - case errc := <-am.quit: - // Manager terminating, return - errc <- nil - // Signals event emitters the loop is not receiving values - // to prevent them from getting stuck. - close(am.term) - return - } - } -} - -// Backends retrieves the backend(s) with the given type from the account manager. -func (am *Manager) Backends(kind reflect.Type) []Backend { - am.lock.RLock() - defer am.lock.RUnlock() - - return am.backends[kind] -} - -// Wallets returns all signer accounts registered under this account manager. -func (am *Manager) Wallets() []Wallet { - am.lock.RLock() - defer am.lock.RUnlock() - - return am.walletsNoLock() -} - -// walletsNoLock returns all registered wallets. Callers must hold am.lock. -func (am *Manager) walletsNoLock() []Wallet { - cpy := make([]Wallet, len(am.wallets)) - copy(cpy, am.wallets) - return cpy -} - -// Wallet retrieves the wallet associated with a particular URL. -func (am *Manager) Wallet(url string) (Wallet, error) { - am.lock.RLock() - defer am.lock.RUnlock() - - parsed, err := parseURL(url) - if err != nil { - return nil, err - } - for _, wallet := range am.walletsNoLock() { - if wallet.URL() == parsed { - return wallet, nil - } - } - return nil, ErrUnknownWallet -} - -// Accounts returns all account addresses of all wallets within the account manager -func (am *Manager) Accounts() []common.Address { - am.lock.RLock() - defer am.lock.RUnlock() - - addresses := make([]common.Address, 0) // return [] instead of nil if empty - for _, wallet := range am.wallets { - for _, account := range wallet.Accounts() { - addresses = append(addresses, account.Address) - } - } - return addresses -} - -// Find attempts to locate the wallet corresponding to a specific account. Since -// accounts can be dynamically added to and removed from wallets, this method has -// a linear runtime in the number of wallets. -func (am *Manager) Find(account Account) (Wallet, error) { - am.lock.RLock() - defer am.lock.RUnlock() - - for _, wallet := range am.wallets { - if wallet.Contains(account) { - return wallet, nil - } - } - return nil, ErrUnknownAccount -} - -// Subscribe creates an async subscription to receive notifications when the -// manager detects the arrival or departure of a wallet from any of its backends. -func (am *Manager) Subscribe(sink chan<- WalletEvent) event.Subscription { - return am.feed.Subscribe(sink) -} - -// merge is a sorted analogue of append for wallets, where the ordering of the -// origin list is preserved by inserting new wallets at the correct position. -// -// The original slice is assumed to be already sorted by URL. -func merge(slice []Wallet, wallets ...Wallet) []Wallet { - for _, wallet := range wallets { - n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) - if n == len(slice) { - slice = append(slice, wallet) - continue - } - slice = append(slice[:n], append([]Wallet{wallet}, slice[n:]...)...) - } - return slice -} - -// drop is the counterpart of merge, which looks up wallets from within the sorted -// cache and removes the ones specified. -func drop(slice []Wallet, wallets ...Wallet) []Wallet { - for _, wallet := range wallets { - n := sort.Search(len(slice), func(i int) bool { return slice[i].URL().Cmp(wallet.URL()) >= 0 }) - if n == len(slice) { - // Wallet not found, may happen during startup - continue - } - slice = append(slice[:n], slice[n+1:]...) - } - return slice -} diff --git a/accounts/scwallet/README.md b/accounts/scwallet/README.md deleted file mode 100644 index 28079c4743..0000000000 --- a/accounts/scwallet/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# Using the smartcard wallet - -## Requirements - - * A USB smartcard reader - * A keycard that supports the status app - * PCSCD version 4.3 running on your system **Only version 4.3 is currently supported** - -## Preparing the smartcard - - **WARNING: FOLLOWING THESE INSTRUCTIONS WILL DESTROY THE MASTER KEY ON YOUR CARD. ONLY PROCEED IF NO FUNDS ARE ASSOCIATED WITH THESE ACCOUNTS** - - You can use status' [keycard-cli](https://github.com/status-im/keycard-cli) and you should get _at least_ version 2.1.1 of their [smartcard application](https://github.com/status-im/status-keycard/releases/download/2.2.1/keycard_v2.2.1.cap) - - You also need to make sure that the PCSC daemon is running on your system. - - Then, you can install the application to the card by typing: - - ``` - keycard install -a keycard_v2.2.1.cap && keycard init - ``` - - At the end of this process, you will be provided with a PIN, a PUK and a pairing password. Write them down, you'll need them shortly. - - Start `geth` with the `console` command. You will notice the following warning: - - ``` - WARN [04-09|16:58:38.898] Failed to open wallet url=keycard://044def09 err="smartcard: pairing password needed" - ``` - - Write down the URL (`keycard://044def09` in this example). Then ask `geth` to open the wallet: - - ``` - > personal.openWallet("keycard://044def09", "pairing password") - ``` - - The pairing password has been generated during the card initialization process. - - The process needs to be repeated once more with the PIN: - - ``` - > personal.openWallet("keycard://044def09", "PIN number") - ``` - - If everything goes well, you should see your new account when typing `personal` on the console: - - ``` - > personal - WARN [04-09|17:02:07.330] Smartcard wallet account derivation failed url=keycard://044def09 err="Unexpected response status Cla=0x80, Ins=0xd1, Sw=0x6985" - { - listAccounts: [], - listWallets: [{ - status: "Empty, waiting for initialization", - url: "keycard://044def09" - }], - ... - } - ``` - - So the communication with the card is working, but there is no key associated with this wallet. Let's create it: - - ``` - > personal.initializeWallet("keycard://044def09") - "tilt ... impact" - ``` - - You should get a list of words, this is your seed so write them down. Your wallet should now be initialized: - - ``` - > personal.listWallets - [{ - accounts: [{ - address: "0x678b7cd55c61917defb23546a41803c5bfefbc7a", - url: "keycard://044d/m/44'/60'/0'/0/0" - }], - status: "Online", - url: "keycard://044def09" - }] - ``` - - You're all set! - -## Usage - - 1. Start `geth` with the `console` command - 2. Check the card's URL by checking `personal.listWallets`: - -``` - listWallets: [{ - status: "Online, can derive public keys", - url: "keycard://a4d73015" - }] -``` - - 3. Open the wallet, you will be prompted for your pairing password, then PIN: - -``` -personal.openWallet("keycard://a4d73015") -``` - - 4. Check that creation was successful by typing e.g. `personal`. Then use it like a regular wallet. - -## Known issues - - * Starting geth with a valid card seems to make firefox crash. - * PCSC version 4.4 should work, but is currently untested diff --git a/accounts/scwallet/apdu.go b/accounts/scwallet/apdu.go deleted file mode 100644 index 3120ef6859..0000000000 --- a/accounts/scwallet/apdu.go +++ /dev/null @@ -1,97 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package scwallet - -import ( - "bytes" - "encoding/binary" - "fmt" -) - -// commandAPDU represents an application data unit sent to a smartcard. -type commandAPDU struct { - Cla, Ins, P1, P2 uint8 // Class, Instruction, Parameter 1, Parameter 2 - Data []byte // Command data - Le uint8 // Command data length -} - -// serialize serializes a command APDU. -func (ca commandAPDU) serialize() ([]byte, error) { - buf := new(bytes.Buffer) - - if err := binary.Write(buf, binary.BigEndian, ca.Cla); err != nil { - return nil, err - } - if err := binary.Write(buf, binary.BigEndian, ca.Ins); err != nil { - return nil, err - } - if err := binary.Write(buf, binary.BigEndian, ca.P1); err != nil { - return nil, err - } - if err := binary.Write(buf, binary.BigEndian, ca.P2); err != nil { - return nil, err - } - if len(ca.Data) > 0 { - if err := binary.Write(buf, binary.BigEndian, uint8(len(ca.Data))); err != nil { - return nil, err - } - if err := binary.Write(buf, binary.BigEndian, ca.Data); err != nil { - return nil, err - } - } - if err := binary.Write(buf, binary.BigEndian, ca.Le); err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -// responseAPDU represents an application data unit received from a smart card. -type responseAPDU struct { - Data []byte // response data - Sw1, Sw2 uint8 // status words 1 and 2 -} - -// deserialize deserializes a response APDU. -func (ra *responseAPDU) deserialize(data []byte) error { - if len(data) < 2 { - return fmt.Errorf("can not deserialize data: payload too short (%d < 2)", len(data)) - } - - ra.Data = make([]byte, len(data)-2) - - buf := bytes.NewReader(data) - if err := binary.Read(buf, binary.BigEndian, &ra.Data); err != nil { - return err - } - if err := binary.Read(buf, binary.BigEndian, &ra.Sw1); err != nil { - return err - } - if err := binary.Read(buf, binary.BigEndian, &ra.Sw2); err != nil { - return err - } - return nil -} diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go deleted file mode 100644 index 89fb564140..0000000000 --- a/accounts/scwallet/hub.go +++ /dev/null @@ -1,312 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// This package implements support for smartcard-based hardware wallets such as -// the one written by Status: https://github.com/status-im/hardware-wallet -// -// This implementation of smartcard wallets have a different interaction process -// to other types of hardware wallet. The process works like this: -// -// 1. (First use with a given client) Establish a pairing between hardware -// wallet and client. This requires a secret value called a 'pairing password'. -// You can pair with an unpaired wallet with `personal.openWallet(URI, pairing password)`. -// 2. (First use only) Initialize the wallet, which generates a keypair, stores -// it on the wallet, and returns it so the user can back it up. You can -// initialize a wallet with `personal.initializeWallet(URI)`. -// 3. Connect to the wallet using the pairing information established in step 1. -// You can connect to a paired wallet with `personal.openWallet(URI, PIN)`. -// 4. Interact with the wallet as normal. - -package scwallet - -import ( - "encoding/json" - "io" - "os" - "path/filepath" - "sort" - "sync" - "time" - - "github.com/ava-labs/coreth/accounts" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - pcsc "github.com/gballet/go-libpcsclite" -) - -// Scheme is the URI prefix for smartcard wallets. -const Scheme = "keycard" - -// refreshCycle is the maximum time between wallet refreshes (if USB hotplug -// notifications don't work). -const refreshCycle = time.Second - -// refreshThrottling is the minimum time between wallet refreshes to avoid thrashing. -const refreshThrottling = 500 * time.Millisecond - -// smartcardPairing contains information about a smart card we have paired with -// or might pair with the hub. -type smartcardPairing struct { - PublicKey []byte `json:"publicKey"` - PairingIndex uint8 `json:"pairingIndex"` - PairingKey []byte `json:"pairingKey"` - Accounts map[common.Address]accounts.DerivationPath `json:"accounts"` -} - -// Hub is a accounts.Backend that can find and handle generic PC/SC hardware wallets. -type Hub struct { - scheme string // Protocol scheme prefixing account and wallet URLs. - - context *pcsc.Client - datadir string - pairings map[string]smartcardPairing - - refreshed time.Time // Time instance when the list of wallets was last refreshed - wallets map[string]*Wallet // Mapping from reader names to wallet instances - updateFeed event.Feed // Event feed to notify wallet additions/removals - updateScope event.SubscriptionScope // Subscription scope tracking current live listeners - updating bool // Whether the event notification loop is running - - quit chan chan error - - stateLock sync.RWMutex // Protects the internals of the hub from racey access -} - -func (hub *Hub) readPairings() error { - hub.pairings = make(map[string]smartcardPairing) - pairingFile, err := os.Open(filepath.Join(hub.datadir, "smartcards.json")) - if err != nil { - if os.IsNotExist(err) { - return nil - } - return err - } - - pairingData, err := io.ReadAll(pairingFile) - if err != nil { - return err - } - var pairings []smartcardPairing - if err := json.Unmarshal(pairingData, &pairings); err != nil { - return err - } - - for _, pairing := range pairings { - hub.pairings[string(pairing.PublicKey)] = pairing - } - return nil -} - -func (hub *Hub) writePairings() error { - pairingFile, err := os.OpenFile(filepath.Join(hub.datadir, "smartcards.json"), os.O_RDWR|os.O_CREATE, 0755) - if err != nil { - return err - } - defer pairingFile.Close() - - pairings := make([]smartcardPairing, 0, len(hub.pairings)) - for _, pairing := range hub.pairings { - pairings = append(pairings, pairing) - } - - pairingData, err := json.Marshal(pairings) - if err != nil { - return err - } - - if _, err := pairingFile.Write(pairingData); err != nil { - return err - } - - return nil -} - -func (hub *Hub) pairing(wallet *Wallet) *smartcardPairing { - if pairing, ok := hub.pairings[string(wallet.PublicKey)]; ok { - return &pairing - } - return nil -} - -func (hub *Hub) setPairing(wallet *Wallet, pairing *smartcardPairing) error { - if pairing == nil { - delete(hub.pairings, string(wallet.PublicKey)) - } else { - hub.pairings[string(wallet.PublicKey)] = *pairing - } - return hub.writePairings() -} - -// NewHub creates a new hardware wallet manager for smartcards. -func NewHub(daemonPath string, scheme string, datadir string) (*Hub, error) { - context, err := pcsc.EstablishContext(daemonPath, pcsc.ScopeSystem) - if err != nil { - return nil, err - } - hub := &Hub{ - scheme: scheme, - context: context, - datadir: datadir, - wallets: make(map[string]*Wallet), - quit: make(chan chan error), - } - if err := hub.readPairings(); err != nil { - return nil, err - } - hub.refreshWallets() - return hub, nil -} - -// Wallets implements accounts.Backend, returning all the currently tracked smart -// cards that appear to be hardware wallets. -func (hub *Hub) Wallets() []accounts.Wallet { - // Make sure the list of wallets is up to date - hub.refreshWallets() - - hub.stateLock.RLock() - defer hub.stateLock.RUnlock() - - cpy := make([]accounts.Wallet, 0, len(hub.wallets)) - for _, wallet := range hub.wallets { - cpy = append(cpy, wallet) - } - sort.Sort(accounts.WalletsByURL(cpy)) - return cpy -} - -// refreshWallets scans the devices attached to the machine and updates the -// list of wallets based on the found devices. -func (hub *Hub) refreshWallets() { - // Don't scan the USB like crazy it the user fetches wallets in a loop - hub.stateLock.RLock() - elapsed := time.Since(hub.refreshed) - hub.stateLock.RUnlock() - - if elapsed < refreshThrottling { - return - } - // Retrieve all the smart card reader to check for cards - readers, err := hub.context.ListReaders() - if err != nil { - // This is a perverted hack, the scard library returns an error if no card - // readers are present instead of simply returning an empty list. We don't - // want to fill the user's log with errors, so filter those out. - if err.Error() != "scard: Cannot find a smart card reader." { - log.Error("Failed to enumerate smart card readers", "err", err) - return - } - } - // Transform the current list of wallets into the new one - hub.stateLock.Lock() - - events := []accounts.WalletEvent{} - seen := make(map[string]struct{}) - - for _, reader := range readers { - // Mark the reader as present - seen[reader] = struct{}{} - - // If we already know about this card, skip to the next reader, otherwise clean up - if wallet, ok := hub.wallets[reader]; ok { - if err := wallet.ping(); err == nil { - continue - } - wallet.Close() - events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) - delete(hub.wallets, reader) - } - // New card detected, try to connect to it - card, err := hub.context.Connect(reader, pcsc.ShareShared, pcsc.ProtocolAny) - if err != nil { - log.Debug("Failed to open smart card", "reader", reader, "err", err) - continue - } - wallet := NewWallet(hub, card) - if err = wallet.connect(); err != nil { - log.Debug("Failed to connect to smart card", "reader", reader, "err", err) - card.Disconnect(pcsc.LeaveCard) - continue - } - // Card connected, start tracking among the wallets - hub.wallets[reader] = wallet - events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletArrived}) - } - // Remove any wallets no longer present - for reader, wallet := range hub.wallets { - if _, ok := seen[reader]; !ok { - wallet.Close() - events = append(events, accounts.WalletEvent{Wallet: wallet, Kind: accounts.WalletDropped}) - delete(hub.wallets, reader) - } - } - hub.refreshed = time.Now() - hub.stateLock.Unlock() - - for _, event := range events { - hub.updateFeed.Send(event) - } -} - -// Subscribe implements accounts.Backend, creating an async subscription to -// receive notifications on the addition or removal of smart card wallets. -func (hub *Hub) Subscribe(sink chan<- accounts.WalletEvent) event.Subscription { - // We need the mutex to reliably start/stop the update loop - hub.stateLock.Lock() - defer hub.stateLock.Unlock() - - // Subscribe the caller and track the subscriber count - sub := hub.updateScope.Track(hub.updateFeed.Subscribe(sink)) - - // Subscribers require an active notification loop, start it - if !hub.updating { - hub.updating = true - go hub.updater() - } - return sub -} - -// updater is responsible for maintaining an up-to-date list of wallets managed -// by the smart card hub, and for firing wallet addition/removal events. -func (hub *Hub) updater() { - for { - // TODO: Wait for a USB hotplug event (not supported yet) or a refresh timeout - // <-hub.changes - time.Sleep(refreshCycle) - - // Run the wallet refresher - hub.refreshWallets() - - // If all our subscribers left, stop the updater - hub.stateLock.Lock() - if hub.updateScope.Count() == 0 { - hub.updating = false - hub.stateLock.Unlock() - return - } - hub.stateLock.Unlock() - } -} diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go deleted file mode 100644 index 062bfcb198..0000000000 --- a/accounts/scwallet/securechannel.go +++ /dev/null @@ -1,350 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package scwallet - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/elliptic" - "crypto/rand" - "crypto/sha256" - "crypto/sha512" - "errors" - "fmt" - - "github.com/ethereum/go-ethereum/crypto" - pcsc "github.com/gballet/go-libpcsclite" - "golang.org/x/crypto/pbkdf2" - "golang.org/x/text/unicode/norm" -) - -const ( - maxPayloadSize = 223 - pairP1FirstStep = 0 - pairP1LastStep = 1 - - scSecretLength = 32 - scBlockSize = 16 - - insOpenSecureChannel = 0x10 - insMutuallyAuthenticate = 0x11 - insPair = 0x12 - insUnpair = 0x13 - - pairingSalt = "Keycard Pairing Password Salt" -) - -// SecureChannelSession enables secure communication with a hardware wallet. -type SecureChannelSession struct { - card *pcsc.Card // A handle to the smartcard for communication - secret []byte // A shared secret generated from our ECDSA keys - publicKey []byte // Our own ephemeral public key - PairingKey []byte // A permanent shared secret for a pairing, if present - sessionEncKey []byte // The current session encryption key - sessionMacKey []byte // The current session MAC key - iv []byte // The current IV - PairingIndex uint8 // The pairing index -} - -// NewSecureChannelSession creates a new secure channel for the given card and public key. -func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSession, error) { - // Generate an ECDSA keypair for ourselves - key, err := crypto.GenerateKey() - if err != nil { - return nil, err - } - cardPublic, err := crypto.UnmarshalPubkey(keyData) - if err != nil { - return nil, fmt.Errorf("could not unmarshal public key from card: %v", err) - } - secret, _ := key.Curve.ScalarMult(cardPublic.X, cardPublic.Y, key.D.Bytes()) - return &SecureChannelSession{ - card: card, - secret: secret.Bytes(), - publicKey: elliptic.Marshal(crypto.S256(), key.PublicKey.X, key.PublicKey.Y), - }, nil -} - -// Pair establishes a new pairing with the smartcard. -func (s *SecureChannelSession) Pair(pairingPassword []byte) error { - secretHash := pbkdf2.Key(norm.NFKD.Bytes(pairingPassword), norm.NFKD.Bytes([]byte(pairingSalt)), 50000, 32, sha256.New) - - challenge := make([]byte, 32) - if _, err := rand.Read(challenge); err != nil { - return err - } - - response, err := s.pair(pairP1FirstStep, challenge) - if err != nil { - return err - } - - md := sha256.New() - md.Write(secretHash[:]) - md.Write(challenge) - - expectedCryptogram := md.Sum(nil) - cardCryptogram := response.Data[:32] - cardChallenge := response.Data[32:64] - - if !bytes.Equal(expectedCryptogram, cardCryptogram) { - return fmt.Errorf("invalid card cryptogram %v != %v", expectedCryptogram, cardCryptogram) - } - - md.Reset() - md.Write(secretHash[:]) - md.Write(cardChallenge) - response, err = s.pair(pairP1LastStep, md.Sum(nil)) - if err != nil { - return err - } - - md.Reset() - md.Write(secretHash[:]) - md.Write(response.Data[1:]) - s.PairingKey = md.Sum(nil) - s.PairingIndex = response.Data[0] - - return nil -} - -// Unpair disestablishes an existing pairing. -func (s *SecureChannelSession) Unpair() error { - if s.PairingKey == nil { - return errors.New("cannot unpair: not paired") - } - - _, err := s.transmitEncrypted(claSCWallet, insUnpair, s.PairingIndex, 0, []byte{}) - if err != nil { - return err - } - s.PairingKey = nil - // Close channel - s.iv = nil - return nil -} - -// Open initializes the secure channel. -func (s *SecureChannelSession) Open() error { - if s.iv != nil { - return errors.New("session already opened") - } - - response, err := s.open() - if err != nil { - return err - } - - // Generate the encryption/mac key by hashing our shared secret, - // pairing key, and the first bytes returned from the Open APDU. - md := sha512.New() - md.Write(s.secret) - md.Write(s.PairingKey) - md.Write(response.Data[:scSecretLength]) - keyData := md.Sum(nil) - s.sessionEncKey = keyData[:scSecretLength] - s.sessionMacKey = keyData[scSecretLength : scSecretLength*2] - - // The IV is the last bytes returned from the Open APDU. - s.iv = response.Data[scSecretLength:] - - return s.mutuallyAuthenticate() -} - -// mutuallyAuthenticate is an internal method to authenticate both ends of the -// connection. -func (s *SecureChannelSession) mutuallyAuthenticate() error { - data := make([]byte, scSecretLength) - if _, err := rand.Read(data); err != nil { - return err - } - - response, err := s.transmitEncrypted(claSCWallet, insMutuallyAuthenticate, 0, 0, data) - if err != nil { - return err - } - if response.Sw1 != 0x90 || response.Sw2 != 0x00 { - return fmt.Errorf("got unexpected response from MUTUALLY_AUTHENTICATE: %#x%x", response.Sw1, response.Sw2) - } - - if len(response.Data) != scSecretLength { - return fmt.Errorf("response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d", len(response.Data), scSecretLength) - } - - return nil -} - -// open is an internal method that sends an open APDU. -func (s *SecureChannelSession) open() (*responseAPDU, error) { - return transmit(s.card, &commandAPDU{ - Cla: claSCWallet, - Ins: insOpenSecureChannel, - P1: s.PairingIndex, - P2: 0, - Data: s.publicKey, - Le: 0, - }) -} - -// pair is an internal method that sends a pair APDU. -func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*responseAPDU, error) { - return transmit(s.card, &commandAPDU{ - Cla: claSCWallet, - Ins: insPair, - P1: p1, - P2: 0, - Data: data, - Le: 0, - }) -} - -// transmitEncrypted sends an encrypted message, and decrypts and returns the response. -func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []byte) (*responseAPDU, error) { - if s.iv == nil { - return nil, errors.New("channel not open") - } - - data, err := s.encryptAPDU(data) - if err != nil { - return nil, err - } - meta := [16]byte{cla, ins, p1, p2, byte(len(data) + scBlockSize)} - if err = s.updateIV(meta[:], data); err != nil { - return nil, err - } - - fulldata := make([]byte, len(s.iv)+len(data)) - copy(fulldata, s.iv) - copy(fulldata[len(s.iv):], data) - - response, err := transmit(s.card, &commandAPDU{ - Cla: cla, - Ins: ins, - P1: p1, - P2: p2, - Data: fulldata, - }) - if err != nil { - return nil, err - } - - rmeta := [16]byte{byte(len(response.Data))} - rmac := response.Data[:len(s.iv)] - rdata := response.Data[len(s.iv):] - plainData, err := s.decryptAPDU(rdata) - if err != nil { - return nil, err - } - - if err = s.updateIV(rmeta[:], rdata); err != nil { - return nil, err - } - if !bytes.Equal(s.iv, rmac) { - return nil, errors.New("invalid MAC in response") - } - - rapdu := &responseAPDU{} - rapdu.deserialize(plainData) - - if rapdu.Sw1 != sw1Ok { - return nil, fmt.Errorf("unexpected response status Cla=%#x, Ins=%#x, Sw=%#x%x", cla, ins, rapdu.Sw1, rapdu.Sw2) - } - - return rapdu, nil -} - -// encryptAPDU is an internal method that serializes and encrypts an APDU. -func (s *SecureChannelSession) encryptAPDU(data []byte) ([]byte, error) { - if len(data) > maxPayloadSize { - return nil, fmt.Errorf("payload of %d bytes exceeds maximum of %d", len(data), maxPayloadSize) - } - data = pad(data, 0x80) - - ret := make([]byte, len(data)) - - a, err := aes.NewCipher(s.sessionEncKey) - if err != nil { - return nil, err - } - crypter := cipher.NewCBCEncrypter(a, s.iv) - crypter.CryptBlocks(ret, data) - return ret, nil -} - -// pad applies message padding to a 16 byte boundary. -func pad(data []byte, terminator byte) []byte { - padded := make([]byte, (len(data)/16+1)*16) - copy(padded, data) - padded[len(data)] = terminator - return padded -} - -// decryptAPDU is an internal method that decrypts and deserializes an APDU. -func (s *SecureChannelSession) decryptAPDU(data []byte) ([]byte, error) { - a, err := aes.NewCipher(s.sessionEncKey) - if err != nil { - return nil, err - } - - ret := make([]byte, len(data)) - - crypter := cipher.NewCBCDecrypter(a, s.iv) - crypter.CryptBlocks(ret, data) - return unpad(ret, 0x80) -} - -// unpad strips padding from a message. -func unpad(data []byte, terminator byte) ([]byte, error) { - for i := 1; i <= 16; i++ { - switch data[len(data)-i] { - case 0: - continue - case terminator: - return data[:len(data)-i], nil - default: - return nil, fmt.Errorf("expected end of padding, got %d", data[len(data)-i]) - } - } - return nil, errors.New("expected end of padding, got 0") -} - -// updateIV is an internal method that updates the initialization vector after -// each message exchanged. -func (s *SecureChannelSession) updateIV(meta, data []byte) error { - data = pad(data, 0) - a, err := aes.NewCipher(s.sessionMacKey) - if err != nil { - return err - } - crypter := cipher.NewCBCEncrypter(a, make([]byte, 16)) - crypter.CryptBlocks(meta, meta) - crypter.CryptBlocks(data, data) - // The first 16 bytes of the last block is the MAC - s.iv = data[len(data)-32 : len(data)-16] - return nil -} diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go deleted file mode 100644 index 327339c222..0000000000 --- a/accounts/scwallet/wallet.go +++ /dev/null @@ -1,1098 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package scwallet - -import ( - "bytes" - "context" - "crypto/hmac" - "crypto/sha256" - "crypto/sha512" - "encoding/asn1" - "encoding/binary" - "errors" - "fmt" - "math/big" - "regexp" - "sort" - "strings" - "sync" - "time" - - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - pcsc "github.com/gballet/go-libpcsclite" - "github.com/status-im/keycard-go/derivationpath" -) - -// ErrPairingPasswordNeeded is returned if opening the smart card requires pairing with a pairing -// password. In this case, the calling application should request user input to enter -// the pairing password and send it back. -var ErrPairingPasswordNeeded = errors.New("smartcard: pairing password needed") - -// ErrPINNeeded is returned if opening the smart card requires a PIN code. In -// this case, the calling application should request user input to enter the PIN -// and send it back. -var ErrPINNeeded = errors.New("smartcard: pin needed") - -// ErrPINUnblockNeeded is returned if opening the smart card requires a PIN code, -// but all PIN attempts have already been exhausted. In this case the calling -// application should request user input for the PUK and a new PIN code to set -// fo the card. -var ErrPINUnblockNeeded = errors.New("smartcard: pin unblock needed") - -// ErrAlreadyOpen is returned if the smart card is attempted to be opened, but -// there is already a paired and unlocked session. -var ErrAlreadyOpen = errors.New("smartcard: already open") - -// ErrPubkeyMismatch is returned if the public key recovered from a signature -// does not match the one expected by the user. -var ErrPubkeyMismatch = errors.New("smartcard: recovered public key mismatch") - -var ( - appletAID = []byte{0xA0, 0x00, 0x00, 0x08, 0x04, 0x00, 0x01, 0x01, 0x01} - // DerivationSignatureHash is used to derive the public key from the signature of this hash - DerivationSignatureHash = sha256.Sum256(common.Hash{}.Bytes()) -) - -// List of APDU command-related constants -const ( - claISO7816 = 0 - claSCWallet = 0x80 - - insSelect = 0xA4 - insGetResponse = 0xC0 - sw1GetResponse = 0x61 - sw1Ok = 0x90 - - insVerifyPin = 0x20 - insUnblockPin = 0x22 - insExportKey = 0xC2 - insSign = 0xC0 - insLoadKey = 0xD0 - insDeriveKey = 0xD1 - insStatus = 0xF2 -) - -// List of ADPU command parameters -const ( - P1DeriveKeyFromMaster = uint8(0x00) - P1DeriveKeyFromParent = uint8(0x01) - P1DeriveKeyFromCurrent = uint8(0x10) - statusP1WalletStatus = uint8(0x00) - statusP1Path = uint8(0x01) - signP1PrecomputedHash = uint8(0x00) - signP2OnlyBlock = uint8(0x00) - exportP1Any = uint8(0x00) - exportP2Pubkey = uint8(0x01) -) - -// Minimum time to wait between self derivation attempts, even it the user is -// requesting accounts like crazy. -const selfDeriveThrottling = time.Second - -// Wallet represents a smartcard wallet instance. -type Wallet struct { - Hub *Hub // A handle to the Hub that instantiated this wallet. - PublicKey []byte // The wallet's public key (used for communication and identification, not signing!) - - lock sync.Mutex // Lock that gates access to struct fields and communication with the card - card *pcsc.Card // A handle to the smartcard interface for the wallet. - session *Session // The secure communication session with the card - log log.Logger // Contextual logger to tag the base with its id - - deriveNextPaths []accounts.DerivationPath // Next derivation paths for account auto-discovery (multiple bases supported) - deriveNextAddrs []common.Address // Next derived account addresses for auto-discovery (multiple bases supported) - deriveChain interfaces.ChainStateReader // Blockchain state reader to discover used account with - deriveReq chan chan struct{} // Channel to request a self-derivation on - deriveQuit chan chan error // Channel to terminate the self-deriver with -} - -// NewWallet constructs and returns a new Wallet instance. -func NewWallet(hub *Hub, card *pcsc.Card) *Wallet { - wallet := &Wallet{ - Hub: hub, - card: card, - } - return wallet -} - -// transmit sends an APDU to the smartcard and receives and decodes the response. -// It automatically handles requests by the card to fetch the return data separately, -// and returns an error if the response status code is not success. -func transmit(card *pcsc.Card, command *commandAPDU) (*responseAPDU, error) { - data, err := command.serialize() - if err != nil { - return nil, err - } - - responseData, _, err := card.Transmit(data) - if err != nil { - return nil, err - } - - response := new(responseAPDU) - if err = response.deserialize(responseData); err != nil { - return nil, err - } - - // Are we being asked to fetch the response separately? - if response.Sw1 == sw1GetResponse && (command.Cla != claISO7816 || command.Ins != insGetResponse) { - return transmit(card, &commandAPDU{ - Cla: claISO7816, - Ins: insGetResponse, - P1: 0, - P2: 0, - Data: nil, - Le: response.Sw2, - }) - } - - if response.Sw1 != sw1Ok { - return nil, fmt.Errorf("unexpected insecure response status Cla=%#x, Ins=%#x, Sw=%#x%x", command.Cla, command.Ins, response.Sw1, response.Sw2) - } - - return response, nil -} - -// applicationInfo encodes information about the smartcard application - its -// instance UID and public key. -type applicationInfo struct { - InstanceUID []byte `asn1:"tag:15"` - PublicKey []byte `asn1:"tag:0"` -} - -// connect connects to the wallet application and establishes a secure channel with it. -// must be called before any other interaction with the wallet. -func (w *Wallet) connect() error { - w.lock.Lock() - defer w.lock.Unlock() - - appinfo, err := w.doselect() - if err != nil { - return err - } - - channel, err := NewSecureChannelSession(w.card, appinfo.PublicKey) - if err != nil { - return err - } - - w.PublicKey = appinfo.PublicKey - w.log = log.New("url", w.URL()) - w.session = &Session{ - Wallet: w, - Channel: channel, - } - return nil -} - -// doselect is an internal (unlocked) function to send a SELECT APDU to the card. -func (w *Wallet) doselect() (*applicationInfo, error) { - response, err := transmit(w.card, &commandAPDU{ - Cla: claISO7816, - Ins: insSelect, - P1: 4, - P2: 0, - Data: appletAID, - }) - if err != nil { - return nil, err - } - - appinfo := new(applicationInfo) - if _, err := asn1.UnmarshalWithParams(response.Data, appinfo, "tag:4"); err != nil { - return nil, err - } - return appinfo, nil -} - -// ping checks the card's status and returns an error if unsuccessful. -func (w *Wallet) ping() error { - w.lock.Lock() - defer w.lock.Unlock() - - // We can't ping if not paired - if !w.session.paired() { - return nil - } - if _, err := w.session.walletStatus(); err != nil { - return err - } - return nil -} - -// release releases any resources held by an open wallet instance. -func (w *Wallet) release() error { - if w.session != nil { - return w.session.release() - } - return nil -} - -// pair is an internal (unlocked) function for establishing a new pairing -// with the wallet. -func (w *Wallet) pair(puk []byte) error { - if w.session.paired() { - return errors.New("wallet already paired") - } - pairing, err := w.session.pair(puk) - if err != nil { - return err - } - if err = w.Hub.setPairing(w, &pairing); err != nil { - return err - } - return w.session.authenticate(pairing) -} - -// Unpair deletes an existing wallet pairing. -func (w *Wallet) Unpair(pin []byte) error { - w.lock.Lock() - defer w.lock.Unlock() - - if !w.session.paired() { - return fmt.Errorf("wallet %x not paired", w.PublicKey) - } - if err := w.session.verifyPin(pin); err != nil { - return fmt.Errorf("failed to verify pin: %s", err) - } - if err := w.session.unpair(); err != nil { - return fmt.Errorf("failed to unpair: %s", err) - } - if err := w.Hub.setPairing(w, nil); err != nil { - return err - } - return nil -} - -// URL retrieves the canonical path under which this wallet is reachable. It is -// user by upper layers to define a sorting order over all wallets from multiple -// backends. -func (w *Wallet) URL() accounts.URL { - return accounts.URL{ - Scheme: w.Hub.scheme, - Path: fmt.Sprintf("%x", w.PublicKey[1:5]), // Byte #0 isn't unique; 1:5 covers << 64K cards, bump to 1:9 for << 4M - } -} - -// Status returns a textual status to aid the user in the current state of the -// wallet. It also returns an error indicating any failure the wallet might have -// encountered. -func (w *Wallet) Status() (string, error) { - w.lock.Lock() - defer w.lock.Unlock() - - // If the card is not paired, we can only wait - if !w.session.paired() { - return "Unpaired, waiting for pairing password", nil - } - // Yay, we have an encrypted session, retrieve the actual status - status, err := w.session.walletStatus() - if err != nil { - return fmt.Sprintf("Failed: %v", err), err - } - switch { - case !w.session.verified && status.PinRetryCount == 0 && status.PukRetryCount == 0: - return "Bricked, waiting for full wipe", nil - case !w.session.verified && status.PinRetryCount == 0: - return fmt.Sprintf("Blocked, waiting for PUK (%d attempts left) and new PIN", status.PukRetryCount), nil - case !w.session.verified: - return fmt.Sprintf("Locked, waiting for PIN (%d attempts left)", status.PinRetryCount), nil - case !status.Initialized: - return "Empty, waiting for initialization", nil - default: - return "Online", nil - } -} - -// Open initializes access to a wallet instance. It is not meant to unlock or -// decrypt account keys, rather simply to establish a connection to hardware -// wallets and/or to access derivation seeds. -// -// The passphrase parameter may or may not be used by the implementation of a -// particular wallet instance. The reason there is no passwordless open method -// is to strive towards a uniform wallet handling, oblivious to the different -// backend providers. -// -// Please note, if you open a wallet, you must close it to release any allocated -// resources (especially important when working with hardware wallets). -func (w *Wallet) Open(passphrase string) error { - w.lock.Lock() - defer w.lock.Unlock() - - // If the session is already open, bail out - if w.session.verified { - return ErrAlreadyOpen - } - // If the smart card is not yet paired, attempt to do so either from a previous - // pairing key or form the supplied PUK code. - if !w.session.paired() { - // If a previous pairing exists, only ever try to use that - if pairing := w.Hub.pairing(w); pairing != nil { - if err := w.session.authenticate(*pairing); err != nil { - return fmt.Errorf("failed to authenticate card %x: %s", w.PublicKey[:4], err) - } - // Pairing still ok, fall through to PIN checks - } else { - // If no passphrase was supplied, request the PUK from the user - if passphrase == "" { - return ErrPairingPasswordNeeded - } - // Attempt to pair the smart card with the user supplied PUK - if err := w.pair([]byte(passphrase)); err != nil { - return err - } - // Pairing succeeded, fall through to PIN checks. This will of course fail, - // but we can't return ErrPINNeeded directly here because we don't know whether - // a PIN check or a PIN reset is needed. - passphrase = "" - } - } - // The smart card was successfully paired, retrieve its status to check whether - // PIN verification or unblocking is needed. - status, err := w.session.walletStatus() - if err != nil { - return err - } - // Request the appropriate next authentication data, or use the one supplied - switch { - case passphrase == "" && status.PinRetryCount > 0: - return ErrPINNeeded - case passphrase == "": - return ErrPINUnblockNeeded - case status.PinRetryCount > 0: - if !regexp.MustCompile(`^[0-9]{6,}$`).MatchString(passphrase) { - w.log.Error("PIN needs to be at least 6 digits") - return ErrPINNeeded - } - if err := w.session.verifyPin([]byte(passphrase)); err != nil { - return err - } - default: - if !regexp.MustCompile(`^[0-9]{12,}$`).MatchString(passphrase) { - w.log.Error("PUK needs to be at least 12 digits") - return ErrPINUnblockNeeded - } - if err := w.session.unblockPin([]byte(passphrase)); err != nil { - return err - } - } - // Smart card paired and unlocked, initialize and register - w.deriveReq = make(chan chan struct{}) - w.deriveQuit = make(chan chan error) - - go w.selfDerive() - - // Notify anyone listening for wallet events that a new device is accessible - go w.Hub.updateFeed.Send(accounts.WalletEvent{Wallet: w, Kind: accounts.WalletOpened}) - - return nil -} - -// Close stops and closes the wallet, freeing any resources. -func (w *Wallet) Close() error { - // Ensure the wallet was opened - w.lock.Lock() - dQuit := w.deriveQuit - w.lock.Unlock() - - // Terminate the self-derivations - var derr error - if dQuit != nil { - errc := make(chan error) - dQuit <- errc - derr = <-errc // Save for later, we *must* close the USB - } - // Terminate the device connection - w.lock.Lock() - defer w.lock.Unlock() - - w.deriveQuit = nil - w.deriveReq = nil - - if err := w.release(); err != nil { - return err - } - return derr -} - -// selfDerive is an account derivation loop that upon request attempts to find -// new non-zero accounts. -func (w *Wallet) selfDerive() { - w.log.Debug("Smart card wallet self-derivation started") - defer w.log.Debug("Smart card wallet self-derivation stopped") - - // Execute self-derivations until termination or error - var ( - reqc chan struct{} - errc chan error - err error - ) - for errc == nil && err == nil { - // Wait until either derivation or termination is requested - select { - case errc = <-w.deriveQuit: - // Termination requested - continue - case reqc = <-w.deriveReq: - // Account discovery requested - } - // Derivation needs a chain and device access, skip if either unavailable - w.lock.Lock() - if w.session == nil || w.deriveChain == nil { - w.lock.Unlock() - reqc <- struct{}{} - continue - } - pairing := w.Hub.pairing(w) - - // Device lock obtained, derive the next batch of accounts - var ( - paths []accounts.DerivationPath - nextAcc accounts.Account - - nextPaths = append([]accounts.DerivationPath{}, w.deriveNextPaths...) - nextAddrs = append([]common.Address{}, w.deriveNextAddrs...) - - context = context.Background() - ) - for i := 0; i < len(nextAddrs); i++ { - for empty := false; !empty; { - // Retrieve the next derived Ethereum account - if nextAddrs[i] == (common.Address{}) { - if nextAcc, err = w.session.derive(nextPaths[i]); err != nil { - w.log.Warn("Smartcard wallet account derivation failed", "err", err) - break - } - nextAddrs[i] = nextAcc.Address - } - // Check the account's status against the current chain state - var ( - balance *big.Int - nonce uint64 - ) - balance, err = w.deriveChain.BalanceAt(context, nextAddrs[i], nil) - if err != nil { - w.log.Warn("Smartcard wallet balance retrieval failed", "err", err) - break - } - nonce, err = w.deriveChain.NonceAt(context, nextAddrs[i], nil) - if err != nil { - w.log.Warn("Smartcard wallet nonce retrieval failed", "err", err) - break - } - // If the next account is empty, stop self-derivation, but add for the last base path - if balance.Sign() == 0 && nonce == 0 { - empty = true - if i < len(nextAddrs)-1 { - break - } - } - // We've just self-derived a new account, start tracking it locally - path := make(accounts.DerivationPath, len(nextPaths[i])) - copy(path[:], nextPaths[i][:]) - paths = append(paths, path) - - // Display a log message to the user for new (or previously empty accounts) - if _, known := pairing.Accounts[nextAddrs[i]]; !known || !empty || nextAddrs[i] != w.deriveNextAddrs[i] { - w.log.Info("Smartcard wallet discovered new account", "address", nextAddrs[i], "path", path, "balance", balance, "nonce", nonce) - } - pairing.Accounts[nextAddrs[i]] = path - - // Fetch the next potential account - if !empty { - nextAddrs[i] = common.Address{} - nextPaths[i][len(nextPaths[i])-1]++ - } - } - } - // If there are new accounts, write them out - if len(paths) > 0 { - err = w.Hub.setPairing(w, pairing) - } - // Shift the self-derivation forward - w.deriveNextAddrs = nextAddrs - w.deriveNextPaths = nextPaths - - // Self derivation complete, release device lock - w.lock.Unlock() - - // Notify the user of termination and loop after a bit of time (to avoid trashing) - reqc <- struct{}{} - if err == nil { - select { - case errc = <-w.deriveQuit: - // Termination requested, abort - case <-time.After(selfDeriveThrottling): - // Waited enough, willing to self-derive again - } - } - } - // In case of error, wait for termination - if err != nil { - w.log.Debug("Smartcard wallet self-derivation failed", "err", err) - errc = <-w.deriveQuit - } - errc <- err -} - -// Accounts retrieves the list of signing accounts the wallet is currently aware -// of. For hierarchical deterministic wallets, the list will not be exhaustive, -// rather only contain the accounts explicitly pinned during account derivation. -func (w *Wallet) Accounts() []accounts.Account { - // Attempt self-derivation if it's running - reqc := make(chan struct{}, 1) - select { - case w.deriveReq <- reqc: - // Self-derivation request accepted, wait for it - <-reqc - default: - // Self-derivation offline, throttled or busy, skip - } - - w.lock.Lock() - defer w.lock.Unlock() - - if pairing := w.Hub.pairing(w); pairing != nil { - ret := make([]accounts.Account, 0, len(pairing.Accounts)) - for address, path := range pairing.Accounts { - ret = append(ret, w.makeAccount(address, path)) - } - sort.Sort(accounts.AccountsByURL(ret)) - return ret - } - return nil -} - -func (w *Wallet) makeAccount(address common.Address, path accounts.DerivationPath) accounts.Account { - return accounts.Account{ - Address: address, - URL: accounts.URL{ - Scheme: w.Hub.scheme, - Path: fmt.Sprintf("%x/%s", w.PublicKey[1:3], path.String()), - }, - } -} - -// Contains returns whether an account is part of this particular wallet or not. -func (w *Wallet) Contains(account accounts.Account) bool { - if pairing := w.Hub.pairing(w); pairing != nil { - _, ok := pairing.Accounts[account.Address] - return ok - } - return false -} - -// Initialize installs a keypair generated from the provided key into the wallet. -func (w *Wallet) Initialize(seed []byte) error { - go w.selfDerive() - // DO NOT lock at this stage, as the initialize - // function relies on Status() - return w.session.initialize(seed) -} - -// Derive attempts to explicitly derive a hierarchical deterministic account at -// the specified derivation path. If requested, the derived account will be added -// to the wallet's tracked account list. -func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) { - w.lock.Lock() - defer w.lock.Unlock() - - account, err := w.session.derive(path) - if err != nil { - return accounts.Account{}, err - } - - if pin { - pairing := w.Hub.pairing(w) - pairing.Accounts[account.Address] = path - if err := w.Hub.setPairing(w, pairing); err != nil { - return accounts.Account{}, err - } - } - - return account, nil -} - -// SelfDerive sets a base account derivation path from which the wallet attempts -// to discover non zero accounts and automatically add them to list of tracked -// accounts. -// -// Note, self derivation will increment the last component of the specified path -// opposed to descending into a child path to allow discovering accounts starting -// from non zero components. -// -// Some hardware wallets switched derivation paths through their evolution, so -// this method supports providing multiple bases to discover old user accounts -// too. Only the last base will be used to derive the next empty account. -// -// You can disable automatic account discovery by calling SelfDerive with a nil -// chain state reader. -func (w *Wallet) SelfDerive(bases []accounts.DerivationPath, chain interfaces.ChainStateReader) { - w.lock.Lock() - defer w.lock.Unlock() - - w.deriveNextPaths = make([]accounts.DerivationPath, len(bases)) - for i, base := range bases { - w.deriveNextPaths[i] = make(accounts.DerivationPath, len(base)) - copy(w.deriveNextPaths[i][:], base[:]) - } - w.deriveNextAddrs = make([]common.Address, len(bases)) - w.deriveChain = chain -} - -// SignData requests the wallet to sign the hash of the given data. -// -// It looks up the account specified either solely via its address contained within, -// or optionally with the aid of any location metadata from the embedded URL field. -// -// If the wallet requires additional authentication to sign the request (e.g. -// a password to decrypt the account, or a PIN code to verify the transaction), -// an AuthNeededError instance will be returned, containing infos for the user -// about which fields or actions are needed. The user may retry by providing -// the needed details via SignDataWithPassphrase, or by other means (e.g. unlock -// the account in a keystore). -func (w *Wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) { - return w.signHash(account, crypto.Keccak256(data)) -} - -func (w *Wallet) signHash(account accounts.Account, hash []byte) ([]byte, error) { - w.lock.Lock() - defer w.lock.Unlock() - - path, err := w.findAccountPath(account) - if err != nil { - return nil, err - } - - return w.session.sign(path, hash) -} - -// SignTx requests the wallet to sign the given transaction. -// -// It looks up the account specified either solely via its address contained within, -// or optionally with the aid of any location metadata from the embedded URL field. -// -// If the wallet requires additional authentication to sign the request (e.g. -// a password to decrypt the account, or a PIN code to verify the transaction), -// an AuthNeededError instance will be returned, containing infos for the user -// about which fields or actions are needed. The user may retry by providing -// the needed details via SignTxWithPassphrase, or by other means (e.g. unlock -// the account in a keystore). -func (w *Wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - signer := types.LatestSignerForChainID(chainID) - hash := signer.Hash(tx) - sig, err := w.signHash(account, hash[:]) - if err != nil { - return nil, err - } - return tx.WithSignature(signer, sig) -} - -// SignDataWithPassphrase requests the wallet to sign the given hash with the -// given passphrase as extra authentication information. -// -// It looks up the account specified either solely via its address contained within, -// or optionally with the aid of any location metadata from the embedded URL field. -func (w *Wallet) SignDataWithPassphrase(account accounts.Account, passphrase, mimeType string, data []byte) ([]byte, error) { - return w.signHashWithPassphrase(account, passphrase, crypto.Keccak256(data)) -} - -func (w *Wallet) signHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) { - if !w.session.verified { - if err := w.Open(passphrase); err != nil { - return nil, err - } - } - - return w.signHash(account, hash) -} - -// SignText requests the wallet to sign the hash of a given piece of data, prefixed -// by the Ethereum prefix scheme -// It looks up the account specified either solely via its address contained within, -// or optionally with the aid of any location metadata from the embedded URL field. -// -// If the wallet requires additional authentication to sign the request (e.g. -// a password to decrypt the account, or a PIN code to verify the transaction), -// an AuthNeededError instance will be returned, containing infos for the user -// about which fields or actions are needed. The user may retry by providing -// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock -// the account in a keystore). -func (w *Wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { - return w.signHash(account, accounts.TextHash(text)) -} - -// SignTextWithPassphrase implements accounts.Wallet, attempting to sign the -// given hash with the given account using passphrase as extra authentication -func (w *Wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { - return w.signHashWithPassphrase(account, passphrase, crypto.Keccak256(accounts.TextHash(text))) -} - -// SignTxWithPassphrase requests the wallet to sign the given transaction, with the -// given passphrase as extra authentication information. -// -// It looks up the account specified either solely via its address contained within, -// or optionally with the aid of any location metadata from the embedded URL field. -func (w *Wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { - if !w.session.verified { - if err := w.Open(passphrase); err != nil { - return nil, err - } - } - return w.SignTx(account, tx, chainID) -} - -// findAccountPath returns the derivation path for the provided account. -// It first checks for the address in the list of pinned accounts, and if it is -// not found, attempts to parse the derivation path from the account's URL. -func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationPath, error) { - pairing := w.Hub.pairing(w) - if path, ok := pairing.Accounts[account.Address]; ok { - return path, nil - } - - // Look for the path in the URL - if account.URL.Scheme != w.Hub.scheme { - return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) - } - - url, path, found := strings.Cut(account.URL.Path, "/") - if !found { - return nil, fmt.Errorf("invalid URL format: %s", account.URL) - } - - if url != fmt.Sprintf("%x", w.PublicKey[1:3]) { - return nil, fmt.Errorf("URL %s is not for this wallet", account.URL) - } - - return accounts.ParseDerivationPath(path) -} - -// Session represents a secured communication session with the wallet. -type Session struct { - Wallet *Wallet // A handle to the wallet that opened the session - Channel *SecureChannelSession // A secure channel for encrypted messages - verified bool // Whether the pin has been verified in this session. -} - -// pair establishes a new pairing over this channel, using the provided secret. -func (s *Session) pair(secret []byte) (smartcardPairing, error) { - err := s.Channel.Pair(secret) - if err != nil { - return smartcardPairing{}, err - } - - return smartcardPairing{ - PublicKey: s.Wallet.PublicKey, - PairingIndex: s.Channel.PairingIndex, - PairingKey: s.Channel.PairingKey, - Accounts: make(map[common.Address]accounts.DerivationPath), - }, nil -} - -// unpair deletes an existing pairing. -func (s *Session) unpair() error { - if !s.verified { - return errors.New("unpair requires that the PIN be verified") - } - return s.Channel.Unpair() -} - -// verifyPin unlocks a wallet with the provided pin. -func (s *Session) verifyPin(pin []byte) error { - if _, err := s.Channel.transmitEncrypted(claSCWallet, insVerifyPin, 0, 0, pin); err != nil { - return err - } - s.verified = true - return nil -} - -// unblockPin unblocks a wallet with the provided puk and resets the pin to the -// new one specified. -func (s *Session) unblockPin(pukpin []byte) error { - if _, err := s.Channel.transmitEncrypted(claSCWallet, insUnblockPin, 0, 0, pukpin); err != nil { - return err - } - s.verified = true - return nil -} - -// release releases resources associated with the channel. -func (s *Session) release() error { - return s.Wallet.card.Disconnect(pcsc.LeaveCard) -} - -// paired returns true if a valid pairing exists. -func (s *Session) paired() bool { - return s.Channel.PairingKey != nil -} - -// authenticate uses an existing pairing to establish a secure channel. -func (s *Session) authenticate(pairing smartcardPairing) error { - if !bytes.Equal(s.Wallet.PublicKey, pairing.PublicKey) { - return fmt.Errorf("cannot pair using another wallet's pairing; %x != %x", s.Wallet.PublicKey, pairing.PublicKey) - } - s.Channel.PairingKey = pairing.PairingKey - s.Channel.PairingIndex = pairing.PairingIndex - return s.Channel.Open() -} - -// walletStatus describes a smartcard wallet's status information. -type walletStatus struct { - PinRetryCount int // Number of remaining PIN retries - PukRetryCount int // Number of remaining PUK retries - Initialized bool // Whether the card has been initialized with a private key -} - -// walletStatus fetches the wallet's status from the card. -func (s *Session) walletStatus() (*walletStatus, error) { - response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1WalletStatus, 0, nil) - if err != nil { - return nil, err - } - - status := new(walletStatus) - if _, err := asn1.UnmarshalWithParams(response.Data, status, "tag:3"); err != nil { - return nil, err - } - return status, nil -} - -// derivationPath fetches the wallet's current derivation path from the card. -// -//lint:ignore U1000 needs to be added to the console interface -func (s *Session) derivationPath() (accounts.DerivationPath, error) { - response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1Path, 0, nil) - if err != nil { - return nil, err - } - buf := bytes.NewReader(response.Data) - path := make(accounts.DerivationPath, len(response.Data)/4) - return path, binary.Read(buf, binary.BigEndian, &path) -} - -// initializeData contains data needed to initialize the smartcard wallet. -type initializeData struct { - PublicKey []byte `asn1:"tag:0"` - PrivateKey []byte `asn1:"tag:1"` - ChainCode []byte `asn1:"tag:2"` -} - -// initialize initializes the card with new key data. -func (s *Session) initialize(seed []byte) error { - // Check that the wallet isn't currently initialized, - // otherwise the key would be overwritten. - status, err := s.Wallet.Status() - if err != nil { - return err - } - if status == "Online" { - return errors.New("card is already initialized, cowardly refusing to proceed") - } - - s.Wallet.lock.Lock() - defer s.Wallet.lock.Unlock() - - // HMAC the seed to produce the private key and chain code - mac := hmac.New(sha512.New, []byte("Bitcoin seed")) - mac.Write(seed) - seed = mac.Sum(nil) - - key, err := crypto.ToECDSA(seed[:32]) - if err != nil { - return err - } - - id := initializeData{} - id.PublicKey = crypto.FromECDSAPub(&key.PublicKey) - id.PrivateKey = seed[:32] - id.ChainCode = seed[32:] - data, err := asn1.Marshal(id) - if err != nil { - return err - } - - // Nasty hack to force the top-level struct tag to be context-specific - data[0] = 0xA1 - - _, err = s.Channel.transmitEncrypted(claSCWallet, insLoadKey, 0x02, 0, data) - return err -} - -// derive derives a new HD key path on the card. -func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error) { - startingPoint, path, err := derivationpath.Decode(path.String()) - if err != nil { - return accounts.Account{}, err - } - - var p1 uint8 - switch startingPoint { - case derivationpath.StartingPointMaster: - p1 = P1DeriveKeyFromMaster - case derivationpath.StartingPointParent: - p1 = P1DeriveKeyFromParent - case derivationpath.StartingPointCurrent: - p1 = P1DeriveKeyFromCurrent - default: - return accounts.Account{}, fmt.Errorf("invalid startingPoint %d", startingPoint) - } - - data := new(bytes.Buffer) - for _, segment := range path { - if err := binary.Write(data, binary.BigEndian, segment); err != nil { - return accounts.Account{}, err - } - } - - _, err = s.Channel.transmitEncrypted(claSCWallet, insDeriveKey, p1, 0, data.Bytes()) - if err != nil { - return accounts.Account{}, err - } - - response, err := s.Channel.transmitEncrypted(claSCWallet, insSign, 0, 0, DerivationSignatureHash[:]) - if err != nil { - return accounts.Account{}, err - } - - sigdata := new(signatureData) - if _, err := asn1.UnmarshalWithParams(response.Data, sigdata, "tag:0"); err != nil { - return accounts.Account{}, err - } - rbytes, sbytes := sigdata.Signature.R.Bytes(), sigdata.Signature.S.Bytes() - sig := make([]byte, 65) - copy(sig[32-len(rbytes):32], rbytes) - copy(sig[64-len(sbytes):64], sbytes) - - if err := confirmPublicKey(sig, sigdata.PublicKey); err != nil { - return accounts.Account{}, err - } - pub, err := crypto.UnmarshalPubkey(sigdata.PublicKey) - if err != nil { - return accounts.Account{}, err - } - return s.Wallet.makeAccount(crypto.PubkeyToAddress(*pub), path), nil -} - -// keyExport contains information on an exported keypair. -// -//lint:ignore U1000 needs to be added to the console interface -type keyExport struct { - PublicKey []byte `asn1:"tag:0"` - PrivateKey []byte `asn1:"tag:1,optional"` -} - -// publicKey returns the public key for the current derivation path. -// -//lint:ignore U1000 needs to be added to the console interface -func (s *Session) publicKey() ([]byte, error) { - response, err := s.Channel.transmitEncrypted(claSCWallet, insExportKey, exportP1Any, exportP2Pubkey, nil) - if err != nil { - return nil, err - } - keys := new(keyExport) - if _, err := asn1.UnmarshalWithParams(response.Data, keys, "tag:1"); err != nil { - return nil, err - } - return keys.PublicKey, nil -} - -// signatureData contains information on a signature - the signature itself and -// the corresponding public key. -type signatureData struct { - PublicKey []byte `asn1:"tag:0"` - Signature struct { - R *big.Int - S *big.Int - } -} - -// sign asks the card to sign a message, and returns a valid signature after -// recovering the v value. -func (s *Session) sign(path accounts.DerivationPath, hash []byte) ([]byte, error) { - startTime := time.Now() - _, err := s.derive(path) - if err != nil { - return nil, err - } - deriveTime := time.Now() - - response, err := s.Channel.transmitEncrypted(claSCWallet, insSign, signP1PrecomputedHash, signP2OnlyBlock, hash) - if err != nil { - return nil, err - } - sigdata := new(signatureData) - if _, err := asn1.UnmarshalWithParams(response.Data, sigdata, "tag:0"); err != nil { - return nil, err - } - // Serialize the signature - rbytes, sbytes := sigdata.Signature.R.Bytes(), sigdata.Signature.S.Bytes() - sig := make([]byte, 65) - copy(sig[32-len(rbytes):32], rbytes) - copy(sig[64-len(sbytes):64], sbytes) - - // Recover the V value. - sig, err = makeRecoverableSignature(hash, sig, sigdata.PublicKey) - if err != nil { - return nil, err - } - log.Debug("Signed using smartcard", "deriveTime", deriveTime.Sub(startTime), "signingTime", time.Since(deriveTime)) - - return sig, nil -} - -// confirmPublicKey confirms that the given signature belongs to the specified key. -func confirmPublicKey(sig, pubkey []byte) error { - _, err := makeRecoverableSignature(DerivationSignatureHash[:], sig, pubkey) - return err -} - -// makeRecoverableSignature uses a signature and an expected public key to -// recover the v value and produce a recoverable signature. -func makeRecoverableSignature(hash, sig, expectedPubkey []byte) ([]byte, error) { - var libraryError error - for v := 0; v < 2; v++ { - sig[64] = byte(v) - if pubkey, err := crypto.Ecrecover(hash, sig); err == nil { - if bytes.Equal(pubkey, expectedPubkey) { - return sig, nil - } - } else { - libraryError = err - } - } - if libraryError != nil { - return nil, libraryError - } - return nil, ErrPubkeyMismatch -} diff --git a/accounts/sort.go b/accounts/sort.go deleted file mode 100644 index 16ec896863..0000000000 --- a/accounts/sort.go +++ /dev/null @@ -1,41 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -// AccountsByURL implements sort.Interface for []Account based on the URL field. -type AccountsByURL []Account - -func (a AccountsByURL) Len() int { return len(a) } -func (a AccountsByURL) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a AccountsByURL) Less(i, j int) bool { return a[i].URL.Cmp(a[j].URL) < 0 } - -// WalletsByURL implements sort.Interface for []Wallet based on the URL field. -type WalletsByURL []Wallet - -func (w WalletsByURL) Len() int { return len(w) } -func (w WalletsByURL) Swap(i, j int) { w[i], w[j] = w[j], w[i] } -func (w WalletsByURL) Less(i, j int) bool { return w[i].URL().Cmp(w[j].URL()) < 0 } diff --git a/accounts/url.go b/accounts/url.go deleted file mode 100644 index d7ebeaefa2..0000000000 --- a/accounts/url.go +++ /dev/null @@ -1,113 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -import ( - "encoding/json" - "errors" - "fmt" - "strings" -) - -// URL represents the canonical identification URL of a wallet or account. -// -// It is a simplified version of url.URL, with the important limitations (which -// are considered features here) that it contains value-copyable components only, -// as well as that it doesn't do any URL encoding/decoding of special characters. -// -// The former is important to allow an account to be copied without leaving live -// references to the original version, whereas the latter is important to ensure -// one single canonical form opposed to many allowed ones by the RFC 3986 spec. -// -// As such, these URLs should not be used outside of the scope of an Ethereum -// wallet or account. -type URL struct { - Scheme string // Protocol scheme to identify a capable account backend - Path string // Path for the backend to identify a unique entity -} - -// parseURL converts a user supplied URL into the accounts specific structure. -func parseURL(url string) (URL, error) { - parts := strings.Split(url, "://") - if len(parts) != 2 || parts[0] == "" { - return URL{}, errors.New("protocol scheme missing") - } - return URL{ - Scheme: parts[0], - Path: parts[1], - }, nil -} - -// String implements the stringer interface. -func (u URL) String() string { - if u.Scheme != "" { - return fmt.Sprintf("%s://%s", u.Scheme, u.Path) - } - return u.Path -} - -// TerminalString implements the log.TerminalStringer interface. -func (u URL) TerminalString() string { - url := u.String() - if len(url) > 32 { - return url[:31] + ".." - } - return url -} - -// MarshalJSON implements the json.Marshaller interface. -func (u URL) MarshalJSON() ([]byte, error) { - return json.Marshal(u.String()) -} - -// UnmarshalJSON parses url. -func (u *URL) UnmarshalJSON(input []byte) error { - var textURL string - err := json.Unmarshal(input, &textURL) - if err != nil { - return err - } - url, err := parseURL(textURL) - if err != nil { - return err - } - u.Scheme = url.Scheme - u.Path = url.Path - return nil -} - -// Cmp compares x and y and returns: -// -// -1 if x < y -// 0 if x == y -// +1 if x > y -func (u URL) Cmp(url URL) int { - if u.Scheme == url.Scheme { - return strings.Compare(u.Path, url.Path) - } - return strings.Compare(u.Scheme, url.Scheme) -} diff --git a/accounts/url_test.go b/accounts/url_test.go deleted file mode 100644 index efcc6a2f89..0000000000 --- a/accounts/url_test.go +++ /dev/null @@ -1,112 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package accounts - -import ( - "testing" -) - -func TestURLParsing(t *testing.T) { - t.Parallel() - url, err := parseURL("https://ethereum.org") - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if url.Scheme != "https" { - t.Errorf("expected: %v, got: %v", "https", url.Scheme) - } - if url.Path != "ethereum.org" { - t.Errorf("expected: %v, got: %v", "ethereum.org", url.Path) - } - - for _, u := range []string{"ethereum.org", ""} { - if _, err = parseURL(u); err == nil { - t.Errorf("input %v, expected err, got: nil", u) - } - } -} - -func TestURLString(t *testing.T) { - t.Parallel() - url := URL{Scheme: "https", Path: "ethereum.org"} - if url.String() != "https://ethereum.org" { - t.Errorf("expected: %v, got: %v", "https://ethereum.org", url.String()) - } - - url = URL{Scheme: "", Path: "ethereum.org"} - if url.String() != "ethereum.org" { - t.Errorf("expected: %v, got: %v", "ethereum.org", url.String()) - } -} - -func TestURLMarshalJSON(t *testing.T) { - t.Parallel() - url := URL{Scheme: "https", Path: "ethereum.org"} - json, err := url.MarshalJSON() - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if string(json) != "\"https://ethereum.org\"" { - t.Errorf("expected: %v, got: %v", "\"https://ethereum.org\"", string(json)) - } -} - -func TestURLUnmarshalJSON(t *testing.T) { - t.Parallel() - url := &URL{} - err := url.UnmarshalJSON([]byte("\"https://ethereum.org\"")) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if url.Scheme != "https" { - t.Errorf("expected: %v, got: %v", "https", url.Scheme) - } - if url.Path != "ethereum.org" { - t.Errorf("expected: %v, got: %v", "https", url.Path) - } -} - -func TestURLComparison(t *testing.T) { - t.Parallel() - tests := []struct { - urlA URL - urlB URL - expect int - }{ - {URL{"https", "ethereum.org"}, URL{"https", "ethereum.org"}, 0}, - {URL{"http", "ethereum.org"}, URL{"https", "ethereum.org"}, -1}, - {URL{"https", "ethereum.org/a"}, URL{"https", "ethereum.org"}, 1}, - {URL{"https", "abc.org"}, URL{"https", "ethereum.org"}, -1}, - } - - for i, tt := range tests { - result := tt.urlA.Cmp(tt.urlB) - if result != tt.expect { - t.Errorf("test %d: cmp mismatch: expected: %d, got: %d", i, tt.expect, result) - } - } -} diff --git a/cmd/abigen/main.go b/cmd/abigen/main.go index a6f670ea4d..2dd4a35682 100644 --- a/cmd/abigen/main.go +++ b/cmd/abigen/main.go @@ -37,9 +37,9 @@ import ( "github.com/ava-labs/coreth/accounts/abi/bind" "github.com/ava-labs/coreth/cmd/utils" "github.com/ava-labs/coreth/internal/flags" - "github.com/ethereum/go-ethereum/common/compiler" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common/compiler" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" "github.com/urfave/cli/v2" ) diff --git a/consensus/consensus.go b/consensus/consensus.go index d4e247ceaf..9b1230dbea 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -31,9 +31,9 @@ import ( "math/big" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // ChainHeaderReader defines a small collection of methods needed to access the local diff --git a/consensus/dummy/consensus.go b/consensus/dummy/consensus.go index ba4c0e9c10..f9177abdb0 100644 --- a/consensus/dummy/consensus.go +++ b/consensus/dummy/consensus.go @@ -14,11 +14,13 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/misc/eip4844" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/trie" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/trie" customheader "github.com/ava-labs/coreth/plugin/evm/header" ) @@ -146,7 +148,7 @@ func NewFullFaker() *DummyEngine { } } -func verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, parent *types.Header) error { +func verifyHeaderGasFields(config *extras.ChainConfig, header *types.Header, parent *types.Header) error { if err := customheader.VerifyGasUsed(config, parent, header); err != nil { return err } @@ -166,30 +168,32 @@ func verifyHeaderGasFields(config *params.ChainConfig, header *types.Header, par return fmt.Errorf("expected base fee %d, found %d", expectedBaseFee, header.BaseFee) } + headerExtra := customtypes.GetHeaderExtra(header) + // Enforce BlockGasCost constraints expectedBlockGasCost := customheader.BlockGasCost( config, parent, header.Time, ) - if !utils.BigEqual(header.BlockGasCost, expectedBlockGasCost) { - return fmt.Errorf("invalid block gas cost: have %d, want %d", header.BlockGasCost, expectedBlockGasCost) + if !utils.BigEqual(headerExtra.BlockGasCost, expectedBlockGasCost) { + return fmt.Errorf("invalid block gas cost: have %d, want %d", headerExtra.BlockGasCost, expectedBlockGasCost) } // Verify ExtDataGasUsed not present before AP4 if !config.IsApricotPhase4(header.Time) { - if header.ExtDataGasUsed != nil { - return fmt.Errorf("invalid extDataGasUsed before fork: have %d, want ", header.ExtDataGasUsed) + if headerExtra.ExtDataGasUsed != nil { + return fmt.Errorf("invalid extDataGasUsed before fork: have %d, want ", headerExtra.ExtDataGasUsed) } return nil } // ExtDataGasUsed correctness is checked during block validation // (when the validator has access to the block contents) - if header.ExtDataGasUsed == nil { + if headerExtra.ExtDataGasUsed == nil { return errExtDataGasUsedNil } - if !header.ExtDataGasUsed.IsUint64() { + if !headerExtra.ExtDataGasUsed.IsUint64() { return errExtDataGasUsedTooLarge } return nil @@ -204,13 +208,14 @@ func (eng *DummyEngine) verifyHeader(chain consensus.ChainHeaderReader, header * // Verify the extra data is well-formed. config := chain.Config() - rules := config.GetAvalancheRules(header.Time) + configExtra := params.GetExtra(config) + rules := configExtra.GetAvalancheRules(header.Time) if err := customheader.VerifyExtra(rules, header.Extra); err != nil { return err } // Ensure gas-related header fields are correct - if err := verifyHeaderGasFields(config, header, parent); err != nil { + if err := verifyHeaderGasFields(configExtra, header, parent); err != nil { return err } @@ -372,10 +377,10 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types } } - config := chain.Config() + config := params.GetExtra(chain.Config()) timestamp := block.Time() // Verify the BlockGasCost set in the header matches the expected value. - blockGasCost := block.BlockGasCost() + blockGasCost := customtypes.BlockGasCost(block) expectedBlockGasCost := customheader.BlockGasCost( config, parent, @@ -392,7 +397,7 @@ func (eng *DummyEngine) Finalize(chain consensus.ChainHeaderReader, block *types if extDataGasUsed == nil { extDataGasUsed = new(big.Int).Set(common.Big0) } - if blockExtDataGasUsed := block.ExtDataGasUsed(); blockExtDataGasUsed == nil || !blockExtDataGasUsed.IsUint64() || blockExtDataGasUsed.Cmp(extDataGasUsed) != 0 { + if blockExtDataGasUsed := customtypes.BlockExtDataGasUsed(block); blockExtDataGasUsed == nil || !blockExtDataGasUsed.IsUint64() || blockExtDataGasUsed.Cmp(extDataGasUsed) != 0 { return fmt.Errorf("invalid extDataGasUsed: have %d, want %d", blockExtDataGasUsed, extDataGasUsed) } @@ -426,23 +431,24 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h } } - config := chain.Config() + configExtra := params.GetExtra(chain.Config()) + headerExtra := customtypes.GetHeaderExtra(header) // Calculate the required block gas cost for this block. - header.BlockGasCost = customheader.BlockGasCost( - config, + headerExtra.BlockGasCost = customheader.BlockGasCost( + configExtra, parent, header.Time, ) - if config.IsApricotPhase4(header.Time) { - header.ExtDataGasUsed = extDataGasUsed - if header.ExtDataGasUsed == nil { - header.ExtDataGasUsed = new(big.Int).Set(common.Big0) + if configExtra.IsApricotPhase4(header.Time) { + headerExtra.ExtDataGasUsed = extDataGasUsed + if headerExtra.ExtDataGasUsed == nil { + headerExtra.ExtDataGasUsed = new(big.Int) } // Verify that this block covers the block fee. if err := eng.verifyBlockFee( header.BaseFee, - header.BlockGasCost, + headerExtra.BlockGasCost, txs, receipts, contribution, @@ -452,19 +458,19 @@ func (eng *DummyEngine) FinalizeAndAssemble(chain consensus.ChainHeaderReader, h } // finalize the header.Extra - extraPrefix, err := customheader.ExtraPrefix(config, parent, header, eng.desiredTargetExcess) + extraPrefix, err := customheader.ExtraPrefix(configExtra, parent, header, eng.desiredTargetExcess) if err != nil { return nil, fmt.Errorf("failed to calculate new header.Extra: %w", err) } header.Extra = append(extraPrefix, header.Extra...) // commit the final state root - header.Root = state.IntermediateRoot(config.IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) // Header seems complete, assemble into a block and return - return types.NewBlockWithExtData( + return customtypes.NewBlockWithExtData( header, txs, uncles, receipts, trie.NewStackTrie(nil), - extraData, config.IsApricotPhase1(header.Time), + extraData, configExtra.IsApricotPhase1(header.Time), ), nil } diff --git a/consensus/dummy/consensus_test.go b/consensus/dummy/consensus_test.go index b4b317c09c..3e8429528a 100644 --- a/consensus/dummy/consensus_test.go +++ b/consensus/dummy/consensus_test.go @@ -8,10 +8,10 @@ import ( "math/big" "testing" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) func TestVerifyBlockFee(t *testing.T) { diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index 4d57af555c..5b78fa9e61 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -31,8 +31,8 @@ import ( "fmt" "math/big" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/libevm/core/types" ) var ( diff --git a/constants/constants.go b/constants/constants.go index 2514f58119..d1523eaa5b 100644 --- a/constants/constants.go +++ b/constants/constants.go @@ -3,7 +3,7 @@ package constants -import "github.com/ethereum/go-ethereum/common" +import "github.com/ava-labs/libevm/common" var ( BlackholeAddr = common.Address{ diff --git a/core/bench_test.go b/core/bench_test.go index ceb8c83f48..ba25ae991e 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -32,14 +32,14 @@ import ( "testing" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb" ) func BenchmarkInsertChain_empty_memdb(b *testing.B) { diff --git a/core/block_validator.go b/core/block_validator.go index a75eeb01a1..66911ce2cc 100644 --- a/core/block_validator.go +++ b/core/block_validator.go @@ -32,9 +32,10 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/trie" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/trie" ) // BlockValidator is responsible for validating block headers, uncles and @@ -147,10 +148,10 @@ func (v *BlockValidator) ValidateState(block *types.Block, statedb *state.StateD // the gas allowance. func CalcGasLimit(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint64 { // contrib = (parentGasUsed * 3 / 2) / 1024 - contrib := (parentGasUsed + parentGasUsed/2) / params.GasLimitBoundDivisor + contrib := (parentGasUsed + parentGasUsed/2) / ap0.GasLimitBoundDivisor // decay = parentGasLimit / 1024 -1 - decay := parentGasLimit/params.GasLimitBoundDivisor - 1 + decay := parentGasLimit/ap0.GasLimitBoundDivisor - 1 /* strategy: gasLimit of block-to-mine is set based on parent's @@ -160,8 +161,8 @@ func CalcGasLimit(parentGasUsed, parentGasLimit, gasFloor, gasCeil uint64) uint6 from parentGasLimit * (2/3) parentGasUsed is. */ limit := parentGasLimit - decay + contrib - if limit < params.MinGasLimit { - limit = params.MinGasLimit + if limit < ap0.MinGasLimit { + limit = ap0.MinGasLimit } // If we're outside our allowed gas range, we try to hone towards them if limit < gasFloor { diff --git a/core/blockchain.go b/core/blockchain.go index bd2eb66727..ab42f107cf 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -41,62 +41,78 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/misc/eip4844" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/internal/version" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/triedb/hashdb" "github.com/ava-labs/coreth/triedb/pathdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/lru" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" + + // Force libevm metrics of the same name to be registered first. + _ "github.com/ava-labs/libevm/core" ) +// ====== If resolving merge conflicts ====== +// +// All calls to metrics.NewRegistered*() for metrics also defined in libevm/core have been +// replaced either with: +// - metrics.GetOrRegister*() to get a metric already registered in libevm/core, or register it +// here otherwise +// - [getOrOverrideAsRegisteredCounter] to get a metric already registered in libevm/core +// only if it is a [metrics.Counter]. If it is not, the metric is unregistered and registered +// as a [metrics.Counter] here. +// +// These replacements ensure the same metrics are shared between the two packages. var ( - accountReadTimer = metrics.NewRegisteredCounter("chain/account/reads", nil) - accountHashTimer = metrics.NewRegisteredCounter("chain/account/hashes", nil) - accountUpdateTimer = metrics.NewRegisteredCounter("chain/account/updates", nil) - accountCommitTimer = metrics.NewRegisteredCounter("chain/account/commits", nil) - storageReadTimer = metrics.NewRegisteredCounter("chain/storage/reads", nil) - storageHashTimer = metrics.NewRegisteredCounter("chain/storage/hashes", nil) - storageUpdateTimer = metrics.NewRegisteredCounter("chain/storage/updates", nil) - storageCommitTimer = metrics.NewRegisteredCounter("chain/storage/commits", nil) - snapshotAccountReadTimer = metrics.NewRegisteredCounter("chain/snapshot/account/reads", nil) - snapshotStorageReadTimer = metrics.NewRegisteredCounter("chain/snapshot/storage/reads", nil) - snapshotCommitTimer = metrics.NewRegisteredCounter("chain/snapshot/commits", nil) - - triedbCommitTimer = metrics.NewRegisteredCounter("chain/triedb/commits", nil) - - blockInsertTimer = metrics.NewRegisteredCounter("chain/block/inserts", nil) - blockInsertCount = metrics.NewRegisteredCounter("chain/block/inserts/count", nil) - blockContentValidationTimer = metrics.NewRegisteredCounter("chain/block/validations/content", nil) - blockStateInitTimer = metrics.NewRegisteredCounter("chain/block/inits/state", nil) - blockExecutionTimer = metrics.NewRegisteredCounter("chain/block/executions", nil) - blockTrieOpsTimer = metrics.NewRegisteredCounter("chain/block/trie", nil) - blockValidationTimer = metrics.NewRegisteredCounter("chain/block/validations/state", nil) - blockWriteTimer = metrics.NewRegisteredCounter("chain/block/writes", nil) - - acceptorQueueGauge = metrics.NewRegisteredGauge("chain/acceptor/queue/size", nil) - acceptorWorkTimer = metrics.NewRegisteredCounter("chain/acceptor/work", nil) - acceptorWorkCount = metrics.NewRegisteredCounter("chain/acceptor/work/count", nil) - processedBlockGasUsedCounter = metrics.NewRegisteredCounter("chain/block/gas/used/processed", nil) - acceptedBlockGasUsedCounter = metrics.NewRegisteredCounter("chain/block/gas/used/accepted", nil) - badBlockCounter = metrics.NewRegisteredCounter("chain/block/bad/count", nil) - - txUnindexTimer = metrics.NewRegisteredCounter("chain/txs/unindex", nil) - acceptedTxsCounter = metrics.NewRegisteredCounter("chain/txs/accepted", nil) - processedTxsCounter = metrics.NewRegisteredCounter("chain/txs/processed", nil) - - acceptedLogsCounter = metrics.NewRegisteredCounter("chain/logs/accepted", nil) - processedLogsCounter = metrics.NewRegisteredCounter("chain/logs/processed", nil) + accountReadTimer = getOrOverrideAsRegisteredCounter("chain/account/reads", nil) + accountHashTimer = getOrOverrideAsRegisteredCounter("chain/account/hashes", nil) + accountUpdateTimer = getOrOverrideAsRegisteredCounter("chain/account/updates", nil) + accountCommitTimer = getOrOverrideAsRegisteredCounter("chain/account/commits", nil) + storageReadTimer = getOrOverrideAsRegisteredCounter("chain/storage/reads", nil) + storageHashTimer = getOrOverrideAsRegisteredCounter("chain/storage/hashes", nil) + storageUpdateTimer = getOrOverrideAsRegisteredCounter("chain/storage/updates", nil) + storageCommitTimer = getOrOverrideAsRegisteredCounter("chain/storage/commits", nil) + snapshotAccountReadTimer = getOrOverrideAsRegisteredCounter("chain/snapshot/account/reads", nil) + snapshotStorageReadTimer = getOrOverrideAsRegisteredCounter("chain/snapshot/storage/reads", nil) + snapshotCommitTimer = getOrOverrideAsRegisteredCounter("chain/snapshot/commits", nil) + + triedbCommitTimer = getOrOverrideAsRegisteredCounter("chain/triedb/commits", nil) + + blockInsertTimer = metrics.GetOrRegisterCounter("chain/block/inserts", nil) + blockInsertCount = metrics.GetOrRegisterCounter("chain/block/inserts/count", nil) + blockContentValidationTimer = metrics.GetOrRegisterCounter("chain/block/validations/content", nil) + blockStateInitTimer = metrics.GetOrRegisterCounter("chain/block/inits/state", nil) + blockExecutionTimer = metrics.GetOrRegisterCounter("chain/block/executions", nil) + blockTrieOpsTimer = metrics.GetOrRegisterCounter("chain/block/trie", nil) + blockValidationTimer = metrics.GetOrRegisterCounter("chain/block/validations/state", nil) + blockWriteTimer = metrics.GetOrRegisterCounter("chain/block/writes", nil) + + acceptorQueueGauge = metrics.GetOrRegisterGauge("chain/acceptor/queue/size", nil) + acceptorWorkTimer = metrics.GetOrRegisterCounter("chain/acceptor/work", nil) + acceptorWorkCount = metrics.GetOrRegisterCounter("chain/acceptor/work/count", nil) + processedBlockGasUsedCounter = metrics.GetOrRegisterCounter("chain/block/gas/used/processed", nil) + acceptedBlockGasUsedCounter = metrics.GetOrRegisterCounter("chain/block/gas/used/accepted", nil) + badBlockCounter = metrics.GetOrRegisterCounter("chain/block/bad/count", nil) + + txUnindexTimer = metrics.GetOrRegisterCounter("chain/txs/unindex", nil) + acceptedTxsCounter = metrics.GetOrRegisterCounter("chain/txs/accepted", nil) + processedTxsCounter = metrics.GetOrRegisterCounter("chain/txs/processed", nil) + + acceptedLogsCounter = metrics.GetOrRegisterCounter("chain/logs/accepted", nil) + processedLogsCounter = metrics.GetOrRegisterCounter("chain/logs/processed", nil) ErrRefuseToCorruptArchiver = errors.New("node has operated with pruning disabled, shutting down to prevent missing tries") @@ -178,18 +194,18 @@ type CacheConfig struct { func (c *CacheConfig) triedbConfig() *triedb.Config { config := &triedb.Config{Preimages: c.Preimages} if c.StateScheme == rawdb.HashScheme || c.StateScheme == "" { - config.HashDB = &hashdb.Config{ + config.DBOverride = hashdb.Config{ CleanCacheSize: c.TrieCleanLimit * 1024 * 1024, StatsPrefix: trieCleanCacheStatsNamespace, ReferenceRootAtomicallyOnUpdate: true, - } + }.BackendConstructor } if c.StateScheme == rawdb.PathScheme { - config.PathDB = &pathdb.Config{ + config.DBOverride = pathdb.Config{ StateHistory: c.StateHistory, CleanCacheSize: c.TrieCleanLimit * 1024 * 1024, DirtyCacheSize: c.TrieDirtyLimit * 1024 * 1024, - } + }.BackendConstructor } return config } @@ -436,7 +452,7 @@ func NewBlockChain( // if txlookup limit is 0 (uindexing disabled), we don't need to repair the tx index tail. if bc.cacheConfig.TransactionHistory != 0 { - latestStateSynced := rawdb.GetLatestSyncPerformed(bc.db) + latestStateSynced := customrawdb.GetLatestSyncPerformed(bc.db) bc.repairTxIndexTail(latestStateSynced) } @@ -469,7 +485,7 @@ func (bc *BlockChain) batchBlockAcceptedIndices(batch ethdb.Batch, b *types.Bloc if !bc.cacheConfig.SkipTxIndexing { rawdb.WriteTxLookupEntriesByBlock(batch, b) } - if err := rawdb.WriteAcceptorTip(batch, b.Hash()); err != nil { + if err := customrawdb.WriteAcceptorTip(batch, b.Hash()); err != nil { return fmt.Errorf("%w: failed to write acceptor tip key", err) } return nil @@ -572,7 +588,7 @@ func (bc *BlockChain) startAcceptor() { bc.acceptorTipLock.Unlock() // Update accepted feeds - flattenedLogs := types.FlattenLogs(logs) + flattenedLogs := customtypes.FlattenLogs(logs) bc.chainAcceptedFeed.Send(ChainEvent{Block: next, Hash: next.Hash(), Logs: flattenedLogs}) if len(flattenedLogs) > 0 { bc.logsAcceptedFeed.Send(flattenedLogs) @@ -1126,8 +1142,8 @@ func (bc *BlockChain) newTip(block *types.Block) bool { // canonical chain. // writeBlockAndSetHead expects to be the last verification step during InsertBlock // since it creates a reference that will only be cleaned up by Accept/Reject. -func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB) error { - if err := bc.writeBlockWithState(block, receipts, state); err != nil { +func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, parentRoot common.Hash, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB) error { + if err := bc.writeBlockWithState(block, parentRoot, receipts, state); err != nil { return err } @@ -1144,7 +1160,7 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types // writeBlockWithState writes the block and all associated state to the database, // but it expects the chain mutex to be held. -func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.Receipt, state *state.StateDB) error { +func (bc *BlockChain) writeBlockWithState(block *types.Block, parentRoot common.Hash, receipts []*types.Receipt, state *state.StateDB) error { // Irrelevant of the canonical status, write the block itself to the database. // // Note all the components of block(hash->number map, header, body, receipts) @@ -1158,14 +1174,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. } // Commit all cached state changes into underlying memory database. - // If snapshots are enabled, call CommitWithSnaps to explicitly create a snapshot - // diff layer for the block. - var err error - if bc.snaps == nil { - _, err = state.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number())) - } else { - _, err = state.CommitWithSnap(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number()), bc.snaps, block.Hash(), block.ParentHash()) - } + _, err := bc.commitWithSnap(block, parentRoot, state) if err != nil { return err } @@ -1358,7 +1367,7 @@ func (bc *BlockChain) insertBlock(block *types.Block, writes bool) error { // will be cleaned up in Accept/Reject so we need to ensure an error cannot occur // later in verification, since that would cause the referenced root to never be dereferenced. wstart := time.Now() - if err := bc.writeBlockAndSetHead(block, receipts, logs, statedb); err != nil { + if err := bc.writeBlockAndSetHead(block, parent.Root, receipts, logs, statedb); err != nil { return err } // Update the metrics touched during block commit @@ -1373,7 +1382,7 @@ func (bc *BlockChain) insertBlock(block *types.Block, writes bool) error { "parentHash", block.ParentHash(), "uncles", len(block.Uncles()), "txs", len(block.Transactions()), "gas", block.GasUsed(), "elapsed", common.PrettyDuration(time.Since(start)), - "root", block.Root(), "baseFeePerGas", block.BaseFee(), "blockGasCost", block.BlockGasCost(), + "root", block.Root(), "baseFeePerGas", block.BaseFee(), "blockGasCost", customtypes.BlockGasCost(block), ) processedBlockGasUsedCounter.Inc(int64(block.GasUsed())) @@ -1416,7 +1425,7 @@ func (bc *BlockChain) collectUnflattenedLogs(b *types.Block, removed bool) [][]* // the processing of a block. These logs are later announced as deleted or reborn. func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log { unflattenedLogs := bc.collectUnflattenedLogs(b, removed) - return types.FlattenLogs(unflattenedLogs) + return customtypes.FlattenLogs(unflattenedLogs) } // reorg takes two blocks, an old chain and a new chain and will reconstruct the @@ -1658,7 +1667,7 @@ func (bc *BlockChain) reprocessBlock(parent *types.Block, current *types.Block) if snap == nil { return common.Hash{}, fmt.Errorf("failed to get snapshot for parent root: %s", parentRoot) } - statedb, err = state.NewWithSnapshot(parentRoot, bc.stateCache, snap) + statedb, err = state.New(parentRoot, bc.stateCache, bc.snaps) } if err != nil { return common.Hash{}, fmt.Errorf("could not fetch state for (%s: %d): %v", parent.Hash().Hex(), parent.NumberU64(), err) @@ -1681,12 +1690,28 @@ func (bc *BlockChain) reprocessBlock(parent *types.Block, current *types.Block) log.Debug("Processed block", "block", current.Hash(), "number", current.NumberU64()) // Commit all cached state changes into underlying memory database. - // If snapshots are enabled, call CommitWithSnaps to explicitly create a snapshot - // diff layer for the block. - if bc.snaps == nil { - return statedb.Commit(current.NumberU64(), bc.chainConfig.IsEIP158(current.Number())) + return bc.commitWithSnap(current, parentRoot, statedb) +} + +func (bc *BlockChain) commitWithSnap( + current *types.Block, parentRoot common.Hash, statedb *state.StateDB, +) (common.Hash, error) { + // blockHashes must be passed through [state.StateDB]'s Commit since snapshots + // are based on the block hash. + blockHashes := snapshot.WithBlockHashes(current.Hash(), current.ParentHash()) + root, err := statedb.Commit(current.NumberU64(), bc.chainConfig.IsEIP158(current.Number()), blockHashes) + if err != nil { + return common.Hash{}, err + } + // Upstream does not perform a snapshot update if the root is the same as the + // parent root, however here the snapshots are based on the block hash, so + // this update is necessary. Note blockHashes are passed here as well. + if bc.snaps != nil && root == parentRoot { + if err := bc.snaps.Update(root, parentRoot, nil, nil, nil, blockHashes); err != nil { + return common.Hash{}, err + } } - return statedb.CommitWithSnap(current.NumberU64(), bc.chainConfig.IsEIP158(current.Number()), bc.snaps, current.Hash(), current.ParentHash()) + return root, nil } // initSnapshot instantiates a Snapshot instance and adds it to [bc] @@ -1723,7 +1748,7 @@ func (bc *BlockChain) initSnapshot(b *types.Header) { // state that reprocessing will start from. func (bc *BlockChain) reprocessState(current *types.Block, reexec uint64) error { origin := current.NumberU64() - acceptorTip, err := rawdb.ReadAcceptorTip(bc.db) + acceptorTip, err := customrawdb.ReadAcceptorTip(bc.db) if err != nil { return fmt.Errorf("%w: unable to get Acceptor tip", err) } @@ -1854,9 +1879,9 @@ func (bc *BlockChain) reprocessState(current *types.Block, reexec uint64) error func (bc *BlockChain) protectTrieIndex() error { if !bc.cacheConfig.Pruning { - return rawdb.WritePruningDisabled(bc.db) + return customrawdb.WritePruningDisabled(bc.db) } - pruningDisabled, err := rawdb.HasPruningDisabled(bc.db) + pruningDisabled, err := customrawdb.HasPruningDisabled(bc.db) if err != nil { return fmt.Errorf("failed to check if the chain has been run with pruning disabled: %w", err) } @@ -1941,7 +1966,7 @@ func (bc *BlockChain) populateMissingTries() error { // Write marker to DB to indicate populate missing tries finished successfully. // Note: writing the marker here means that we do allow consecutive runs of re-populating // missing tries if it does not finish during the prior run. - if err := rawdb.WritePopulateMissingTries(bc.db); err != nil { + if err := customrawdb.WritePopulateMissingTries(bc.db); err != nil { return fmt.Errorf("failed to write offline pruning success marker: %w", err) } @@ -2039,9 +2064,9 @@ func (bc *BlockChain) ResetToStateSyncedBlock(block *types.Block) error { } rawdb.WriteHeadBlockHash(batch, block.Hash()) rawdb.WriteHeadHeaderHash(batch, block.Hash()) - rawdb.WriteSnapshotBlockHash(batch, block.Hash()) + customrawdb.WriteSnapshotBlockHash(batch, block.Hash()) rawdb.WriteSnapshotRoot(batch, block.Root()) - if err := rawdb.WriteSyncPerformed(batch, block.NumberU64()); err != nil { + if err := customrawdb.WriteSyncPerformed(batch, block.NumberU64()); err != nil { return err } diff --git a/core/blockchain_ext.go b/core/blockchain_ext.go new file mode 100644 index 0000000000..875f9b8296 --- /dev/null +++ b/core/blockchain_ext.go @@ -0,0 +1,26 @@ +// (c) 2024 Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. +package core + +import "github.com/ava-labs/libevm/metrics" + +// getOrOverrideAsRegisteredCounter searches for a metric already registered +// with `name`. If a metric is found and it is a [metrics.Counter], it is returned. If a +// metric is found and it is not a [metrics.Counter], it is unregistered and replaced with +// a new registered [metrics.Counter]. If no metric is found, a new [metrics.Counter] is constructed +// and registered. +// +// This is necessary for a metric defined in libevm with the same name but a +// different type to what we expect. +func getOrOverrideAsRegisteredCounter(name string, r metrics.Registry) metrics.Counter { + if r == nil { + r = metrics.DefaultRegistry + } + + if c, ok := r.GetOrRegister(name, metrics.NewCounter).(metrics.Counter); ok { + return c + } + // `name` must have already been registered to be any other type + r.Unregister(name) + return metrics.NewRegisteredCounter(name, r) +} diff --git a/core/blockchain_iterator.go b/core/blockchain_iterator.go index e81d4a5761..e453720c7b 100644 --- a/core/blockchain_iterator.go +++ b/core/blockchain_iterator.go @@ -33,7 +33,7 @@ import ( "fmt" "sync" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" ) type blockAndState struct { diff --git a/core/blockchain_log_test.go b/core/blockchain_log_test.go index 662376d946..dcda9349f7 100644 --- a/core/blockchain_log_test.go +++ b/core/blockchain_log_test.go @@ -10,13 +10,13 @@ import ( "github.com/ava-labs/coreth/accounts/abi" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" ) diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 8f73445f43..c01660192d 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -28,15 +28,15 @@ package core import ( "github.com/ava-labs/coreth/consensus" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/triedb" ) // CurrentHeader retrieves the current head header of the canonical chain. The diff --git a/core/blockchain_repair_test.go b/core/blockchain_repair_test.go index 86c5b4f384..202f8e9fc8 100644 --- a/core/blockchain_repair_test.go +++ b/core/blockchain_repair_test.go @@ -35,14 +35,14 @@ import ( "testing" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/triedb" "github.com/stretchr/testify/require" ) diff --git a/core/blockchain_sethead_test.go b/core/blockchain_sethead_test.go index 6695ea0464..9bf245b092 100644 --- a/core/blockchain_sethead_test.go +++ b/core/blockchain_sethead_test.go @@ -32,7 +32,7 @@ package core import ( "testing" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" ) // verifyNoGaps checks that there are no gaps after the initial set of blocks in diff --git a/core/blockchain_snapshot_test.go b/core/blockchain_snapshot_test.go index 569954617d..30a0516002 100644 --- a/core/blockchain_snapshot_test.go +++ b/core/blockchain_snapshot_test.go @@ -40,13 +40,13 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/ethdb" ) // snapshotTestBasic wraps the common testing fields in the snapshot tests. diff --git a/core/blockchain_test.go b/core/blockchain_test.go index 74ddb87ec4..6565da75e1 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -11,17 +11,18 @@ import ( "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/state/pruner" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers/logger" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/eth/tracers/logger" + "github.com/ava-labs/libevm/ethdb" "github.com/holiman/uint256" ) @@ -238,7 +239,7 @@ func TestCorruptSnapshots(t *testing.T) { create := func(db ethdb.Database, gspec *Genesis, lastAcceptedHash common.Hash) (*BlockChain, error) { // Delete the snapshot block hash and state root to ensure that if we die in between writing a snapshot // diff layer to disk at any point, we can still recover on restart. - rawdb.DeleteSnapshotBlockHash(db) + customrawdb.DeleteSnapshotBlockHash(db) rawdb.DeleteSnapshotRoot(db) return createBlockChain(db, pruningConfig, gspec, lastAcceptedHash) diff --git a/core/bloom_indexer.go b/core/bloom_indexer.go index ab8bc706f1..16e78ec83c 100644 --- a/core/bloom_indexer.go +++ b/core/bloom_indexer.go @@ -21,11 +21,11 @@ import ( "time" "github.com/ava-labs/coreth/core/bloombits" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/bitutil" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/bitutil" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" ) const ( diff --git a/core/bloombits/generator.go b/core/bloombits/generator.go index c0422caad5..9acabe35b8 100644 --- a/core/bloombits/generator.go +++ b/core/bloombits/generator.go @@ -29,7 +29,7 @@ package bloombits import ( "errors" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" ) var ( diff --git a/core/bloombits/generator_test.go b/core/bloombits/generator_test.go index 40a4749c15..c07a5d2b9c 100644 --- a/core/bloombits/generator_test.go +++ b/core/bloombits/generator_test.go @@ -32,7 +32,7 @@ import ( "math/rand" "testing" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" ) // Tests that batched bloom bits are correctly rotated from the input bloom diff --git a/core/bloombits/matcher.go b/core/bloombits/matcher.go index 532bc7af93..94bbb59c6b 100644 --- a/core/bloombits/matcher.go +++ b/core/bloombits/matcher.go @@ -36,8 +36,8 @@ import ( "sync/atomic" "time" - "github.com/ethereum/go-ethereum/common/bitutil" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common/bitutil" + "github.com/ava-labs/libevm/crypto" ) // bloomIndexes represents the bit indexes inside the bloom filter that belong diff --git a/core/bloombits/matcher_test.go b/core/bloombits/matcher_test.go index c095ec31e4..04318f3489 100644 --- a/core/bloombits/matcher_test.go +++ b/core/bloombits/matcher_test.go @@ -33,7 +33,7 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) const testSectionSize = 4096 diff --git a/core/chain_indexer.go b/core/chain_indexer.go index 05cbc54c76..1dd532f885 100644 --- a/core/chain_indexer.go +++ b/core/chain_indexer.go @@ -35,12 +35,12 @@ import ( "sync/atomic" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" ) // ChainIndexerBackend defines the methods needed to process chain segments in diff --git a/core/chain_indexer_test.go b/core/chain_indexer_test.go index 3edf175d3d..97d7f479ec 100644 --- a/core/chain_indexer_test.go +++ b/core/chain_indexer_test.go @@ -35,9 +35,9 @@ import ( "testing" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" ) // Runs multiple tests with randomized parameters. diff --git a/core/chain_makers.go b/core/chain_makers.go index 4883361b91..f2fa1e9ee7 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -32,15 +32,15 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/misc/eip4844" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/header" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/triedb" "github.com/holiman/uint256" ) @@ -373,11 +373,12 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, func (cm *chainMaker) makeHeader(parent *types.Block, gap uint64, state *state.StateDB, engine consensus.Engine) *types.Header { time := parent.Time() + gap // block time is fixed at [gap] seconds - gasLimit, err := header.GasLimit(cm.config, parent.Header(), time) + config := params.GetExtra(cm.config) + gasLimit, err := header.GasLimit(config, parent.Header(), time) if err != nil { panic(err) } - baseFee, err := header.BaseFee(cm.config, parent.Header(), time) + baseFee, err := header.BaseFee(config, parent.Header(), time) if err != nil { panic(err) } diff --git a/core/chain_makers_test.go b/core/chain_makers_test.go index 34c53bd7f1..695ae96d25 100644 --- a/core/chain_makers_test.go +++ b/core/chain_makers_test.go @@ -31,13 +31,13 @@ import ( "math/big" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/triedb" ) func ExampleGenerateChain() { diff --git a/core/error.go b/core/error.go index e00fbd83f7..e321e07d69 100644 --- a/core/error.go +++ b/core/error.go @@ -29,7 +29,7 @@ package core import ( "errors" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" ) var ( diff --git a/core/events.go b/core/events.go index 462d26d9ee..90345c67de 100644 --- a/core/events.go +++ b/core/events.go @@ -27,8 +27,8 @@ package core import ( - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // NewTxsEvent is posted when a batch of transactions enter the transaction pool. diff --git a/core/evm.go b/core/evm.go index 6e537fd334..d42e47422f 100644 --- a/core/evm.go +++ b/core/evm.go @@ -27,17 +27,70 @@ package core import ( + "bytes" "math/big" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/misc/eip4844" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/predicate" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/coreth/core/extstate" + "github.com/ava-labs/coreth/core/state" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + customheader "github.com/ava-labs/coreth/plugin/evm/header" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" "github.com/holiman/uint256" ) +func init() { + vm.RegisterHooks(hooks{}) +} + +type hooks struct{} + +// OverrideNewEVMArgs is a hook that is called in [vm.NewEVM]. +// It allows for the modification of the EVM arguments before the EVM is created. +// Specifically, we set Random to be the same as Difficulty since Shanghai. +// This allows using the same jump table as upstream. +// Then we set Difficulty to 0 as it is post Merge in upstream. +// Additionally we wrap the StateDB with the appropriate StateDB wrapper, +// which is used in coreth to process historical pre-AP1 blocks with the +// [StateDbAP1.GetCommittedState] method as it was historically. +func (hooks) OverrideNewEVMArgs(args *vm.NewEVMArgs) *vm.NewEVMArgs { + rules := args.ChainConfig.Rules(args.BlockContext.BlockNumber, params.IsMergeTODO, args.BlockContext.Time) + args.StateDB = wrapStateDB(rules, args.StateDB) + + if rules.IsShanghai { + args.BlockContext.Random = new(common.Hash) + args.BlockContext.Random.SetBytes(args.BlockContext.Difficulty.Bytes()) + args.BlockContext.Difficulty = new(big.Int) + } + + return args +} + +func (hooks) OverrideEVMResetArgs(rules params.Rules, args *vm.EVMResetArgs) *vm.EVMResetArgs { + args.StateDB = wrapStateDB(rules, args.StateDB) + return args +} + +func wrapStateDB(rules params.Rules, db vm.StateDB) vm.StateDB { + if params.GetRulesExtra(rules).IsApricotPhase1 { + db = &StateDbAP1{db.(extstate.VmStateDB)} + } + return extstate.New(db.(extstate.VmStateDB)) +} + +type StateDbAP1 struct { + extstate.VmStateDB +} + +func (s *StateDbAP1) GetCommittedState(addr common.Address, key common.Hash) common.Hash { + state.NormalizeStateKey(&key) + return s.VmStateDB.GetCommittedState(addr, key) +} + // ChainContext supports retrieving headers and consensus parameters from the // current blockchain to be used during transaction processing. type ChainContext interface { @@ -69,30 +122,37 @@ func NewEVMBlockContext(header *types.Header, chain ChainContext, author *common blobBaseFee = eip4844.CalcBlobFee(*header.ExcessBlobGas) } return vm.BlockContext{ - CanTransfer: CanTransfer, - CanTransferMC: CanTransferMC, - Transfer: Transfer, - TransferMultiCoin: TransferMultiCoin, - GetHash: GetHashFn(header, chain), - Extra: header.Extra, - Coinbase: beneficiary, - BlockNumber: new(big.Int).Set(header.Number), - Time: header.Time, - Difficulty: new(big.Int).Set(header.Difficulty), - BaseFee: baseFee, - BlobBaseFee: blobBaseFee, - GasLimit: header.GasLimit, + CanTransfer: CanTransfer, + Transfer: Transfer, + GetHash: GetHashFn(header, chain), + Coinbase: beneficiary, + BlockNumber: new(big.Int).Set(header.Number), + Time: header.Time, + Difficulty: new(big.Int).Set(header.Difficulty), + BaseFee: baseFee, + BlobBaseFee: blobBaseFee, + GasLimit: header.GasLimit, + Header: &types.Header{ + Number: new(big.Int).Set(header.Number), + Time: header.Time, + Extra: header.Extra, + }, } } -// NewEVMBlockContextWithPredicateResults creates a new context for use in the EVM with an override for the predicate results that is not present -// in header.Extra. -// This function is used to create a BlockContext when the header Extra data is not fully formed yet and it's more efficient to pass in predicateResults -// directly rather than re-encode the latest results when executing each individaul transaction. -func NewEVMBlockContextWithPredicateResults(header *types.Header, chain ChainContext, author *common.Address, predicateResults *predicate.Results) vm.BlockContext { - blockContext := NewEVMBlockContext(header, chain, author) - blockContext.PredicateResults = predicateResults - return blockContext +// NewEVMBlockContextWithPredicateResults creates a new context for use in the +// EVM with an override for the predicate results. The miner uses this to pass +// predicate results to the EVM when header.Extra is not fully formed yet. +func NewEVMBlockContextWithPredicateResults(rules extras.AvalancheRules, header *types.Header, chain ChainContext, author *common.Address, predicateBytes []byte) vm.BlockContext { + blockCtx := NewEVMBlockContext(header, chain, author) + // Note this only sets the block context, which is the hand-off point for + // the EVM. The actual header is not modified. + blockCtx.Header.Extra = customheader.SetPredicateBytesInExtra( + rules, + bytes.Clone(header.Extra), + predicateBytes, + ) + return blockCtx } // NewEVMTxContext creates a new transaction context for a single transaction. @@ -153,18 +213,8 @@ func CanTransfer(db vm.StateDB, addr common.Address, amount *uint256.Int) bool { return db.GetBalance(addr).Cmp(amount) >= 0 } -func CanTransferMC(db vm.StateDB, addr common.Address, to common.Address, coinID common.Hash, amount *big.Int) bool { - return db.GetBalanceMultiCoin(addr, coinID).Cmp(amount) >= 0 -} - // Transfer subtracts amount from sender and adds amount to recipient using the given Db func Transfer(db vm.StateDB, sender, recipient common.Address, amount *uint256.Int) { db.SubBalance(sender, amount) db.AddBalance(recipient, amount) } - -// Transfer subtracts amount from sender and adds amount to recipient using the given Db -func TransferMultiCoin(db vm.StateDB, sender, recipient common.Address, coinID common.Hash, amount *big.Int) { - db.SubBalanceMultiCoin(sender, coinID, amount) - db.AddBalanceMultiCoin(recipient, coinID, amount) -} diff --git a/core/extstate/statedb.go b/core/extstate/statedb.go new file mode 100644 index 0000000000..2ee0d6bbdc --- /dev/null +++ b/core/extstate/statedb.go @@ -0,0 +1,81 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package extstate + +import ( + "math/big" + + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/predicate" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" +) + +type VmStateDB interface { + vm.StateDB + Logs() []*types.Log + GetTxHash() common.Hash + GetBalanceMultiCoin(common.Address, common.Hash) *big.Int + AddBalanceMultiCoin(common.Address, common.Hash, *big.Int) + SubBalanceMultiCoin(common.Address, common.Hash, *big.Int) +} + +type vmStateDB = VmStateDB + +type StateDB struct { + vmStateDB + + // Ordered storage slots to be used in predicate verification as set in the tx access list. + // Only set in [StateDB.Prepare], and un-modified through execution. + predicateStorageSlots map[common.Address][][]byte +} + +// New creates a new [*StateDB] with the given [VmStateDB], effectively wrapping it +// with additional functionality. +func New(vm VmStateDB) *StateDB { + return &StateDB{ + vmStateDB: vm, + predicateStorageSlots: make(map[common.Address][][]byte), + } +} + +func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) { + rulesExtra := params.GetRulesExtra(rules) + s.predicateStorageSlots = predicate.PreparePredicateStorageSlots(rulesExtra, list) + s.vmStateDB.Prepare(rules, sender, coinbase, dst, precompiles, list) +} + +// GetLogData returns the underlying topics and data from each log included in the [StateDB]. +// Test helper function. +func (s *StateDB) GetLogData() (topics [][]common.Hash, data [][]byte) { + for _, log := range s.Logs() { + topics = append(topics, log.Topics) + data = append(data, common.CopyBytes(log.Data)) + } + return topics, data +} + +// GetPredicateStorageSlots returns the storage slots associated with the address, index pair. +// A list of access tuples can be included within transaction types post EIP-2930. The address +// is declared directly on the access tuple and the index is the i'th occurrence of an access +// tuple with the specified address. +// +// Ex. AccessList[[AddrA, Predicate1], [AddrB, Predicate2], [AddrA, Predicate3]] +// In this case, the caller could retrieve predicates 1-3 with the following calls: +// GetPredicateStorageSlots(AddrA, 0) -> Predicate1 +// GetPredicateStorageSlots(AddrB, 0) -> Predicate2 +// GetPredicateStorageSlots(AddrA, 1) -> Predicate3 +func (s *StateDB) GetPredicateStorageSlots(address common.Address, index int) ([]byte, bool) { + predicates, exists := s.predicateStorageSlots[address] + if !exists || index >= len(predicates) { + return nil, false + } + return predicates[index], true +} + +// SetPredicateStorageSlots sets the predicate storage slots for the given address +func (s *StateDB) SetPredicateStorageSlots(address common.Address, predicates [][]byte) { + s.predicateStorageSlots[address] = predicates +} diff --git a/core/state/test_statedb.go b/core/extstate/test_statedb.go similarity index 58% rename from core/state/test_statedb.go rename to core/extstate/test_statedb.go index dc4d0e582d..903480dfe0 100644 --- a/core/state/test_statedb.go +++ b/core/extstate/test_statedb.go @@ -1,19 +1,20 @@ // (c) 2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package state +package extstate import ( "testing" - "github.com/ava-labs/coreth/core/rawdb" + "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/precompile/contract" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" "github.com/stretchr/testify/require" ) func NewTestStateDB(t testing.TB) contract.StateDB { db := rawdb.NewMemoryDatabase() - stateDB, err := New(common.Hash{}, NewDatabase(db), nil) + statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil) require.NoError(t, err) - return stateDB + return New(statedb) } diff --git a/core/gen_genesis.go b/core/gen_genesis.go index 1112a6bab6..553a499a24 100644 --- a/core/gen_genesis.go +++ b/core/gen_genesis.go @@ -7,11 +7,11 @@ import ( "errors" "math/big" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/types" ) var _ = (*genesisSpecMarshaling)(nil) @@ -19,21 +19,21 @@ var _ = (*genesisSpecMarshaling)(nil) // MarshalJSON marshals as JSON. func (g Genesis) MarshalJSON() ([]byte, error) { type Genesis struct { - Config *params.ChainConfig `json:"config"` - Nonce math.HexOrDecimal64 `json:"nonce"` - Timestamp math.HexOrDecimal64 `json:"timestamp"` - ExtraData hexutil.Bytes `json:"extraData"` - GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash common.Hash `json:"mixHash"` - Coinbase common.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]types.GenesisAccount `json:"alloc" gencodec:"required"` - Number math.HexOrDecimal64 `json:"number"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` - ParentHash common.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` - ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` - BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` + Config *params.ChainConfig `json:"config"` + Nonce math.HexOrDecimal64 `json:"nonce"` + Timestamp math.HexOrDecimal64 `json:"timestamp"` + ExtraData hexutil.Bytes `json:"extraData"` + GasLimit math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash common.Hash `json:"mixHash"` + Coinbase common.Address `json:"coinbase"` + Alloc map[common.UnprefixedAddress]types.Account `json:"alloc" gencodec:"required"` + Number math.HexOrDecimal64 `json:"number"` + GasUsed math.HexOrDecimal64 `json:"gasUsed"` + ParentHash common.Hash `json:"parentHash"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` + BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` } var enc Genesis enc.Config = g.Config @@ -45,7 +45,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) { enc.Mixhash = g.Mixhash enc.Coinbase = g.Coinbase if g.Alloc != nil { - enc.Alloc = make(map[common.UnprefixedAddress]types.GenesisAccount, len(g.Alloc)) + enc.Alloc = make(map[common.UnprefixedAddress]types.Account, len(g.Alloc)) for k, v := range g.Alloc { enc.Alloc[common.UnprefixedAddress(k)] = v } @@ -62,21 +62,21 @@ func (g Genesis) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (g *Genesis) UnmarshalJSON(input []byte) error { type Genesis struct { - Config *params.ChainConfig `json:"config"` - Nonce *math.HexOrDecimal64 `json:"nonce"` - Timestamp *math.HexOrDecimal64 `json:"timestamp"` - ExtraData *hexutil.Bytes `json:"extraData"` - GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` - Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` - Mixhash *common.Hash `json:"mixHash"` - Coinbase *common.Address `json:"coinbase"` - Alloc map[common.UnprefixedAddress]types.GenesisAccount `json:"alloc" gencodec:"required"` - Number *math.HexOrDecimal64 `json:"number"` - GasUsed *math.HexOrDecimal64 `json:"gasUsed"` - ParentHash *common.Hash `json:"parentHash"` - BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` - ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` - BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` + Config *params.ChainConfig `json:"config"` + Nonce *math.HexOrDecimal64 `json:"nonce"` + Timestamp *math.HexOrDecimal64 `json:"timestamp"` + ExtraData *hexutil.Bytes `json:"extraData"` + GasLimit *math.HexOrDecimal64 `json:"gasLimit" gencodec:"required"` + Difficulty *math.HexOrDecimal256 `json:"difficulty" gencodec:"required"` + Mixhash *common.Hash `json:"mixHash"` + Coinbase *common.Address `json:"coinbase"` + Alloc map[common.UnprefixedAddress]types.Account `json:"alloc" gencodec:"required"` + Number *math.HexOrDecimal64 `json:"number"` + GasUsed *math.HexOrDecimal64 `json:"gasUsed"` + ParentHash *common.Hash `json:"parentHash"` + BaseFee *math.HexOrDecimal256 `json:"baseFeePerGas"` + ExcessBlobGas *math.HexOrDecimal64 `json:"excessBlobGas"` + BlobGasUsed *math.HexOrDecimal64 `json:"blobGasUsed"` } var dec Genesis if err := json.Unmarshal(input, &dec); err != nil { diff --git a/core/genesis.go b/core/genesis.go index 1fb1854c1c..37c0405267 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -33,19 +33,19 @@ import ( "fmt" "math/big" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/triedb/pathdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" "github.com/holiman/uint256" ) @@ -53,8 +53,8 @@ import ( var errGenesisNoConfig = errors.New("genesis has no chain configuration") -// Deprecated: use types.GenesisAccount instead. -type GenesisAccount = types.GenesisAccount +// Deprecated: use types.Account instead. +type GenesisAccount = types.Account // Deprecated: use types.GenesisAlloc instead. type GenesisAlloc = types.GenesisAlloc @@ -172,7 +172,7 @@ func SetupGenesisBlock( rawdb.WriteChainConfig(db, stored, newcfg) return newcfg, stored, nil } - storedcfg.SetEthUpgrades() + params.SetEthUpgrades(storedcfg) storedData, _ := json.Marshal(storedcfg) // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. @@ -220,8 +220,8 @@ func (g *Genesis) trieConfig() *triedb.Config { return nil } return &triedb.Config{ - PathDB: pathdb.Defaults, - IsVerkle: true, + DBOverride: pathdb.Defaults.BackendConstructor, + IsVerkle: true, } } @@ -247,7 +247,8 @@ func (g *Genesis) toBlock(db ethdb.Database, triedb *triedb.Database) *types.Blo } // Configure any stateful precompiles that should be enabled in the genesis. - err = ApplyPrecompileActivations(g.Config, nil, types.NewBlockWithHeader(head), statedb) + blockContext := NewBlockContext(head.Number, head.Time) + err = ApplyPrecompileActivations(g.Config, nil, blockContext, statedb) if err != nil { panic(fmt.Sprintf("unable to configure precompiles in genesis block: %v", err)) } @@ -259,11 +260,6 @@ func (g *Genesis) toBlock(db ethdb.Database, triedb *triedb.Database) *types.Blo for key, value := range account.Storage { statedb.SetState(addr, key, value) } - if account.MCBalance != nil { - for coinID, value := range account.MCBalance { - statedb.AddBalanceMultiCoin(addr, coinID, value) - } - } } root := statedb.IntermediateRoot(false) head.Root = root @@ -276,7 +272,7 @@ func (g *Genesis) toBlock(db ethdb.Database, triedb *triedb.Database) *types.Blo } if conf := g.Config; conf != nil { num := new(big.Int).SetUint64(g.Number) - if conf.IsApricotPhase3(g.Timestamp) { + if params.GetExtra(conf).IsApricotPhase3(g.Timestamp) { if g.BaseFee != nil { head.BaseFee = g.BaseFee } else { diff --git a/core/genesis_extra_test.go b/core/genesis_extra_test.go index 25008653e0..34a14f50d9 100644 --- a/core/genesis_extra_test.go +++ b/core/genesis_extra_test.go @@ -31,35 +31,45 @@ import ( "testing" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/triedb" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/triedb" "github.com/stretchr/testify/require" ) func TestGenesisEthUpgrades(t *testing.T) { db := rawdb.NewMemoryDatabase() - preEthUpgrades := ¶ms.ChainConfig{ - ChainID: big.NewInt(43114), // Specifically refers to mainnet for this UT - HomesteadBlock: big.NewInt(0), - DAOForkBlock: nil, - DAOForkSupport: false, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), + preEthUpgrades := params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(43114), // Specifically refers to mainnet for this UT + HomesteadBlock: big.NewInt(0), + // For this test to be a proper regression test, DAOForkBlock and + // DAOForkSupport should be set to match the values in + // [params.SetEthUpgrades]. Otherwise, in case of a regression, the test + // would pass as there would be a mismatch at genesis, which is + // incorrectly considered a success. + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), }, - } + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + }, + }, + ) tdb := triedb.NewDatabase(db, triedb.HashDefaults) config := *preEthUpgrades @@ -84,7 +94,7 @@ func TestGenesisEthUpgrades(t *testing.T) { // We should still be able to re-initialize config = *preEthUpgrades - config.SetEthUpgrades() // New versions will set additional fields eg, LondonBlock + params.SetEthUpgrades(&config) // New versions will set additional fields eg, LondonBlock _, _, err = SetupGenesisBlock(db, tdb, &Genesis{Config: &config}, block.Hash(), false) require.NoError(t, err) } diff --git a/core/genesis_test.go b/core/genesis_test.go index d9840023b1..cbc2de60c2 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -34,19 +34,21 @@ import ( "testing" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/precompile/contracts/warp" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/triedb/pathdb" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/ethdb" + ethparams "github.com/ava-labs/libevm/params" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" "github.com/stretchr/testify/require" ) @@ -68,8 +70,8 @@ func TestSetupGenesis(t *testing.T) { } func testSetupGenesis(t *testing.T, scheme string) { - apricotPhase1Config := *params.TestApricotPhase1Config - apricotPhase1Config.ApricotPhase1BlockTimestamp = utils.NewUint64(100) + apricotPhase1Config := params.Copy(params.TestApricotPhase1Config) + params.GetExtra(&apricotPhase1Config).ApricotPhase1BlockTimestamp = utils.NewUint64(100) var ( customghash = common.HexToHash("0x1099a11e9e454bd3ef31d688cf21936671966407bc330f051d754b5ce401e7ed") customg = Genesis{ @@ -81,8 +83,8 @@ func testSetupGenesis(t *testing.T, scheme string) { oldcustomg = customg ) - rollbackApricotPhase1Config := apricotPhase1Config - rollbackApricotPhase1Config.ApricotPhase1BlockTimestamp = utils.NewUint64(90) + rollbackApricotPhase1Config := params.Copy(&apricotPhase1Config) + params.GetExtra(&rollbackApricotPhase1Config).ApricotPhase1BlockTimestamp = utils.NewUint64(90) oldcustomg.Config = &rollbackApricotPhase1Config tests := []struct { name string @@ -158,7 +160,7 @@ func testSetupGenesis(t *testing.T, scheme string) { }, wantHash: customghash, wantConfig: customg.Config, - wantErr: ¶ms.ConfigCompatError{ + wantErr: ðparams.ConfigCompatError{ What: "ApricotPhase1 fork block timestamp", StoredTime: u64(90), NewTime: u64(100), @@ -223,8 +225,8 @@ func TestNetworkUpgradeBetweenHeadAndAcceptedBlock(t *testing.T) { activatedGenesis := customg apricotPhase2Timestamp := utils.NewUint64(51) - updatedApricotPhase2Config := *params.TestApricotPhase1Config - updatedApricotPhase2Config.ApricotPhase2BlockTimestamp = apricotPhase2Timestamp + updatedApricotPhase2Config := params.Copy(params.TestApricotPhase1Config) + params.GetExtra(&updatedApricotPhase2Config).ApricotPhase2BlockTimestamp = apricotPhase2Timestamp activatedGenesis.Config = &updatedApricotPhase2Config @@ -243,7 +245,7 @@ func TestNetworkUpgradeBetweenHeadAndAcceptedBlock(t *testing.T) { func TestGenesisWriteUpgradesRegression(t *testing.T) { require := require.New(t) - config := *params.TestChainConfig + config := params.Copy(params.TestChainConfig) genesis := &Genesis{ Config: &config, Alloc: types.GenesisAlloc{ @@ -258,7 +260,7 @@ func TestGenesisWriteUpgradesRegression(t *testing.T) { _, _, err := SetupGenesisBlock(db, trieDB, genesis, genesisBlock.Hash(), false) require.NoError(err) - genesis.Config.UpgradeConfig.PrecompileUpgrades = []params.PrecompileUpgrade{ + params.GetExtra(genesis.Config).UpgradeConfig.PrecompileUpgrades = []extras.PrecompileUpgrade{ { Config: warp.NewConfig(utils.NewUint64(51), 0, false), }, @@ -286,7 +288,7 @@ func newDbConfig(scheme string) *triedb.Config { if scheme == rawdb.HashScheme { return triedb.HashDefaults } - return &triedb.Config{PathDB: pathdb.Defaults} + return &triedb.Config{DBOverride: pathdb.Defaults.BackendConstructor} } func TestVerkleGenesisCommit(t *testing.T) { @@ -326,7 +328,7 @@ func TestVerkleGenesisCommit(t *testing.T) { } db := rawdb.NewMemoryDatabase() - triedb := triedb.NewDatabase(db, &triedb.Config{IsVerkle: true, PathDB: pathdb.Defaults}) + triedb := triedb.NewDatabase(db, &triedb.Config{IsVerkle: true, DBOverride: pathdb.Defaults.BackendConstructor}) block := genesis.MustCommit(db, triedb) if !bytes.Equal(block.Root().Bytes(), expected) { t.Fatalf("invalid genesis state root, expected %x, got %x", expected, got) diff --git a/core/headerchain.go b/core/headerchain.go index fe8f752d41..dda4a6f948 100644 --- a/core/headerchain.go +++ b/core/headerchain.go @@ -34,12 +34,12 @@ import ( "sync/atomic" "github.com/ava-labs/coreth/consensus" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/lru" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" ) const ( diff --git a/core/headerchain_test.go b/core/headerchain_test.go index 24f443202e..b3bc553a9e 100644 --- a/core/headerchain_test.go +++ b/core/headerchain_test.go @@ -34,12 +34,12 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" ) func verifyUnbrokenCanonchain(bc *BlockChain) error { diff --git a/core/main_test.go b/core/main_test.go index 6ea70c4b6c..28812d78a4 100644 --- a/core/main_test.go +++ b/core/main_test.go @@ -15,6 +15,7 @@ func TestMain(m *testing.M) { opts := []goleak.Option{ // No good way to shut down these goroutines: goleak.IgnoreTopFunction("github.com/ava-labs/coreth/core/state/snapshot.(*diskLayer).generate"), + goleak.IgnoreTopFunction("github.com/ava-labs/libevm/core.(*txSenderCacher).cache"), goleak.IgnoreTopFunction("github.com/ava-labs/libevm/metrics.(*meterArbiter).tick"), goleak.IgnoreTopFunction("github.com/syndtr/goleveldb/leveldb.(*DB).mpoolDrain"), } diff --git a/core/mkalloc.go b/core/mkalloc.go index f481249c60..4fd247323e 100644 --- a/core/mkalloc.go +++ b/core/mkalloc.go @@ -43,8 +43,8 @@ import ( "strconv" "github.com/ava-labs/coreth/core" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/rlp" "golang.org/x/exp/slices" ) diff --git a/core/predicate_check.go b/core/predicate_check.go index b4694a251f..ed01e58b8f 100644 --- a/core/predicate_check.go +++ b/core/predicate_check.go @@ -8,12 +8,12 @@ import ( "fmt" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/predicate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/log" ) var ErrMissingPredicateContext = errors.New("missing predicate context") @@ -30,14 +30,15 @@ func CheckPredicates(rules params.Rules, predicateContext *precompileconfig.Pred return nil, fmt.Errorf("%w for predicate verification (%d) < intrinsic gas (%d)", ErrIntrinsicGas, tx.Gas(), intrinsicGas) } + rulesExtra := params.GetRulesExtra(rules) predicateResults := make(map[common.Address][]byte) // Short circuit early if there are no precompile predicates to verify - if !rules.PredicatersExist() { + if !rulesExtra.PredicatersExist() { return predicateResults, nil } // Prepare the predicate storage slots from the transaction's access list - predicateArguments := predicate.PreparePredicateStorageSlots(rules, tx.AccessList()) + predicateArguments := predicate.PreparePredicateStorageSlots(rulesExtra, tx.AccessList()) // If there are no predicates to verify, return early and skip requiring the proposervm block // context to be populated. @@ -52,6 +53,7 @@ func CheckPredicates(rules params.Rules, predicateContext *precompileconfig.Pred for address, predicates := range predicateArguments { // Since [address] is only added to [predicateArguments] when there's a valid predicate in the ruleset // there's no need to check if the predicate exists here. + rules := params.GetRulesExtra(rules) predicaterContract := rules.Predicaters[address] bitset := set.NewBits() for i, predicate := range predicates { diff --git a/core/predicate_check_test.go b/core/predicate_check_test.go index 3c17aac698..9fdb6120f5 100644 --- a/core/predicate_check_test.go +++ b/core/predicate_check_test.go @@ -9,10 +9,10 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/precompile/precompileconfig" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -296,9 +296,10 @@ func TestCheckPredicate(t *testing.T) { t.Run(name, func(t *testing.T) { require := require.New(t) // Create the rules from TestChainConfig and update the predicates based on the test params - rules := params.TestChainConfig.Rules(common.Big0, 0) + rules := params.TestChainConfig.Rules(common.Big0, params.IsMergeTODO, 0) if test.createPredicates != nil { for address, predicater := range test.createPredicates(t) { + rules := params.GetRulesExtra(rules) rules.Predicaters[address] = predicater } } @@ -422,7 +423,7 @@ func TestCheckPredicatesOutput(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) // Create the rules from TestChainConfig and update the predicates based on the test params - rules := params.TestChainConfig.Rules(common.Big0, 0) + rules := params.TestChainConfig.Rules(common.Big0, params.IsMergeTODO, 0) predicater := precompileconfig.NewMockPredicater(gomock.NewController(t)) predicater.EXPECT().PredicateGas(gomock.Any()).Return(uint64(0), nil).Times(len(test.testTuple)) @@ -444,8 +445,9 @@ func TestCheckPredicatesOutput(t *testing.T) { }) } - rules.Predicaters[addr1] = predicater - rules.Predicaters[addr2] = predicater + rulesExtra := params.GetRulesExtra(rules) + rulesExtra.Predicaters[addr1] = predicater + rulesExtra.Predicaters[addr2] = predicater // Specify only the access list, since this test should not depend on any other values tx := types.NewTx(&types.DynamicFeeTx{ diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go deleted file mode 100644 index d63da4782a..0000000000 --- a/core/rawdb/accessors_chain.go +++ /dev/null @@ -1,606 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "bytes" - "encoding/binary" - "errors" - "math/big" - - "github.com/ava-labs/coreth/consensus/misc/eip4844" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" -) - -// ReadCanonicalHash retrieves the hash assigned to a canonical block number. -func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash { - data, _ := db.Get(headerHashKey(number)) - if len(data) == 0 { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// WriteCanonicalHash stores the hash assigned to a canonical block number. -func WriteCanonicalHash(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - if err := db.Put(headerHashKey(number), hash.Bytes()); err != nil { - log.Crit("Failed to store number to hash mapping", "err", err) - } -} - -// DeleteCanonicalHash removes the number to hash canonical mapping. -func DeleteCanonicalHash(db ethdb.KeyValueWriter, number uint64) { - if err := db.Delete(headerHashKey(number)); err != nil { - log.Crit("Failed to delete number to hash mapping", "err", err) - } -} - -// ReadAllHashes retrieves all the hashes assigned to blocks at a certain heights, -// both canonical and reorged forks included. -func ReadAllHashes(db ethdb.Iteratee, number uint64) []common.Hash { - prefix := headerKeyPrefix(number) - - hashes := make([]common.Hash, 0, 1) - it := db.NewIterator(prefix, nil) - defer it.Release() - - for it.Next() { - if key := it.Key(); len(key) == len(prefix)+32 { - hashes = append(hashes, common.BytesToHash(key[len(key)-32:])) - } - } - return hashes -} - -type NumberHash struct { - Number uint64 - Hash common.Hash -} - -// ReadAllHashesInRange retrieves all the hashes assigned to blocks at certain -// heights, both canonical and reorged forks included. -// This method considers both limits to be _inclusive_. -func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash { - var ( - start = encodeBlockNumber(first) - keyLength = len(headerPrefix) + 8 + 32 - hashes = make([]*NumberHash, 0, 1+last-first) - it = db.NewIterator(headerPrefix, start) - ) - defer it.Release() - for it.Next() { - key := it.Key() - if len(key) != keyLength { - continue - } - num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8]) - if num > last { - break - } - hash := common.BytesToHash(key[len(key)-32:]) - hashes = append(hashes, &NumberHash{num, hash}) - } - return hashes -} - -// ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the -// certain chain range. If the accumulated entries reaches the given threshold, -// abort the iteration and return the semi-finish result. -func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) { - // Short circuit if the limit is 0. - if limit == 0 { - return nil, nil - } - var ( - numbers []uint64 - hashes []common.Hash - ) - // Construct the key prefix of start point. - start, end := headerHashKey(from), headerHashKey(to) - it := db.NewIterator(nil, start) - defer it.Release() - - for it.Next() { - if bytes.Compare(it.Key(), end) >= 0 { - break - } - if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) { - numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8])) - hashes = append(hashes, common.BytesToHash(it.Value())) - // If the accumulated entries reaches the limit threshold, return. - if len(numbers) >= limit { - break - } - } - } - return numbers, hashes -} - -// ReadHeaderNumber returns the header number assigned to a hash. -func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) *uint64 { - data, _ := db.Get(headerNumberKey(hash)) - if len(data) != 8 { - return nil - } - number := binary.BigEndian.Uint64(data) - return &number -} - -// WriteHeaderNumber stores the hash->number mapping. -func WriteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - key := headerNumberKey(hash) - enc := encodeBlockNumber(number) - if err := db.Put(key, enc); err != nil { - log.Crit("Failed to store hash to number mapping", "err", err) - } -} - -// DeleteHeaderNumber removes hash->number mapping. -func DeleteHeaderNumber(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Delete(headerNumberKey(hash)); err != nil { - log.Crit("Failed to delete hash to number mapping", "err", err) - } -} - -// ReadHeadHeaderHash retrieves the hash of the current canonical head header. -func ReadHeadHeaderHash(db ethdb.KeyValueReader) common.Hash { - data, _ := db.Get(headHeaderKey) - if len(data) == 0 { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// WriteHeadHeaderHash stores the hash of the current canonical head header. -func WriteHeadHeaderHash(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Put(headHeaderKey, hash.Bytes()); err != nil { - log.Crit("Failed to store last header's hash", "err", err) - } -} - -// ReadHeadBlockHash retrieves the hash of the current canonical head block. -func ReadHeadBlockHash(db ethdb.KeyValueReader) common.Hash { - data, _ := db.Get(headBlockKey) - if len(data) == 0 { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// WriteHeadBlockHash stores the head block's hash. -func WriteHeadBlockHash(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Put(headBlockKey, hash.Bytes()); err != nil { - log.Crit("Failed to store last block's hash", "err", err) - } -} - -// ReadHeaderRLP retrieves a block header in its raw RLP database encoding. -func ReadHeaderRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { - data, _ := db.Get(headerKey(number, hash)) - if len(data) > 0 { - return data - } - return nil -} - -// HasHeader verifies the existence of a block header corresponding to the hash. -func HasHeader(db ethdb.Reader, hash common.Hash, number uint64) bool { - if has, err := db.Has(headerKey(number, hash)); !has || err != nil { - return false - } - return true -} - -// ReadHeader retrieves the block header corresponding to the hash. -func ReadHeader(db ethdb.Reader, hash common.Hash, number uint64) *types.Header { - data := ReadHeaderRLP(db, hash, number) - if len(data) == 0 { - return nil - } - header := new(types.Header) - if err := rlp.DecodeBytes(data, header); err != nil { - log.Error("Invalid block header RLP", "hash", hash, "err", err) - return nil - } - return header -} - -// WriteHeader stores a block header into the database and also stores the hash- -// to-number mapping. -func WriteHeader(db ethdb.KeyValueWriter, header *types.Header) { - var ( - hash = header.Hash() - number = header.Number.Uint64() - ) - // Write the hash -> number mapping - WriteHeaderNumber(db, hash, number) - - // Write the encoded header - data, err := rlp.EncodeToBytes(header) - if err != nil { - log.Crit("Failed to RLP encode header", "err", err) - } - key := headerKey(number, hash) - if err := db.Put(key, data); err != nil { - log.Crit("Failed to store header", "err", err) - } -} - -// DeleteHeader removes all block header data associated with a hash. -func DeleteHeader(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - deleteHeaderWithoutNumber(db, hash, number) - if err := db.Delete(headerNumberKey(hash)); err != nil { - log.Crit("Failed to delete hash to number mapping", "err", err) - } -} - -// deleteHeaderWithoutNumber removes only the block header but does not remove -// the hash to number mapping. -func deleteHeaderWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - if err := db.Delete(headerKey(number, hash)); err != nil { - log.Crit("Failed to delete header", "err", err) - } -} - -// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding. -func ReadBodyRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { - data, _ := db.Get(blockBodyKey(number, hash)) - if len(data) > 0 { - return data - } - return nil -} - -// ReadCanonicalBodyRLP retrieves the block body (transactions and uncles) for the canonical -// block at number, in RLP encoding. -func ReadCanonicalBodyRLP(db ethdb.Reader, number uint64) rlp.RawValue { - // Need to get the hash - data, _ := db.Get(blockBodyKey(number, ReadCanonicalHash(db, number))) - if len(data) > 0 { - return data - } - return nil -} - -// WriteBodyRLP stores an RLP encoded block body into the database. -func WriteBodyRLP(db ethdb.KeyValueWriter, hash common.Hash, number uint64, rlp rlp.RawValue) { - if err := db.Put(blockBodyKey(number, hash), rlp); err != nil { - log.Crit("Failed to store block body", "err", err) - } -} - -// HasBody verifies the existence of a block body corresponding to the hash. -func HasBody(db ethdb.Reader, hash common.Hash, number uint64) bool { - if has, err := db.Has(blockBodyKey(number, hash)); !has || err != nil { - return false - } - return true -} - -// ReadBody retrieves the block body corresponding to the hash. -func ReadBody(db ethdb.Reader, hash common.Hash, number uint64) *types.Body { - data := ReadBodyRLP(db, hash, number) - if len(data) == 0 { - return nil - } - body := new(types.Body) - if err := rlp.DecodeBytes(data, body); err != nil { - log.Error("Invalid block body RLP", "hash", hash, "err", err) - return nil - } - return body -} - -// WriteBody stores a block body into the database. -func WriteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64, body *types.Body) { - data, err := rlp.EncodeToBytes(body) - if err != nil { - log.Crit("Failed to RLP encode body", "err", err) - } - WriteBodyRLP(db, hash, number, data) -} - -// DeleteBody removes all block body data associated with a hash. -func DeleteBody(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - if err := db.Delete(blockBodyKey(number, hash)); err != nil { - log.Crit("Failed to delete block body", "err", err) - } -} - -// HasReceipts verifies the existence of all the transaction receipts belonging -// to a block. -func HasReceipts(db ethdb.Reader, hash common.Hash, number uint64) bool { - if has, err := db.Has(blockReceiptsKey(number, hash)); !has || err != nil { - return false - } - return true -} - -// ReadReceiptsRLP retrieves all the transaction receipts belonging to a block in RLP encoding. -func ReadReceiptsRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue { - data, _ := db.Get(blockReceiptsKey(number, hash)) - if len(data) > 0 { - return data - } - return nil -} - -// ReadRawReceipts retrieves all the transaction receipts belonging to a block. -// The receipt metadata fields are not guaranteed to be populated, so they -// should not be used. Use ReadReceipts instead if the metadata is needed. -func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Receipts { - // Retrieve the flattened receipt slice - data := ReadReceiptsRLP(db, hash, number) - if len(data) == 0 { - return nil - } - // Convert the receipts from their storage form to their internal representation - storageReceipts := []*types.ReceiptForStorage{} - if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { - log.Error("Invalid receipt array RLP", "hash", hash, "err", err) - return nil - } - receipts := make(types.Receipts, len(storageReceipts)) - for i, storageReceipt := range storageReceipts { - receipts[i] = (*types.Receipt)(storageReceipt) - } - return receipts -} - -// ReadReceipts retrieves all the transaction receipts belonging to a block, including -// its corresponding metadata fields. If it is unable to populate these metadata -// fields then nil is returned. -// -// The current implementation populates these metadata fields by reading the receipts' -// corresponding block body, so if the block body is not found it will return nil even -// if the receipt itself is stored. -func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, config *params.ChainConfig) types.Receipts { - // We're deriving many fields from the block body, retrieve beside the receipt - receipts := ReadRawReceipts(db, hash, number) - if receipts == nil { - return nil - } - body := ReadBody(db, hash, number) - if body == nil { - log.Error("Missing body but have receipt", "hash", hash, "number", number) - return nil - } - header := ReadHeader(db, hash, number) - - var baseFee *big.Int - if header == nil { - baseFee = big.NewInt(0) - } else { - baseFee = header.BaseFee - } - // Compute effective blob gas price. - var blobGasPrice *big.Int - if header != nil && header.ExcessBlobGas != nil { - blobGasPrice = eip4844.CalcBlobFee(*header.ExcessBlobGas) - } - if err := receipts.DeriveFields(config, hash, number, time, baseFee, blobGasPrice, body.Transactions); err != nil { - log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err) - return nil - } - return receipts -} - -// WriteReceipts stores all the transaction receipts belonging to a block. -func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) { - // Convert the receipts into their storage form and serialize them - storageReceipts := make([]*types.ReceiptForStorage, len(receipts)) - for i, receipt := range receipts { - storageReceipts[i] = (*types.ReceiptForStorage)(receipt) - } - bytes, err := rlp.EncodeToBytes(storageReceipts) - if err != nil { - log.Crit("Failed to encode block receipts", "err", err) - } - // Store the flattened receipt slice - if err := db.Put(blockReceiptsKey(number, hash), bytes); err != nil { - log.Crit("Failed to store block receipts", "err", err) - } -} - -// DeleteReceipts removes all receipt data associated with a block hash. -func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - if err := db.Delete(blockReceiptsKey(number, hash)); err != nil { - log.Crit("Failed to delete block receipts", "err", err) - } -} - -// storedReceiptRLP is the storage encoding of a receipt. -// Re-definition in core/types/receipt.go. -// TODO: Re-use the existing definition. -type storedReceiptRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - Logs []*types.Log -} - -// ReceiptLogs is a barebone version of ReceiptForStorage which only keeps -// the list of logs. When decoding a stored receipt into this object we -// avoid creating the bloom filter. -type receiptLogs struct { - Logs []*types.Log -} - -// DecodeRLP implements rlp.Decoder. -func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error { - var stored storedReceiptRLP - if err := s.Decode(&stored); err != nil { - return err - } - r.Logs = stored.Logs - return nil -} - -// DeriveLogFields fills the logs in receiptLogs with information such as block number, txhash, etc. -func deriveLogFields(receipts []*receiptLogs, hash common.Hash, number uint64, txs types.Transactions) error { - logIndex := uint(0) - if len(txs) != len(receipts) { - return errors.New("transaction and receipt count mismatch") - } - for i := 0; i < len(receipts); i++ { - txHash := txs[i].Hash() - // The derived log fields can simply be set from the block and transaction - for j := 0; j < len(receipts[i].Logs); j++ { - receipts[i].Logs[j].BlockNumber = number - receipts[i].Logs[j].BlockHash = hash - receipts[i].Logs[j].TxHash = txHash - receipts[i].Logs[j].TxIndex = uint(i) - receipts[i].Logs[j].Index = logIndex - logIndex++ - } - } - return nil -} - -// ReadLogs retrieves the logs for all transactions in a block. In case -// receipts is not found, a nil is returned. -// Note: ReadLogs does not derive unstored log fields. -func ReadLogs(db ethdb.Reader, hash common.Hash, number uint64) [][]*types.Log { - // Retrieve the flattened receipt slice - data := ReadReceiptsRLP(db, hash, number) - if len(data) == 0 { - return nil - } - receipts := []*receiptLogs{} - if err := rlp.DecodeBytes(data, &receipts); err != nil { - log.Error("Invalid receipt array RLP", "hash", hash, "err", err) - return nil - } - - logs := make([][]*types.Log, len(receipts)) - for i, receipt := range receipts { - logs[i] = receipt.Logs - } - return logs -} - -// ReadBlock retrieves an entire block corresponding to the hash, assembling it -// back from the stored header and body. If either the header or body could not -// be retrieved nil is returned. -// -// Note, due to concurrent download of header and block body the header and thus -// canonical hash can be stored in the database but the body data not (yet). -func ReadBlock(db ethdb.Reader, hash common.Hash, number uint64) *types.Block { - header := ReadHeader(db, hash, number) - if header == nil { - return nil - } - body := ReadBody(db, hash, number) - if body == nil { - return nil - } - return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles).WithExtData(body.Version, body.ExtData) -} - -// WriteBlock serializes a block into the database, header and body separately. -func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) { - WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) - WriteHeader(db, block.Header()) -} - -// DeleteBlock removes all block data associated with a hash. -func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - DeleteReceipts(db, hash, number) - DeleteHeader(db, hash, number) - DeleteBody(db, hash, number) -} - -// DeleteBlockWithoutNumber removes all block data associated with a hash, except -// the hash to number mapping. -func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { - DeleteReceipts(db, hash, number) - deleteHeaderWithoutNumber(db, hash, number) - DeleteBody(db, hash, number) -} - -// FindCommonAncestor returns the last common ancestor of two block headers -func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { - for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { - a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) - if a == nil { - return nil - } - } - for an := a.Number.Uint64(); an < b.Number.Uint64(); { - b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) - if b == nil { - return nil - } - } - for a.Hash() != b.Hash() { - a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) - if a == nil { - return nil - } - b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) - if b == nil { - return nil - } - } - return a -} - -// ReadHeadBlock returns the current canonical head block. -func ReadHeadBlock(db ethdb.Reader) *types.Block { - headBlockHash := ReadHeadBlockHash(db) - if headBlockHash == (common.Hash{}) { - return nil - } - headBlockNumber := ReadHeaderNumber(db, headBlockHash) - if headBlockNumber == nil { - return nil - } - return ReadBlock(db, headBlockHash, *headBlockNumber) -} - -// ReadTxIndexTail retrieves the number of oldest indexed block -// whose transaction indices has been indexed. -func ReadTxIndexTail(db ethdb.KeyValueReader) *uint64 { - data, _ := db.Get(txIndexTailKey) - if len(data) != 8 { - return nil - } - number := binary.BigEndian.Uint64(data) - return &number -} - -// WriteTxIndexTail stores the number of oldest indexed block -// into database. -func WriteTxIndexTail(db ethdb.KeyValueWriter, number uint64) { - if err := db.Put(txIndexTailKey, encodeBlockNumber(number)); err != nil { - log.Crit("Failed to store the transaction index tail", "err", err) - } -} diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go deleted file mode 100644 index 1157eee792..0000000000 --- a/core/rawdb/accessors_chain_test.go +++ /dev/null @@ -1,622 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "bytes" - "encoding/hex" - "fmt" - "math/big" - "os" - "reflect" - "testing" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -// Tests block header storage and retrieval operations. -func TestHeaderStorage(t *testing.T) { - db := NewMemoryDatabase() - - // Create a test header to move around the database and make sure it's really new - header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")} - if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { - t.Fatalf("Non existent header returned: %v", entry) - } - // Write and verify the header in the database - WriteHeader(db, header) - if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry == nil { - t.Fatalf("Stored header not found") - } else if entry.Hash() != header.Hash() { - t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, header) - } - if entry := ReadHeaderRLP(db, header.Hash(), header.Number.Uint64()); entry == nil { - t.Fatalf("Stored header RLP not found") - } else { - hasher := sha3.NewLegacyKeccak256() - hasher.Write(entry) - - if hash := common.BytesToHash(hasher.Sum(nil)); hash != header.Hash() { - t.Fatalf("Retrieved RLP header mismatch: have %v, want %v", entry, header) - } - } - // Delete the header and verify the execution - DeleteHeader(db, header.Hash(), header.Number.Uint64()) - if entry := ReadHeader(db, header.Hash(), header.Number.Uint64()); entry != nil { - t.Fatalf("Deleted header returned: %v", entry) - } -} - -// Tests block body storage and retrieval operations. -func TestBodyStorage(t *testing.T) { - db := NewMemoryDatabase() - - // Create a test body to move around the database and make sure it's really new - body := &types.Body{Uncles: []*types.Header{{Extra: []byte("test header")}}} - - hasher := sha3.NewLegacyKeccak256() - rlp.Encode(hasher, body) - hash := common.BytesToHash(hasher.Sum(nil)) - - if entry := ReadBody(db, hash, 0); entry != nil { - t.Fatalf("Non existent body returned: %v", entry) - } - // Write and verify the body in the database - WriteBody(db, hash, 0, body) - if entry := ReadBody(db, hash, 0); entry == nil { - t.Fatalf("Stored body not found") - } else if types.DeriveSha(types.Transactions(entry.Transactions), newTestHasher()) != types.DeriveSha(types.Transactions(body.Transactions), newTestHasher()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(body.Uncles) { - t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, body) - } - if entry := ReadBodyRLP(db, hash, 0); entry == nil { - t.Fatalf("Stored body RLP not found") - } else { - hasher := sha3.NewLegacyKeccak256() - hasher.Write(entry) - - if calc := common.BytesToHash(hasher.Sum(nil)); calc != hash { - t.Fatalf("Retrieved RLP body mismatch: have %v, want %v", entry, body) - } - } - // Delete the body and verify the execution - DeleteBody(db, hash, 0) - if entry := ReadBody(db, hash, 0); entry != nil { - t.Fatalf("Deleted body returned: %v", entry) - } -} - -// Tests block storage and retrieval operations. -func TestBlockStorage(t *testing.T) { - db := NewMemoryDatabase() - - // Create a test block to move around the database and make sure it's really new - block := types.NewBlockWithHeader(&types.Header{ - Extra: []byte("test block"), - UncleHash: types.EmptyUncleHash, - TxHash: types.EmptyTxsHash, - ReceiptHash: types.EmptyReceiptsHash, - }) - if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Non existent block returned: %v", entry) - } - if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Non existent header returned: %v", entry) - } - if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Non existent body returned: %v", entry) - } - // Write and verify the block in the database - WriteBlock(db, block) - if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil { - t.Fatalf("Stored block not found") - } else if entry.Hash() != block.Hash() { - t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block) - } - if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry == nil { - t.Fatalf("Stored header not found") - } else if entry.Hash() != block.Header().Hash() { - t.Fatalf("Retrieved header mismatch: have %v, want %v", entry, block.Header()) - } - if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry == nil { - t.Fatalf("Stored body not found") - } else if types.DeriveSha(types.Transactions(entry.Transactions), newTestHasher()) != types.DeriveSha(block.Transactions(), newTestHasher()) || types.CalcUncleHash(entry.Uncles) != types.CalcUncleHash(block.Uncles()) { - t.Fatalf("Retrieved body mismatch: have %v, want %v", entry, block.Body()) - } - // Delete the block and verify the execution - DeleteBlock(db, block.Hash(), block.NumberU64()) - if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Deleted block returned: %v", entry) - } - if entry := ReadHeader(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Deleted header returned: %v", entry) - } - if entry := ReadBody(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Deleted body returned: %v", entry) - } -} - -// Tests that partial block contents don't get reassembled into full blocks. -func TestPartialBlockStorage(t *testing.T) { - db := NewMemoryDatabase() - block := types.NewBlockWithHeader(&types.Header{ - Extra: []byte("test block"), - UncleHash: types.EmptyUncleHash, - TxHash: types.EmptyTxsHash, - ReceiptHash: types.EmptyReceiptsHash, - }) - // Store a header and check that it's not recognized as a block - WriteHeader(db, block.Header()) - if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Non existent block returned: %v", entry) - } - DeleteHeader(db, block.Hash(), block.NumberU64()) - - // Store a body and check that it's not recognized as a block - WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) - if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry != nil { - t.Fatalf("Non existent block returned: %v", entry) - } - DeleteBody(db, block.Hash(), block.NumberU64()) - - // Store a header and a body separately and check reassembly - WriteHeader(db, block.Header()) - WriteBody(db, block.Hash(), block.NumberU64(), block.Body()) - - if entry := ReadBlock(db, block.Hash(), block.NumberU64()); entry == nil { - t.Fatalf("Stored block not found") - } else if entry.Hash() != block.Hash() { - t.Fatalf("Retrieved block mismatch: have %v, want %v", entry, block) - } -} - -// Tests that canonical numbers can be mapped to hashes and retrieved. -func TestCanonicalMappingStorage(t *testing.T) { - db := NewMemoryDatabase() - - // Create a test canonical number and assigned hash to move around - hash, number := common.Hash{0: 0xff}, uint64(314) - if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) { - t.Fatalf("Non existent canonical mapping returned: %v", entry) - } - // Write and verify the TD in the database - WriteCanonicalHash(db, hash, number) - if entry := ReadCanonicalHash(db, number); entry == (common.Hash{}) { - t.Fatalf("Stored canonical mapping not found") - } else if entry != hash { - t.Fatalf("Retrieved canonical mapping mismatch: have %v, want %v", entry, hash) - } - // Delete the TD and verify the execution - DeleteCanonicalHash(db, number) - if entry := ReadCanonicalHash(db, number); entry != (common.Hash{}) { - t.Fatalf("Deleted canonical mapping returned: %v", entry) - } -} - -// Tests that head headers and head blocks can be assigned, individually. -func TestHeadStorage(t *testing.T) { - db := NewMemoryDatabase() - - blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")}) - blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")}) - - // Check that no head entries are in a pristine database - if entry := ReadHeadHeaderHash(db); entry != (common.Hash{}) { - t.Fatalf("Non head header entry returned: %v", entry) - } - if entry := ReadHeadBlockHash(db); entry != (common.Hash{}) { - t.Fatalf("Non head block entry returned: %v", entry) - } - // Assign separate entries for the head header and block - WriteHeadHeaderHash(db, blockHead.Hash()) - WriteHeadBlockHash(db, blockFull.Hash()) - - // Check that both heads are present, and different (i.e. two heads maintained) - if entry := ReadHeadHeaderHash(db); entry != blockHead.Hash() { - t.Fatalf("Head header hash mismatch: have %v, want %v", entry, blockHead.Hash()) - } - if entry := ReadHeadBlockHash(db); entry != blockFull.Hash() { - t.Fatalf("Head block hash mismatch: have %v, want %v", entry, blockFull.Hash()) - } -} - -// Tests that receipts associated with a single block can be stored and retrieved. -func TestBlockReceiptStorage(t *testing.T) { - db := NewMemoryDatabase() - - // Create a live block since we need metadata to reconstruct the receipt - tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil) - tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil) - - body := &types.Body{Transactions: types.Transactions{tx1, tx2}} - - // Create the two receipts to manage afterwards - receipt1 := &types.Receipt{ - Status: types.ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*types.Log{ - {Address: common.BytesToAddress([]byte{0x11})}, - {Address: common.BytesToAddress([]byte{0x01, 0x11})}, - }, - TxHash: tx1.Hash(), - ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), - GasUsed: 111111, - } - receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1}) - - receipt2 := &types.Receipt{ - PostState: common.Hash{2}.Bytes(), - CumulativeGasUsed: 2, - Logs: []*types.Log{ - {Address: common.BytesToAddress([]byte{0x22})}, - {Address: common.BytesToAddress([]byte{0x02, 0x22})}, - }, - TxHash: tx2.Hash(), - ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), - GasUsed: 222222, - } - receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) - receipts := []*types.Receipt{receipt1, receipt2} - - // Check that no receipt entries are in a pristine database - header := &types.Header{Number: big.NewInt(0), Extra: []byte("test header")} - hash := header.Hash() - if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 { - t.Fatalf("non existent receipts returned: %v", rs) - } - // Insert the body that corresponds to the receipts - WriteHeader(db, header) - WriteBody(db, hash, 0, body) - if header := ReadHeader(db, hash, 0); header == nil { - t.Fatal("header is nil") - } - - // Insert the receipt slice into the database and check presence - WriteReceipts(db, hash, 0, receipts) - if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) == 0 { - t.Fatal("no receipts returned") - } else { - if err := checkReceiptsRLP(rs, receipts); err != nil { - t.Fatal(err) - } - } - // Delete the body and ensure that the receipts are no longer returned (metadata can't be recomputed) - DeleteHeader(db, hash, 0) - DeleteBody(db, hash, 0) - if header := ReadHeader(db, hash, 0); header != nil { - t.Fatal("header is not nil") - } - if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); rs != nil { - t.Fatalf("receipts returned when body was deleted: %v", rs) - } - // Ensure that receipts without metadata can be returned without the block body too - if err := checkReceiptsRLP(ReadRawReceipts(db, hash, 0), receipts); err != nil { - t.Fatal(err) - } - // Sanity check that body and header alone without the receipt is a full purge - WriteHeader(db, header) - WriteBody(db, hash, 0, body) - - DeleteReceipts(db, hash, 0) - if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 { - t.Fatalf("deleted receipts returned: %v", rs) - } -} - -func checkReceiptsRLP(have, want types.Receipts) error { - if len(have) != len(want) { - return fmt.Errorf("receipts sizes mismatch: have %d, want %d", len(have), len(want)) - } - for i := 0; i < len(want); i++ { - rlpHave, err := rlp.EncodeToBytes(have[i]) - if err != nil { - return err - } - rlpWant, err := rlp.EncodeToBytes(want[i]) - if err != nil { - return err - } - if !bytes.Equal(rlpHave, rlpWant) { - return fmt.Errorf("receipt #%d: receipt mismatch: have %s, want %s", i, hex.EncodeToString(rlpHave), hex.EncodeToString(rlpWant)) - } - } - return nil -} - -func TestCanonicalHashIteration(t *testing.T) { - var cases = []struct { - from, to uint64 - limit int - expect []uint64 - }{ - {1, 8, 0, nil}, - {1, 8, 1, []uint64{1}}, - {1, 8, 10, []uint64{1, 2, 3, 4, 5, 6, 7}}, - {1, 9, 10, []uint64{1, 2, 3, 4, 5, 6, 7, 8}}, - {2, 9, 10, []uint64{2, 3, 4, 5, 6, 7, 8}}, - {9, 10, 10, nil}, - } - // Test empty db iteration - db := NewMemoryDatabase() - numbers, _ := ReadAllCanonicalHashes(db, 0, 10, 10) - if len(numbers) != 0 { - t.Fatalf("No entry should be returned to iterate an empty db") - } - // Fill database with testing data. - for i := uint64(1); i <= 8; i++ { - WriteCanonicalHash(db, common.Hash{}, i) - } - for i, c := range cases { - numbers, _ := ReadAllCanonicalHashes(db, c.from, c.to, c.limit) - if !reflect.DeepEqual(numbers, c.expect) { - t.Fatalf("Case %d failed, want %v, got %v", i, c.expect, numbers) - } - } -} - -func TestHashesInRange(t *testing.T) { - mkHeader := func(number, seq int) *types.Header { - h := types.Header{ - Difficulty: new(big.Int), - Number: big.NewInt(int64(number)), - GasLimit: uint64(seq), - } - return &h - } - db := NewMemoryDatabase() - // For each number, write N versions of that particular number - total := 0 - for i := 0; i < 15; i++ { - for ii := 0; ii < i; ii++ { - WriteHeader(db, mkHeader(i, ii)) - total++ - } - } - if have, want := len(ReadAllHashesInRange(db, 10, 10)), 10; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashesInRange(db, 10, 9)), 0; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashesInRange(db, 0, 100)), total; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashesInRange(db, 9, 10)), 9+10; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashes(db, 10)), 10; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashes(db, 16)), 0; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashes(db, 1)), 1; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } -} - -type fullLogRLP struct { - Address common.Address - Topics []common.Hash - Data []byte - BlockNumber uint64 - TxHash common.Hash - TxIndex uint - BlockHash common.Hash - Index uint -} - -func newFullLogRLP(l *types.Log) *fullLogRLP { - return &fullLogRLP{ - Address: l.Address, - Topics: l.Topics, - Data: l.Data, - BlockNumber: l.BlockNumber, - TxHash: l.TxHash, - TxIndex: l.TxIndex, - BlockHash: l.BlockHash, - Index: l.Index, - } -} - -// Tests that logs associated with a single block can be retrieved. -func TestReadLogs(t *testing.T) { - db := NewMemoryDatabase() - - // Create a live block since we need metadata to reconstruct the receipt - tx1 := types.NewTransaction(1, common.HexToAddress("0x1"), big.NewInt(1), 1, big.NewInt(1), nil) - tx2 := types.NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil) - - body := &types.Body{Transactions: types.Transactions{tx1, tx2}} - - // Create the two receipts to manage afterwards - receipt1 := &types.Receipt{ - Status: types.ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*types.Log{ - {Address: common.BytesToAddress([]byte{0x11})}, - {Address: common.BytesToAddress([]byte{0x01, 0x11})}, - }, - TxHash: tx1.Hash(), - ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), - GasUsed: 111111, - } - receipt1.Bloom = types.CreateBloom(types.Receipts{receipt1}) - - receipt2 := &types.Receipt{ - PostState: common.Hash{2}.Bytes(), - CumulativeGasUsed: 2, - Logs: []*types.Log{ - {Address: common.BytesToAddress([]byte{0x22})}, - {Address: common.BytesToAddress([]byte{0x02, 0x22})}, - }, - TxHash: tx2.Hash(), - ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), - GasUsed: 222222, - } - receipt2.Bloom = types.CreateBloom(types.Receipts{receipt2}) - receipts := []*types.Receipt{receipt1, receipt2} - - hash := common.BytesToHash([]byte{0x03, 0x14}) - // Check that no receipt entries are in a pristine database - if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 { - t.Fatalf("non existent receipts returned: %v", rs) - } - // Insert the body that corresponds to the receipts - WriteBody(db, hash, 0, body) - - // Insert the receipt slice into the database and check presence - WriteReceipts(db, hash, 0, receipts) - - logs := ReadLogs(db, hash, 0) - if len(logs) == 0 { - t.Fatalf("no logs returned") - } - if have, want := len(logs), 2; have != want { - t.Fatalf("unexpected number of logs returned, have %d want %d", have, want) - } - if have, want := len(logs[0]), 2; have != want { - t.Fatalf("unexpected number of logs[0] returned, have %d want %d", have, want) - } - if have, want := len(logs[1]), 2; have != want { - t.Fatalf("unexpected number of logs[1] returned, have %d want %d", have, want) - } - - for i, pr := range receipts { - for j, pl := range pr.Logs { - rlpHave, err := rlp.EncodeToBytes(newFullLogRLP(logs[i][j])) - if err != nil { - t.Fatal(err) - } - rlpWant, err := rlp.EncodeToBytes(newFullLogRLP(pl)) - if err != nil { - t.Fatal(err) - } - if !bytes.Equal(rlpHave, rlpWant) { - t.Fatalf("receipt #%d: receipt mismatch: have %s, want %s", i, hex.EncodeToString(rlpHave), hex.EncodeToString(rlpWant)) - } - } - } -} - -func TestDeriveLogFields(t *testing.T) { - // Create a few transactions to have receipts for - to2 := common.HexToAddress("0x2") - to3 := common.HexToAddress("0x3") - txs := types.Transactions{ - types.NewTx(&types.LegacyTx{ - Nonce: 1, - Value: big.NewInt(1), - Gas: 1, - GasPrice: big.NewInt(1), - }), - types.NewTx(&types.LegacyTx{ - To: &to2, - Nonce: 2, - Value: big.NewInt(2), - Gas: 2, - GasPrice: big.NewInt(2), - }), - types.NewTx(&types.AccessListTx{ - To: &to3, - Nonce: 3, - Value: big.NewInt(3), - Gas: 3, - GasPrice: big.NewInt(3), - }), - } - // Create the corresponding receipts - receipts := []*receiptLogs{ - { - Logs: []*types.Log{ - {Address: common.BytesToAddress([]byte{0x11})}, - {Address: common.BytesToAddress([]byte{0x01, 0x11})}, - }, - }, - { - Logs: []*types.Log{ - {Address: common.BytesToAddress([]byte{0x22})}, - {Address: common.BytesToAddress([]byte{0x02, 0x22})}, - }, - }, - { - Logs: []*types.Log{ - {Address: common.BytesToAddress([]byte{0x33})}, - {Address: common.BytesToAddress([]byte{0x03, 0x33})}, - }, - }, - } - - // Derive log metadata fields - number := big.NewInt(1) - hash := common.BytesToHash([]byte{0x03, 0x14}) - if err := deriveLogFields(receipts, hash, number.Uint64(), txs); err != nil { - t.Fatal(err) - } - - // Iterate over all the computed fields and check that they're correct - logIndex := uint(0) - for i := range receipts { - for j := range receipts[i].Logs { - if receipts[i].Logs[j].BlockNumber != number.Uint64() { - t.Errorf("receipts[%d].Logs[%d].BlockNumber = %d, want %d", i, j, receipts[i].Logs[j].BlockNumber, number.Uint64()) - } - if receipts[i].Logs[j].BlockHash != hash { - t.Errorf("receipts[%d].Logs[%d].BlockHash = %s, want %s", i, j, receipts[i].Logs[j].BlockHash.String(), hash.String()) - } - if receipts[i].Logs[j].TxHash != txs[i].Hash() { - t.Errorf("receipts[%d].Logs[%d].TxHash = %s, want %s", i, j, receipts[i].Logs[j].TxHash.String(), txs[i].Hash().String()) - } - if receipts[i].Logs[j].TxIndex != uint(i) { - t.Errorf("receipts[%d].Logs[%d].TransactionIndex = %d, want %d", i, j, receipts[i].Logs[j].TxIndex, i) - } - if receipts[i].Logs[j].Index != logIndex { - t.Errorf("receipts[%d].Logs[%d].Index = %d, want %d", i, j, receipts[i].Logs[j].Index, logIndex) - } - logIndex++ - } - } -} - -func BenchmarkDecodeRLPLogs(b *testing.B) { - // Encoded receipts from block 0x14ee094309fbe8f70b65f45ebcc08fb33f126942d97464aad5eb91cfd1e2d269 - buf, err := os.ReadFile("testdata/stored_receipts.bin") - if err != nil { - b.Fatal(err) - } - b.Run("ReceiptForStorage", func(b *testing.B) { - b.ReportAllocs() - var r []*types.ReceiptForStorage - for i := 0; i < b.N; i++ { - if err := rlp.DecodeBytes(buf, &r); err != nil { - b.Fatal(err) - } - } - }) - b.Run("rlpLogs", func(b *testing.B) { - b.ReportAllocs() - var r []*receiptLogs - for i := 0; i < b.N; i++ { - if err := rlp.DecodeBytes(buf, &r); err != nil { - b.Fatal(err) - } - } - }) -} diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go deleted file mode 100644 index 511fa39d8f..0000000000 --- a/core/rawdb/accessors_indexes.go +++ /dev/null @@ -1,191 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "bytes" - "math/big" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" -) - -// ReadTxLookupEntry retrieves the positional metadata associated with a transaction -// hash to allow retrieving the transaction or receipt by hash. -func ReadTxLookupEntry(db ethdb.Reader, hash common.Hash) *uint64 { - data, _ := db.Get(txLookupKey(hash)) - if len(data) == 0 { - return nil - } - // Database v6 tx lookup just stores the block number - if len(data) < common.HashLength { - number := new(big.Int).SetBytes(data).Uint64() - return &number - } - // Database v4-v5 tx lookup format just stores the hash - if len(data) == common.HashLength { - return ReadHeaderNumber(db, common.BytesToHash(data)) - } - // Finally try database v3 tx lookup format - var entry LegacyTxLookupEntry - if err := rlp.DecodeBytes(data, &entry); err != nil { - log.Error("Invalid transaction lookup entry RLP", "hash", hash, "blob", data, "err", err) - return nil - } - return &entry.BlockIndex -} - -// writeTxLookupEntry stores a positional metadata for a transaction, -// enabling hash based transaction and receipt lookups. -func writeTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash, numberBytes []byte) { - if err := db.Put(txLookupKey(hash), numberBytes); err != nil { - log.Crit("Failed to store transaction lookup entry", "err", err) - } -} - -// WriteTxLookupEntries is identical to WriteTxLookupEntry, but it works on -// a list of hashes -func WriteTxLookupEntries(db ethdb.KeyValueWriter, number uint64, hashes []common.Hash) { - numberBytes := new(big.Int).SetUint64(number).Bytes() - for _, hash := range hashes { - writeTxLookupEntry(db, hash, numberBytes) - } -} - -// WriteTxLookupEntriesByBlock stores a positional metadata for every transaction from -// a block, enabling hash based transaction and receipt lookups. -func WriteTxLookupEntriesByBlock(db ethdb.KeyValueWriter, block *types.Block) { - numberBytes := block.Number().Bytes() - for _, tx := range block.Transactions() { - writeTxLookupEntry(db, tx.Hash(), numberBytes) - } -} - -// DeleteTxLookupEntry removes all transaction data associated with a hash. -func DeleteTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Delete(txLookupKey(hash)); err != nil { - log.Crit("Failed to delete transaction lookup entry", "err", err) - } -} - -// DeleteTxLookupEntries removes all transaction lookups for a given block. -func DeleteTxLookupEntries(db ethdb.KeyValueWriter, hashes []common.Hash) { - for _, hash := range hashes { - DeleteTxLookupEntry(db, hash) - } -} - -// ReadTransaction retrieves a specific transaction from the database, along with -// its added positional metadata. -func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) { - blockNumber := ReadTxLookupEntry(db, hash) - if blockNumber == nil { - return nil, common.Hash{}, 0, 0 - } - blockHash := ReadCanonicalHash(db, *blockNumber) - if blockHash == (common.Hash{}) { - return nil, common.Hash{}, 0, 0 - } - body := ReadBody(db, blockHash, *blockNumber) - if body == nil { - log.Error("Transaction referenced missing", "number", *blockNumber, "hash", blockHash) - return nil, common.Hash{}, 0, 0 - } - for txIndex, tx := range body.Transactions { - if tx.Hash() == hash { - return tx, blockHash, *blockNumber, uint64(txIndex) - } - } - log.Error("Transaction not found", "number", *blockNumber, "hash", blockHash, "txhash", hash) - return nil, common.Hash{}, 0, 0 -} - -// ReadReceipt retrieves a specific transaction receipt from the database, along with -// its added positional metadata. -func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig) (*types.Receipt, common.Hash, uint64, uint64) { - // Retrieve the context of the receipt based on the transaction hash - blockNumber := ReadTxLookupEntry(db, hash) - if blockNumber == nil { - return nil, common.Hash{}, 0, 0 - } - blockHash := ReadCanonicalHash(db, *blockNumber) - if blockHash == (common.Hash{}) { - return nil, common.Hash{}, 0, 0 - } - blockHeader := ReadHeader(db, blockHash, *blockNumber) - if blockHeader == nil { - return nil, common.Hash{}, 0, 0 - } - // Read all the receipts from the block and return the one with the matching hash - receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config) - for receiptIndex, receipt := range receipts { - if receipt.TxHash == hash { - return receipt, blockHash, *blockNumber, uint64(receiptIndex) - } - } - log.Error("Receipt not found", "number", *blockNumber, "hash", blockHash, "txhash", hash) - return nil, common.Hash{}, 0, 0 -} - -// ReadBloomBits retrieves the compressed bloom bit vector belonging to the given -// section and bit index from the. -func ReadBloomBits(db ethdb.KeyValueReader, bit uint, section uint64, head common.Hash) ([]byte, error) { - return db.Get(bloomBitsKey(bit, section, head)) -} - -// WriteBloomBits stores the compressed bloom bits vector belonging to the given -// section and bit index. -func WriteBloomBits(db ethdb.KeyValueWriter, bit uint, section uint64, head common.Hash, bits []byte) { - if err := db.Put(bloomBitsKey(bit, section, head), bits); err != nil { - log.Crit("Failed to store bloom bits", "err", err) - } -} - -// DeleteBloombits removes all compressed bloom bits vector belonging to the -// given section range and bit index. -func DeleteBloombits(db ethdb.Database, bit uint, from uint64, to uint64) { - start, end := bloomBitsKey(bit, from, common.Hash{}), bloomBitsKey(bit, to, common.Hash{}) - it := db.NewIterator(nil, start) - defer it.Release() - - for it.Next() { - if bytes.Compare(it.Key(), end) >= 0 { - break - } - if len(it.Key()) != len(bloomBitsPrefix)+2+8+32 { - continue - } - db.Delete(it.Key()) - } - if it.Error() != nil { - log.Crit("Failed to delete bloom bits", "err", it.Error()) - } -} diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go deleted file mode 100644 index 1930d81e91..0000000000 --- a/core/rawdb/accessors_indexes_test.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "bytes" - "math/big" - "testing" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/internal/blocktest" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" -) - -var newTestHasher = blocktest.NewHasher - -// Tests that positional lookup metadata can be stored and retrieved. -func TestLookupStorage(t *testing.T) { - tests := []struct { - name string - writeTxLookupEntriesByBlock func(ethdb.Writer, *types.Block) - }{ - { - "DatabaseV6", - func(db ethdb.Writer, block *types.Block) { - WriteTxLookupEntriesByBlock(db, block) - }, - }, - { - "DatabaseV4-V5", - func(db ethdb.Writer, block *types.Block) { - for _, tx := range block.Transactions() { - db.Put(txLookupKey(tx.Hash()), block.Hash().Bytes()) - } - }, - }, - { - "DatabaseV3", - func(db ethdb.Writer, block *types.Block) { - for index, tx := range block.Transactions() { - entry := LegacyTxLookupEntry{ - BlockHash: block.Hash(), - BlockIndex: block.NumberU64(), - Index: uint64(index), - } - data, _ := rlp.EncodeToBytes(entry) - db.Put(txLookupKey(tx.Hash()), data) - } - }, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - db := NewMemoryDatabase() - - tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), big.NewInt(111), 1111, big.NewInt(11111), []byte{0x11, 0x11, 0x11}) - tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), big.NewInt(222), 2222, big.NewInt(22222), []byte{0x22, 0x22, 0x22}) - tx3 := types.NewTransaction(3, common.BytesToAddress([]byte{0x33}), big.NewInt(333), 3333, big.NewInt(33333), []byte{0x33, 0x33, 0x33}) - txs := []*types.Transaction{tx1, tx2, tx3} - - block := types.NewBlock(&types.Header{Number: big.NewInt(314)}, txs, nil, nil, newTestHasher()) - - // Check that no transactions entries are in a pristine database - for i, tx := range txs { - if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil { - t.Fatalf("tx #%d [%x]: non existent transaction returned: %v", i, tx.Hash(), txn) - } - } - // Insert all the transactions into the database, and verify contents - WriteCanonicalHash(db, block.Hash(), block.NumberU64()) - WriteBlock(db, block) - tc.writeTxLookupEntriesByBlock(db, block) - - for i, tx := range txs { - if txn, hash, number, index := ReadTransaction(db, tx.Hash()); txn == nil { - t.Fatalf("tx #%d [%x]: transaction not found", i, tx.Hash()) - } else { - if hash != block.Hash() || number != block.NumberU64() || index != uint64(i) { - t.Fatalf("tx #%d [%x]: positional metadata mismatch: have %x/%d/%d, want %x/%v/%v", i, tx.Hash(), hash, number, index, block.Hash(), block.NumberU64(), i) - } - if tx.Hash() != txn.Hash() { - t.Fatalf("tx #%d [%x]: transaction mismatch: have %v, want %v", i, tx.Hash(), txn, tx) - } - } - } - // Delete the transactions and check purge - for i, tx := range txs { - DeleteTxLookupEntry(db, tx.Hash()) - if txn, _, _, _ := ReadTransaction(db, tx.Hash()); txn != nil { - t.Fatalf("tx #%d [%x]: deleted transaction returned: %v", i, tx.Hash(), txn) - } - } - }) - } -} - -func TestDeleteBloomBits(t *testing.T) { - // Prepare testing data - db := NewMemoryDatabase() - - genesisHash0 := common.BytesToHash([]byte{1, 2, 3, 4, 5}) - genesisHash1 := common.BytesToHash([]byte{5, 4, 3, 2, 1}) - for i := uint(0); i < 2; i++ { - for s := uint64(0); s < 2; s++ { - WriteBloomBits(db, i, s, genesisHash0, []byte{0x01, 0x02}) - WriteBloomBits(db, i, s, genesisHash1, []byte{0x01, 0x02}) - } - } - check := func(bit uint, section uint64, head common.Hash, exist bool) { - bits, _ := ReadBloomBits(db, bit, section, head) - if exist && !bytes.Equal(bits, []byte{0x01, 0x02}) { - t.Fatalf("Bloombits mismatch") - } - if !exist && len(bits) > 0 { - t.Fatalf("Bloombits should be removed") - } - } - // Check the existence of written data. - check(0, 0, genesisHash0, true) - check(0, 0, genesisHash1, true) - - // Check the existence of deleted data. - DeleteBloombits(db, 0, 0, 1) - check(0, 0, genesisHash0, false) - check(0, 0, genesisHash1, false) - check(0, 1, genesisHash0, true) - check(0, 1, genesisHash1, true) - - // Check the existence of deleted data. - DeleteBloombits(db, 0, 0, 2) - check(0, 0, genesisHash0, false) - check(0, 0, genesisHash1, false) - check(0, 1, genesisHash0, false) - check(0, 1, genesisHash1, false) - - // Bit1 shouldn't be affect. - check(1, 0, genesisHash0, true) - check(1, 0, genesisHash1, true) - check(1, 1, genesisHash0, true) - check(1, 1, genesisHash1, true) -} diff --git a/core/rawdb/accessors_metadata.go b/core/rawdb/accessors_metadata.go deleted file mode 100644 index c6ad7645a3..0000000000 --- a/core/rawdb/accessors_metadata.go +++ /dev/null @@ -1,278 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "encoding/json" - "time" - - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" -) - -// ReadDatabaseVersion retrieves the version number of the database. -func ReadDatabaseVersion(db ethdb.KeyValueReader) *uint64 { - var version uint64 - - enc, _ := db.Get(databaseVersionKey) - if len(enc) == 0 { - return nil - } - if err := rlp.DecodeBytes(enc, &version); err != nil { - return nil - } - - return &version -} - -// WriteDatabaseVersion stores the version number of the database -func WriteDatabaseVersion(db ethdb.KeyValueWriter, version uint64) { - enc, err := rlp.EncodeToBytes(version) - if err != nil { - log.Crit("Failed to encode database version", "err", err) - } - if err = db.Put(databaseVersionKey, enc); err != nil { - log.Crit("Failed to store the database version", "err", err) - } -} - -// ReadChainConfig retrieves the consensus settings based on the given genesis hash. -func ReadChainConfig(db ethdb.KeyValueReader, hash common.Hash) *params.ChainConfig { - data, _ := db.Get(configKey(hash)) - if len(data) == 0 { - return nil - } - var config params.ChainConfig - if err := json.Unmarshal(data, &config); err != nil { - log.Error("Invalid chain config JSON", "hash", hash, "err", err) - return nil - } - return &config -} - -// WriteChainConfig writes the chain config settings to the database. -func WriteChainConfig(db ethdb.KeyValueWriter, hash common.Hash, cfg *params.ChainConfig) { - if cfg == nil { - return - } - data, err := json.Marshal(cfg) - if err != nil { - log.Crit("Failed to JSON encode chain config", "err", err) - } - if err := db.Put(configKey(hash), data); err != nil { - log.Crit("Failed to store chain config", "err", err) - } -} - -// crashList is a list of unclean-shutdown-markers, for rlp-encoding to the -// database -type crashList struct { - Discarded uint64 // how many ucs have we deleted - Recent []uint64 // unix timestamps of 10 latest unclean shutdowns -} - -const crashesToKeep = 10 - -// PushUncleanShutdownMarker appends a new unclean shutdown marker and returns -// the previous data -// - a list of timestamps -// - a count of how many old unclean-shutdowns have been discarded -func PushUncleanShutdownMarker(db ethdb.KeyValueStore) ([]uint64, uint64, error) { - var uncleanShutdowns crashList - // Read old data - if data, err := db.Get(uncleanShutdownKey); err == nil { - if err := rlp.DecodeBytes(data, &uncleanShutdowns); err != nil { - return nil, 0, err - } - } - var discarded = uncleanShutdowns.Discarded - var previous = make([]uint64, len(uncleanShutdowns.Recent)) - copy(previous, uncleanShutdowns.Recent) - // Add a new (but cap it) - uncleanShutdowns.Recent = append(uncleanShutdowns.Recent, uint64(time.Now().Unix())) - if count := len(uncleanShutdowns.Recent); count > crashesToKeep+1 { - numDel := count - (crashesToKeep + 1) - uncleanShutdowns.Recent = uncleanShutdowns.Recent[numDel:] - uncleanShutdowns.Discarded += uint64(numDel) - } - // And save it again - data, _ := rlp.EncodeToBytes(uncleanShutdowns) - if err := db.Put(uncleanShutdownKey, data); err != nil { - log.Warn("Failed to write unclean-shutdown marker", "err", err) - return nil, 0, err - } - return previous, discarded, nil -} - -// PopUncleanShutdownMarker removes the last unclean shutdown marker -func PopUncleanShutdownMarker(db ethdb.KeyValueStore) { - var uncleanShutdowns crashList - // Read old data - if data, err := db.Get(uncleanShutdownKey); err != nil { - log.Warn("Error reading unclean shutdown markers", "error", err) - } else if err := rlp.DecodeBytes(data, &uncleanShutdowns); err != nil { - log.Error("Error decoding unclean shutdown markers", "error", err) // Should mos def _not_ happen - } - if l := len(uncleanShutdowns.Recent); l > 0 { - uncleanShutdowns.Recent = uncleanShutdowns.Recent[:l-1] - } - data, _ := rlp.EncodeToBytes(uncleanShutdowns) - if err := db.Put(uncleanShutdownKey, data); err != nil { - log.Warn("Failed to clear unclean-shutdown marker", "err", err) - } -} - -// UpdateUncleanShutdownMarker updates the last marker's timestamp to now. -func UpdateUncleanShutdownMarker(db ethdb.KeyValueStore) { - var uncleanShutdowns crashList - // Read old data - if data, err := db.Get(uncleanShutdownKey); err != nil { - log.Warn("Error reading unclean shutdown markers", "error", err) - } else if err := rlp.DecodeBytes(data, &uncleanShutdowns); err != nil { - log.Warn("Error decoding unclean shutdown markers", "error", err) - } - // This shouldn't happen because we push a marker on Backend instantiation - count := len(uncleanShutdowns.Recent) - if count == 0 { - log.Warn("No unclean shutdown marker to update") - return - } - uncleanShutdowns.Recent[count-1] = uint64(time.Now().Unix()) - data, _ := rlp.EncodeToBytes(uncleanShutdowns) - if err := db.Put(uncleanShutdownKey, data); err != nil { - log.Warn("Failed to write unclean-shutdown marker", "err", err) - } -} - -// WriteTimeMarker writes a marker of the current time in the db at [key] -func WriteTimeMarker(db ethdb.KeyValueStore, key []byte) error { - data, err := rlp.EncodeToBytes(uint64(time.Now().Unix())) - if err != nil { - return err - } - return db.Put(key, data) -} - -// ReadTimeMarker reads the timestamp stored at [key] -func ReadTimeMarker(db ethdb.KeyValueStore, key []byte) (time.Time, error) { - data, err := db.Get(key) - if err != nil { - return time.Time{}, err - } - - var lastRun uint64 - if err := rlp.DecodeBytes(data, &lastRun); err != nil { - return time.Time{}, err - } - - return time.Unix(int64(lastRun), 0), nil -} - -// DeleteTimeMarker deletes any value stored at [key] -func DeleteTimeMarker(db ethdb.KeyValueStore, key []byte) error { - return db.Delete(key) -} - -// WriteOfflinePruning writes a marker of the last attempt to run offline pruning -// The marker is written when offline pruning completes and is deleted when the node -// is started successfully with offline pruning disabled. This ensures users must -// disable offline pruning and start their node successfully between runs of offline -// pruning. -func WriteOfflinePruning(db ethdb.KeyValueStore) error { - return WriteTimeMarker(db, offlinePruningKey) -} - -// ReadOfflinePruning reads the most recent timestamp of an attempt to run offline -// pruning if present. -func ReadOfflinePruning(db ethdb.KeyValueStore) (time.Time, error) { - return ReadTimeMarker(db, offlinePruningKey) -} - -// DeleteOfflinePruning deletes any marker of the last attempt to run offline pruning. -func DeleteOfflinePruning(db ethdb.KeyValueStore) error { - return DeleteTimeMarker(db, offlinePruningKey) -} - -// WritePopulateMissingTries writes a marker for the current attempt to populate -// missing tries. -func WritePopulateMissingTries(db ethdb.KeyValueStore) error { - return WriteTimeMarker(db, populateMissingTriesKey) -} - -// ReadPopulateMissingTries reads the most recent timestamp of an attempt to -// re-populate missing trie nodes. -func ReadPopulateMissingTries(db ethdb.KeyValueStore) (time.Time, error) { - return ReadTimeMarker(db, populateMissingTriesKey) -} - -// DeletePopulateMissingTries deletes any marker of the last attempt to -// re-populate missing trie nodes. -func DeletePopulateMissingTries(db ethdb.KeyValueStore) error { - return DeleteTimeMarker(db, populateMissingTriesKey) -} - -// WritePruningDisabled writes a marker to track whether the node has ever run -// with pruning disabled. -func WritePruningDisabled(db ethdb.KeyValueStore) error { - return db.Put(pruningDisabledKey, nil) -} - -// HasPruningDisabled returns true if there is a marker present indicating that -// the node has run with pruning disabled at some pooint. -func HasPruningDisabled(db ethdb.KeyValueStore) (bool, error) { - return db.Has(pruningDisabledKey) -} - -// DeletePruningDisabled deletes the marker indicating that the node has -// run with pruning disabled. -func DeletePruningDisabled(db ethdb.KeyValueStore) error { - return db.Delete(pruningDisabledKey) -} - -// WriteAcceptorTip writes [hash] as the last accepted block that has been fully processed. -func WriteAcceptorTip(db ethdb.KeyValueWriter, hash common.Hash) error { - return db.Put(acceptorTipKey, hash[:]) -} - -// ReadAcceptorTip reads the hash of the last accepted block that was fully processed. -// If there is no value present (the index is being initialized for the first time), then the -// empty hash is returned. -func ReadAcceptorTip(db ethdb.KeyValueReader) (common.Hash, error) { - has, err := db.Has(acceptorTipKey) - // If the index is not present on disk, the [acceptorTipKey] index has not been initialized yet. - if !has || err != nil { - return common.Hash{}, err - } - h, err := db.Get(acceptorTipKey) - if err != nil { - return common.Hash{}, err - } - return common.BytesToHash(h), nil -} diff --git a/core/rawdb/accessors_snapshot.go b/core/rawdb/accessors_snapshot.go deleted file mode 100644 index 06a136ba89..0000000000 --- a/core/rawdb/accessors_snapshot.go +++ /dev/null @@ -1,155 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" -) - -// ReadSnapshotRoot retrieves the root of the block whose state is contained in -// the persisted snapshot. -func ReadSnapshotRoot(db ethdb.KeyValueReader) common.Hash { - data, _ := db.Get(snapshotRootKey) - if len(data) != common.HashLength { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// WriteSnapshotRoot stores the root of the block whose state is contained in -// the persisted snapshot. -func WriteSnapshotRoot(db ethdb.KeyValueWriter, root common.Hash) { - if err := db.Put(snapshotRootKey, root[:]); err != nil { - log.Crit("Failed to store snapshot root", "err", err) - } -} - -// DeleteSnapshotRoot deletes the root of the block whose state is contained in -// the persisted snapshot. Since snapshots are not immutable, this method can -// be used during updates, so a crash or failure will mark the entire snapshot -// invalid. -func DeleteSnapshotRoot(db ethdb.KeyValueWriter) { - if err := db.Delete(snapshotRootKey); err != nil { - log.Crit("Failed to remove snapshot root", "err", err) - } -} - -// ReadSnapshotBlockHash retrieves the hash of the block whose state is contained in -// the persisted snapshot. -func ReadSnapshotBlockHash(db ethdb.KeyValueReader) common.Hash { - data, _ := db.Get(snapshotBlockHashKey) - if len(data) != common.HashLength { - return common.Hash{} - } - return common.BytesToHash(data) -} - -// WriteSnapshotBlockHash stores the root of the block whose state is contained in -// the persisted snapshot. -func WriteSnapshotBlockHash(db ethdb.KeyValueWriter, blockHash common.Hash) { - if err := db.Put(snapshotBlockHashKey, blockHash[:]); err != nil { - log.Crit("Failed to store snapshot block hash", "err", err) - } -} - -// DeleteSnapshotBlockHash deletes the hash of the block whose state is contained in -// the persisted snapshot. Since snapshots are not immutable, this method can -// be used during updates, so a crash or failure will mark the entire snapshot -// invalid. -func DeleteSnapshotBlockHash(db ethdb.KeyValueWriter) { - if err := db.Delete(snapshotBlockHashKey); err != nil { - log.Crit("Failed to remove snapshot block hash", "err", err) - } -} - -// ReadAccountSnapshot retrieves the snapshot entry of an account trie leaf. -func ReadAccountSnapshot(db ethdb.KeyValueReader, hash common.Hash) []byte { - data, _ := db.Get(accountSnapshotKey(hash)) - return data -} - -// WriteAccountSnapshot stores the snapshot entry of an account trie leaf. -func WriteAccountSnapshot(db ethdb.KeyValueWriter, hash common.Hash, entry []byte) { - if err := db.Put(accountSnapshotKey(hash), entry); err != nil { - log.Crit("Failed to store account snapshot", "err", err) - } -} - -// DeleteAccountSnapshot removes the snapshot entry of an account trie leaf. -func DeleteAccountSnapshot(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Delete(accountSnapshotKey(hash)); err != nil { - log.Crit("Failed to delete account snapshot", "err", err) - } -} - -// ReadStorageSnapshot retrieves the snapshot entry of an storage trie leaf. -func ReadStorageSnapshot(db ethdb.KeyValueReader, accountHash, storageHash common.Hash) []byte { - data, _ := db.Get(storageSnapshotKey(accountHash, storageHash)) - return data -} - -// WriteStorageSnapshot stores the snapshot entry of an storage trie leaf. -func WriteStorageSnapshot(db ethdb.KeyValueWriter, accountHash, storageHash common.Hash, entry []byte) { - if err := db.Put(storageSnapshotKey(accountHash, storageHash), entry); err != nil { - log.Crit("Failed to store storage snapshot", "err", err) - } -} - -// DeleteStorageSnapshot removes the snapshot entry of an storage trie leaf. -func DeleteStorageSnapshot(db ethdb.KeyValueWriter, accountHash, storageHash common.Hash) { - if err := db.Delete(storageSnapshotKey(accountHash, storageHash)); err != nil { - log.Crit("Failed to delete storage snapshot", "err", err) - } -} - -// IterateStorageSnapshots returns an iterator for walking the entire storage -// space of a specific account. -func IterateStorageSnapshots(db ethdb.Iteratee, accountHash common.Hash) ethdb.Iterator { - return NewKeyLengthIterator(db.NewIterator(storageSnapshotsKey(accountHash), nil), len(SnapshotStoragePrefix)+2*common.HashLength) -} - -// IterateAccountSnapshots returns an iterator for walking all of the accounts in the snapshot -func IterateAccountSnapshots(db ethdb.Iteratee) ethdb.Iterator { - return NewKeyLengthIterator(db.NewIterator(SnapshotAccountPrefix, nil), len(SnapshotAccountPrefix)+common.HashLength) -} - -// ReadSnapshotGenerator retrieves the serialized snapshot generator saved at -// the last shutdown. -func ReadSnapshotGenerator(db ethdb.KeyValueReader) []byte { - data, _ := db.Get(snapshotGeneratorKey) - return data -} - -// WriteSnapshotGenerator stores the serialized snapshot generator to save at -// shutdown. -func WriteSnapshotGenerator(db ethdb.KeyValueWriter, generator []byte) { - if err := db.Put(snapshotGeneratorKey, generator); err != nil { - log.Crit("Failed to store snapshot generator", "err", err) - } -} diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go deleted file mode 100644 index 03cbf44b6c..0000000000 --- a/core/rawdb/accessors_state.go +++ /dev/null @@ -1,146 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "encoding/binary" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" -) - -// ReadPreimage retrieves a single preimage of the provided hash. -func ReadPreimage(db ethdb.KeyValueReader, hash common.Hash) []byte { - data, _ := db.Get(preimageKey(hash)) - return data -} - -// WritePreimages writes the provided set of preimages to the database. -func WritePreimages(db ethdb.KeyValueWriter, preimages map[common.Hash][]byte) { - for hash, preimage := range preimages { - if err := db.Put(preimageKey(hash), preimage); err != nil { - log.Crit("Failed to store trie preimage", "err", err) - } - } - preimageCounter.Inc(int64(len(preimages))) - preimageHitCounter.Inc(int64(len(preimages))) -} - -// ReadCode retrieves the contract code of the provided code hash. -func ReadCode(db ethdb.KeyValueReader, hash common.Hash) []byte { - // Try with the prefixed code scheme first and only. The legacy scheme was never used in coreth. - data, _ := db.Get(codeKey(hash)) - return data -} - -// HasCode checks if the contract code corresponding to the -// provided code hash is present in the db. -func HasCode(db ethdb.KeyValueReader, hash common.Hash) bool { - // Try with the prefixed code scheme first and only. The legacy scheme was never used in coreth. - ok, _ := db.Has(codeKey(hash)) - return ok -} - -// WriteCode writes the provided contract code database. -func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) { - if err := db.Put(codeKey(hash), code); err != nil { - log.Crit("Failed to store contract code", "err", err) - } -} - -// DeleteCode deletes the specified contract code from the database. -func DeleteCode(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Delete(codeKey(hash)); err != nil { - log.Crit("Failed to delete contract code", "err", err) - } -} - -// ReadStateID retrieves the state id with the provided state root. -func ReadStateID(db ethdb.KeyValueReader, root common.Hash) *uint64 { - data, err := db.Get(stateIDKey(root)) - if err != nil || len(data) == 0 { - return nil - } - number := binary.BigEndian.Uint64(data) - return &number -} - -// WriteStateID writes the provided state lookup to database. -func WriteStateID(db ethdb.KeyValueWriter, root common.Hash, id uint64) { - var buff [8]byte - binary.BigEndian.PutUint64(buff[:], id) - if err := db.Put(stateIDKey(root), buff[:]); err != nil { - log.Crit("Failed to store state ID", "err", err) - } -} - -// DeleteStateID deletes the specified state lookup from the database. -func DeleteStateID(db ethdb.KeyValueWriter, root common.Hash) { - if err := db.Delete(stateIDKey(root)); err != nil { - log.Crit("Failed to delete state ID", "err", err) - } -} - -// ReadPersistentStateID retrieves the id of the persistent state from the database. -func ReadPersistentStateID(db ethdb.KeyValueReader) uint64 { - data, _ := db.Get(persistentStateIDKey) - if len(data) != 8 { - return 0 - } - return binary.BigEndian.Uint64(data) -} - -// WritePersistentStateID stores the id of the persistent state into database. -func WritePersistentStateID(db ethdb.KeyValueWriter, number uint64) { - if err := db.Put(persistentStateIDKey, encodeBlockNumber(number)); err != nil { - log.Crit("Failed to store the persistent state ID", "err", err) - } -} - -// ReadTrieJournal retrieves the serialized in-memory trie nodes of layers saved at -// the last shutdown. -func ReadTrieJournal(db ethdb.KeyValueReader) []byte { - data, _ := db.Get(trieJournalKey) - return data -} - -// WriteTrieJournal stores the serialized in-memory trie nodes of layers to save at -// shutdown. -func WriteTrieJournal(db ethdb.KeyValueWriter, journal []byte) { - if err := db.Put(trieJournalKey, journal); err != nil { - log.Crit("Failed to store tries journal", "err", err) - } -} - -// DeleteTrieJournal deletes the serialized in-memory trie nodes of layers saved at -// the last shutdown. -func DeleteTrieJournal(db ethdb.KeyValueWriter) { - if err := db.Delete(trieJournalKey); err != nil { - log.Crit("Failed to remove tries journal", "err", err) - } -} diff --git a/core/rawdb/accessors_trie.go b/core/rawdb/accessors_trie.go deleted file mode 100644 index e148a4280b..0000000000 --- a/core/rawdb/accessors_trie.go +++ /dev/null @@ -1,357 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see - -package rawdb - -import ( - "fmt" - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "golang.org/x/crypto/sha3" -) - -// HashScheme is the legacy hash-based state scheme with which trie nodes are -// stored in the disk with node hash as the database key. The advantage of this -// scheme is that different versions of trie nodes can be stored in disk, which -// is very beneficial for constructing archive nodes. The drawback is it will -// store different trie nodes on the same path to different locations on the disk -// with no data locality, and it's unfriendly for designing state pruning. -// -// Now this scheme is still kept for backward compatibility, and it will be used -// for archive node and some other tries(e.g. light trie). -const HashScheme = "hash" - -// PathScheme is the new path-based state scheme with which trie nodes are stored -// in the disk with node path as the database key. This scheme will only store one -// version of state data in the disk, which means that the state pruning operation -// is native. At the same time, this scheme will put adjacent trie nodes in the same -// area of the disk with good data locality property. But this scheme needs to rely -// on extra state diffs to survive deep reorg. -const PathScheme = "path" - -// hasher is used to compute the sha256 hash of the provided data. -type hasher struct{ sha crypto.KeccakState } - -var hasherPool = sync.Pool{ - New: func() interface{} { return &hasher{sha: sha3.NewLegacyKeccak256().(crypto.KeccakState)} }, -} - -func newHasher() *hasher { - return hasherPool.Get().(*hasher) -} - -func (h *hasher) hash(data []byte) common.Hash { - return crypto.HashData(h.sha, data) -} - -func (h *hasher) release() { - hasherPool.Put(h) -} - -// ReadAccountTrieNode retrieves the account trie node and the associated node -// hash with the specified node path. -func ReadAccountTrieNode(db ethdb.KeyValueReader, path []byte) ([]byte, common.Hash) { - data, err := db.Get(accountTrieNodeKey(path)) - if err != nil { - return nil, common.Hash{} - } - h := newHasher() - defer h.release() - return data, h.hash(data) -} - -// HasAccountTrieNode checks the account trie node presence with the specified -// node path and the associated node hash. -func HasAccountTrieNode(db ethdb.KeyValueReader, path []byte, hash common.Hash) bool { - data, err := db.Get(accountTrieNodeKey(path)) - if err != nil { - return false - } - h := newHasher() - defer h.release() - return h.hash(data) == hash -} - -// ExistsAccountTrieNode checks the presence of the account trie node with the -// specified node path, regardless of the node hash. -func ExistsAccountTrieNode(db ethdb.KeyValueReader, path []byte) bool { - has, err := db.Has(accountTrieNodeKey(path)) - if err != nil { - return false - } - return has -} - -// WriteAccountTrieNode writes the provided account trie node into database. -func WriteAccountTrieNode(db ethdb.KeyValueWriter, path []byte, node []byte) { - if err := db.Put(accountTrieNodeKey(path), node); err != nil { - log.Crit("Failed to store account trie node", "err", err) - } -} - -// DeleteAccountTrieNode deletes the specified account trie node from the database. -func DeleteAccountTrieNode(db ethdb.KeyValueWriter, path []byte) { - if err := db.Delete(accountTrieNodeKey(path)); err != nil { - log.Crit("Failed to delete account trie node", "err", err) - } -} - -// ReadStorageTrieNode retrieves the storage trie node and the associated node -// hash with the specified node path. -func ReadStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) ([]byte, common.Hash) { - data, err := db.Get(storageTrieNodeKey(accountHash, path)) - if err != nil { - return nil, common.Hash{} - } - h := newHasher() - defer h.release() - return data, h.hash(data) -} - -// HasStorageTrieNode checks the storage trie node presence with the provided -// node path and the associated node hash. -func HasStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte, hash common.Hash) bool { - data, err := db.Get(storageTrieNodeKey(accountHash, path)) - if err != nil { - return false - } - h := newHasher() - defer h.release() - return h.hash(data) == hash -} - -// ExistsStorageTrieNode checks the presence of the storage trie node with the -// specified account hash and node path, regardless of the node hash. -func ExistsStorageTrieNode(db ethdb.KeyValueReader, accountHash common.Hash, path []byte) bool { - has, err := db.Has(storageTrieNodeKey(accountHash, path)) - if err != nil { - return false - } - return has -} - -// WriteStorageTrieNode writes the provided storage trie node into database. -func WriteStorageTrieNode(db ethdb.KeyValueWriter, accountHash common.Hash, path []byte, node []byte) { - if err := db.Put(storageTrieNodeKey(accountHash, path), node); err != nil { - log.Crit("Failed to store storage trie node", "err", err) - } -} - -// DeleteStorageTrieNode deletes the specified storage trie node from the database. -func DeleteStorageTrieNode(db ethdb.KeyValueWriter, accountHash common.Hash, path []byte) { - if err := db.Delete(storageTrieNodeKey(accountHash, path)); err != nil { - log.Crit("Failed to delete storage trie node", "err", err) - } -} - -// ReadLegacyTrieNode retrieves the legacy trie node with the given -// associated node hash. -func ReadLegacyTrieNode(db ethdb.KeyValueReader, hash common.Hash) []byte { - data, err := db.Get(hash.Bytes()) - if err != nil { - return nil - } - return data -} - -// HasLegacyTrieNode checks if the trie node with the provided hash is present in db. -func HasLegacyTrieNode(db ethdb.KeyValueReader, hash common.Hash) bool { - ok, _ := db.Has(hash.Bytes()) - return ok -} - -// WriteLegacyTrieNode writes the provided legacy trie node to database. -func WriteLegacyTrieNode(db ethdb.KeyValueWriter, hash common.Hash, node []byte) { - if err := db.Put(hash.Bytes(), node); err != nil { - log.Crit("Failed to store legacy trie node", "err", err) - } -} - -// DeleteLegacyTrieNode deletes the specified legacy trie node from database. -func DeleteLegacyTrieNode(db ethdb.KeyValueWriter, hash common.Hash) { - if err := db.Delete(hash.Bytes()); err != nil { - log.Crit("Failed to delete legacy trie node", "err", err) - } -} - -// HasTrieNode checks the trie node presence with the provided node info and -// the associated node hash. -func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash common.Hash, scheme string) bool { - switch scheme { - case HashScheme: - return HasLegacyTrieNode(db, hash) - case PathScheme: - if owner == (common.Hash{}) { - return HasAccountTrieNode(db, path, hash) - } - return HasStorageTrieNode(db, owner, path, hash) - default: - panic(fmt.Sprintf("Unknown scheme %v", scheme)) - } -} - -// ReadTrieNode retrieves the trie node from database with the provided node info -// and associated node hash. -// hashScheme-based lookup requires the following: -// - hash -// -// pathScheme-based lookup requires the following: -// - owner -// - path -func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash common.Hash, scheme string) []byte { - switch scheme { - case HashScheme: - return ReadLegacyTrieNode(db, hash) - case PathScheme: - var ( - blob []byte - nHash common.Hash - ) - if owner == (common.Hash{}) { - blob, nHash = ReadAccountTrieNode(db, path) - } else { - blob, nHash = ReadStorageTrieNode(db, owner, path) - } - if nHash != hash { - return nil - } - return blob - default: - panic(fmt.Sprintf("Unknown scheme %v", scheme)) - } -} - -// WriteTrieNode writes the trie node into database with the provided node info -// and associated node hash. -// hashScheme-based lookup requires the following: -// - hash -// -// pathScheme-based lookup requires the following: -// - owner -// - path -func WriteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash common.Hash, node []byte, scheme string) { - switch scheme { - case HashScheme: - WriteLegacyTrieNode(db, hash, node) - case PathScheme: - if owner == (common.Hash{}) { - WriteAccountTrieNode(db, path, node) - } else { - WriteStorageTrieNode(db, owner, path, node) - } - default: - panic(fmt.Sprintf("Unknown scheme %v", scheme)) - } -} - -// DeleteTrieNode deletes the trie node from database with the provided node info -// and associated node hash. -// hashScheme-based lookup requires the following: -// - hash -// -// pathScheme-based lookup requires the following: -// - owner -// - path -func DeleteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, hash common.Hash, scheme string) { - switch scheme { - case HashScheme: - DeleteLegacyTrieNode(db, hash) - case PathScheme: - if owner == (common.Hash{}) { - DeleteAccountTrieNode(db, path) - } else { - DeleteStorageTrieNode(db, owner, path) - } - default: - panic(fmt.Sprintf("Unknown scheme %v", scheme)) - } -} - -// ReadStateScheme reads the state scheme of persistent state, or none -// if the state is not present in database. -func ReadStateScheme(db ethdb.Reader) string { - // Check if state in path-based scheme is present - blob, _ := ReadAccountTrieNode(db, nil) - if len(blob) != 0 { - return PathScheme - } - // The root node might be deleted during the initial snap sync, check - // the persistent state id then. - if id := ReadPersistentStateID(db); id != 0 { - return PathScheme - } - // In a hash-based scheme, the genesis state is consistently stored - // on the disk. To assess the scheme of the persistent state, it - // suffices to inspect the scheme of the genesis state. - header := ReadHeader(db, ReadCanonicalHash(db, 0), 0) - if header == nil { - return "" // empty datadir - } - blob = ReadLegacyTrieNode(db, header.Root) - if len(blob) == 0 { - return "" // no state in disk - } - return HashScheme -} - -// ParseStateScheme checks if the specified state scheme is compatible with -// the stored state. -// -// - If the provided scheme is none, use the scheme consistent with persistent -// state, or fallback to hash-based scheme if state is empty. -// -// - If the provided scheme is hash, use hash-based scheme or error out if not -// compatible with persistent state scheme. -// -// - If the provided scheme is path: use path-based scheme or error out if not -// compatible with persistent state scheme. -func ParseStateScheme(provided string, disk ethdb.Database) (string, error) { - // If state scheme is not specified, use the scheme consistent - // with persistent state, or fallback to hash mode if database - // is empty. - stored := ReadStateScheme(disk) - if provided == "" { - if stored == "" { - // use default scheme for empty database, flip it when - // path mode is chosen as default - log.Info("State schema set to default", "scheme", "hash") - return HashScheme, nil - } - log.Info("State scheme set to already existing", "scheme", stored) - return stored, nil // reuse scheme of persistent scheme - } - // If state scheme is specified, ensure it's compatible with - // persistent state. - if stored == "" || provided == stored { - log.Info("State scheme set by user", "scheme", provided) - return provided, nil - } - return "", fmt.Errorf("incompatible state scheme, stored: %s, provided: %s", stored, provided) -} diff --git a/core/rawdb/chain_iterator.go b/core/rawdb/chain_iterator.go deleted file mode 100644 index 5f449e4b6c..0000000000 --- a/core/rawdb/chain_iterator.go +++ /dev/null @@ -1,320 +0,0 @@ -// (c) 2019-2022, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "runtime" - "sync/atomic" - "time" - - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/prque" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" -) - -type blockTxHashes struct { - number uint64 - hashes []common.Hash -} - -// iterateTransactions iterates over all transactions in the (canon) block -// number(s) given, and yields the hashes on a channel. If there is a signal -// received from interrupt channel, the iteration will be aborted and result -// channel will be closed. -// Iterates blocks in the range [from, to) -func iterateTransactions(db ethdb.Database, from uint64, to uint64, reverse bool, interrupt chan struct{}) chan *blockTxHashes { - // One thread sequentially reads data from db - type numberRlp struct { - number uint64 - rlp rlp.RawValue - } - if to == from { - return nil - } - threads := to - from - if cpus := runtime.NumCPU(); threads > uint64(cpus) { - threads = uint64(cpus) - } - var ( - rlpCh = make(chan *numberRlp, threads*2) // we send raw rlp over this channel - hashesCh = make(chan *blockTxHashes, threads*2) // send hashes over hashesCh - ) - // lookup runs in one instance - lookup := func() { - n, end := from, to - if reverse { - n, end = to-1, from-1 - } - defer close(rlpCh) - for n != end { - data := ReadCanonicalBodyRLP(db, n) - // Feed the block to the aggregator, or abort on interrupt - select { - case rlpCh <- &numberRlp{n, data}: - case <-interrupt: - return - } - if reverse { - n-- - } else { - n++ - } - } - } - // process runs in parallel - var nThreadsAlive atomic.Int32 - nThreadsAlive.Store(int32(threads)) - process := func() { - defer func() { - // Last processor closes the result channel - if nThreadsAlive.Add(-1) == 0 { - close(hashesCh) - } - }() - for data := range rlpCh { - var body types.Body - if err := rlp.DecodeBytes(data.rlp, &body); err != nil { - log.Warn("Failed to decode block body", "block", data.number, "error", err) - return - } - var hashes []common.Hash - for _, tx := range body.Transactions { - hashes = append(hashes, tx.Hash()) - } - result := &blockTxHashes{ - hashes: hashes, - number: data.number, - } - // Feed the block to the aggregator, or abort on interrupt - select { - case hashesCh <- result: - case <-interrupt: - return - } - } - } - go lookup() // start the sequential db accessor - for i := 0; i < int(threads); i++ { - go process() - } - return hashesCh -} - -// indexTransactions creates txlookup indices of the specified block range. -// -// This function iterates canonical chain in reverse order, it has one main advantage: -// We can write tx index tail flag periodically even without the whole indexing -// procedure is finished. So that we can resume indexing procedure next time quickly. -// -// There is a passed channel, the whole procedure will be interrupted if any -// signal received. -func indexTransactions(db ethdb.Database, from uint64, to uint64, interrupt chan struct{}, hook func(uint64) bool, report bool) { - // short circuit for invalid range - if from >= to { - return - } - var ( - hashesCh = iterateTransactions(db, from, to, true, interrupt) - batch = db.NewBatch() - start = time.Now() - logged = start.Add(-7 * time.Second) - - // Since we iterate in reverse, we expect the first number to come - // in to be [to-1]. Therefore, setting lastNum to means that the - // queue gap-evaluation will work correctly - lastNum = to - queue = prque.New[int64, *blockTxHashes](nil) - blocks, txs = 0, 0 // for stats reporting - ) - for chanDelivery := range hashesCh { - // Push the delivery into the queue and process contiguous ranges. - // Since we iterate in reverse, so lower numbers have lower prio, and - // we can use the number directly as prio marker - queue.Push(chanDelivery, int64(chanDelivery.number)) - for !queue.Empty() { - // If the next available item is gapped, return - if _, priority := queue.Peek(); priority != int64(lastNum-1) { - break - } - // For testing - if hook != nil && !hook(lastNum-1) { - break - } - // Next block available, pop it off and index it - delivery := queue.PopItem() - lastNum = delivery.number - WriteTxLookupEntries(batch, delivery.number, delivery.hashes) - blocks++ - txs += len(delivery.hashes) - // If enough data was accumulated in memory or we're at the last block, dump to disk - if batch.ValueSize() > ethdb.IdealBatchSize { - WriteTxIndexTail(batch, lastNum) // Also write the tail here - if err := batch.Write(); err != nil { - log.Crit("Failed writing batch to db", "error", err) - return - } - batch.Reset() - } - // If we've spent too much time already, notify the user of what we're doing - if time.Since(logged) > 8*time.Second { - log.Info("Indexing transactions", "blocks", blocks, "txs", txs, "tail", lastNum, "total", to-from, "elapsed", common.PrettyDuration(time.Since(start))) - logged = time.Now() - } - } - } - // Flush the new indexing tail and the last committed data. It can also happen - // that the last batch is empty because nothing to index, but the tail has to - // be flushed anyway. - WriteTxIndexTail(batch, lastNum) - if err := batch.Write(); err != nil { - log.Crit("Failed writing batch to db", "error", err) - return - } - logger := log.Debug - if report { - logger = log.Info - } - select { - case <-interrupt: - logger("Transaction indexing interrupted", "blocks", blocks, "txs", txs, "tail", lastNum, "elapsed", common.PrettyDuration(time.Since(start))) - default: - logger("Indexed transactions", "blocks", blocks, "txs", txs, "tail", lastNum, "elapsed", common.PrettyDuration(time.Since(start))) - } -} - -// IndexTransactions creates txlookup indices of the specified block range. The from -// is included while to is excluded. -// -// This function iterates canonical chain in reverse order, it has one main advantage: -// We can write tx index tail flag periodically even without the whole indexing -// procedure is finished. So that we can resume indexing procedure next time quickly. -// -// There is a passed channel, the whole procedure will be interrupted if any -// signal received. -func IndexTransactions(db ethdb.Database, from uint64, to uint64, interrupt chan struct{}, report bool) { - indexTransactions(db, from, to, interrupt, nil, report) -} - -// indexTransactionsForTesting is the internal debug version with an additional hook. -func indexTransactionsForTesting(db ethdb.Database, from uint64, to uint64, interrupt chan struct{}, hook func(uint64) bool) { - indexTransactions(db, from, to, interrupt, hook, false) -} - -// unindexTransactions removes txlookup indices of the specified block range. -// -// There is a passed channel, the whole procedure will be interrupted if any -// signal received. -func unindexTransactions(db ethdb.Database, from uint64, to uint64, interrupt chan struct{}, hook func(uint64) bool, report bool) { - // short circuit for invalid range - if from >= to { - return - } - var ( - hashesCh = iterateTransactions(db, from, to, false, interrupt) - batch = db.NewBatch() - start = time.Now() - logged = start.Add(-7 * time.Second) - - // we expect the first number to come in to be [from]. Therefore, setting - // nextNum to from means that the queue gap-evaluation will work correctly - nextNum = from - queue = prque.New[int64, *blockTxHashes](nil) - blocks, txs = 0, 0 // for stats reporting - ) - // Otherwise spin up the concurrent iterator and unindexer - for delivery := range hashesCh { - // Push the delivery into the queue and process contiguous ranges. - queue.Push(delivery, -int64(delivery.number)) - for !queue.Empty() { - // If the next available item is gapped, return - if _, priority := queue.Peek(); -priority != int64(nextNum) { - break - } - // For testing - if hook != nil && !hook(nextNum) { - break - } - delivery := queue.PopItem() - nextNum = delivery.number + 1 - DeleteTxLookupEntries(batch, delivery.hashes) - txs += len(delivery.hashes) - blocks++ - - // If enough data was accumulated in memory or we're at the last block, dump to disk - // A batch counts the size of deletion as '1', so we need to flush more - // often than that. - if blocks%1000 == 0 { - WriteTxIndexTail(batch, nextNum) - if err := batch.Write(); err != nil { - log.Crit("Failed writing batch to db", "error", err) - return - } - batch.Reset() - } - // If we've spent too much time already, notify the user of what we're doing - if time.Since(logged) > 8*time.Second { - log.Info("Unindexing transactions", "blocks", blocks, "txs", txs, "total", to-from, "elapsed", common.PrettyDuration(time.Since(start))) - logged = time.Now() - } - } - } - // Flush the new indexing tail and the last committed data. It can also happen - // that the last batch is empty because nothing to unindex, but the tail has to - // be flushed anyway. - WriteTxIndexTail(batch, nextNum) - if err := batch.Write(); err != nil { - log.Crit("Failed writing batch to db", "error", err) - return - } - logger := log.Debug - if report { - logger = log.Info - } - select { - case <-interrupt: - logger("Transaction unindexing interrupted", "blocks", blocks, "txs", txs, "tail", to, "elapsed", common.PrettyDuration(time.Since(start))) - default: - logger("Unindexed transactions", "blocks", blocks, "txs", txs, "tail", to, "elapsed", common.PrettyDuration(time.Since(start))) - } -} - -// UnindexTransactions removes txlookup indices of the specified block range. -// The from is included while to is excluded. -// -// There is a passed channel, the whole procedure will be interrupted if any -// signal received. -func UnindexTransactions(db ethdb.Database, from uint64, to uint64, interrupt chan struct{}, report bool) { - unindexTransactions(db, from, to, interrupt, nil, report) -} - -// unindexTransactionsForTesting is the internal debug version with an additional hook. -func unindexTransactionsForTesting(db ethdb.Database, from uint64, to uint64, interrupt chan struct{}, hook func(uint64) bool) { - unindexTransactions(db, from, to, interrupt, hook, false) -} diff --git a/core/rawdb/chain_iterator_test.go b/core/rawdb/chain_iterator_test.go deleted file mode 100644 index 0e4e762789..0000000000 --- a/core/rawdb/chain_iterator_test.go +++ /dev/null @@ -1,218 +0,0 @@ -// (c) 2019-2022, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "math/big" - "reflect" - "sort" - "sync" - "testing" - - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" -) - -func TestChainIterator(t *testing.T) { - // Construct test chain db - chainDb := NewMemoryDatabase() - - var block *types.Block - var txs []*types.Transaction - to := common.BytesToAddress([]byte{0x11}) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, nil, newTestHasher()) // Empty genesis block - WriteBlock(chainDb, block) - WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) - for i := uint64(1); i <= 10; i++ { - var tx *types.Transaction - if i%2 == 0 { - tx = types.NewTx(&types.LegacyTx{ - Nonce: i, - GasPrice: big.NewInt(11111), - Gas: 1111, - To: &to, - Value: big.NewInt(111), - Data: []byte{0x11, 0x11, 0x11}, - }) - } else { - tx = types.NewTx(&types.AccessListTx{ - ChainID: big.NewInt(1337), - Nonce: i, - GasPrice: big.NewInt(11111), - Gas: 1111, - To: &to, - Value: big.NewInt(111), - Data: []byte{0x11, 0x11, 0x11}, - }) - } - txs = append(txs, tx) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, []*types.Transaction{tx}, nil, nil, newTestHasher()) - WriteBlock(chainDb, block) - WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) - } - - var cases = []struct { - from, to uint64 - reverse bool - expect []int - }{ - {0, 11, true, []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}}, - {0, 0, true, nil}, - {0, 5, true, []int{4, 3, 2, 1, 0}}, - {10, 11, true, []int{10}}, - {0, 11, false, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}, - {0, 0, false, nil}, - {10, 11, false, []int{10}}, - } - for i, c := range cases { - var numbers []int - hashCh := iterateTransactions(chainDb, c.from, c.to, c.reverse, nil) - if hashCh != nil { - for h := range hashCh { - numbers = append(numbers, int(h.number)) - if len(h.hashes) > 0 { - if got, exp := h.hashes[0], txs[h.number-1].Hash(); got != exp { - t.Fatalf("block %d: hash wrong, got %x exp %x", h.number, got, exp) - } - } - } - } - if !c.reverse { - sort.Ints(numbers) - } else { - sort.Sort(sort.Reverse(sort.IntSlice(numbers))) - } - if !reflect.DeepEqual(numbers, c.expect) { - t.Fatalf("Case %d failed, visit element mismatch, want %v, got %v", i, c.expect, numbers) - } - } -} - -func TestIndexTransactions(t *testing.T) { - // Construct test chain db - chainDb := NewMemoryDatabase() - - var block *types.Block - var txs []*types.Transaction - to := common.BytesToAddress([]byte{0x11}) - - // Write empty genesis block - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(0))}, nil, nil, nil, newTestHasher()) - WriteBlock(chainDb, block) - WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) - - for i := uint64(1); i <= 10; i++ { - var tx *types.Transaction - if i%2 == 0 { - tx = types.NewTx(&types.LegacyTx{ - Nonce: i, - GasPrice: big.NewInt(11111), - Gas: 1111, - To: &to, - Value: big.NewInt(111), - Data: []byte{0x11, 0x11, 0x11}, - }) - } else { - tx = types.NewTx(&types.AccessListTx{ - ChainID: big.NewInt(1337), - Nonce: i, - GasPrice: big.NewInt(11111), - Gas: 1111, - To: &to, - Value: big.NewInt(111), - Data: []byte{0x11, 0x11, 0x11}, - }) - } - txs = append(txs, tx) - block = types.NewBlock(&types.Header{Number: big.NewInt(int64(i))}, []*types.Transaction{tx}, nil, nil, newTestHasher()) - WriteBlock(chainDb, block) - WriteCanonicalHash(chainDb, block.Hash(), block.NumberU64()) - } - // verify checks whether the tx indices in the range [from, to) - // is expected. - verify := func(from, to int, exist bool, tail uint64) { - for i := from; i < to; i++ { - if i == 0 { - continue - } - number := ReadTxLookupEntry(chainDb, txs[i-1].Hash()) - if exist && number == nil { - t.Fatalf("Transaction index %d missing", i) - } - if !exist && number != nil { - t.Fatalf("Transaction index %d is not deleted", i) - } - } - number := ReadTxIndexTail(chainDb) - if number == nil || *number != tail { - t.Fatalf("Transaction tail mismatch") - } - } - IndexTransactions(chainDb, 5, 11, nil, false) - verify(5, 11, true, 5) - verify(0, 5, false, 5) - - IndexTransactions(chainDb, 0, 5, nil, false) - verify(0, 11, true, 0) - - UnindexTransactions(chainDb, 0, 5, nil, false) - verify(5, 11, true, 5) - verify(0, 5, false, 5) - - UnindexTransactions(chainDb, 5, 11, nil, false) - verify(0, 11, false, 11) - - // Testing corner cases - signal := make(chan struct{}) - var once sync.Once - indexTransactionsForTesting(chainDb, 5, 11, signal, func(n uint64) bool { - if n <= 8 { - once.Do(func() { - close(signal) - }) - return false - } - return true - }) - verify(9, 11, true, 9) - verify(0, 9, false, 9) - IndexTransactions(chainDb, 0, 9, nil, false) - - signal = make(chan struct{}) - var once2 sync.Once - unindexTransactionsForTesting(chainDb, 0, 11, signal, func(n uint64) bool { - if n >= 8 { - once2.Do(func() { - close(signal) - }) - return false - } - return true - }) - verify(8, 11, true, 8) - verify(0, 8, false, 8) -} diff --git a/core/rawdb/database.go b/core/rawdb/database.go deleted file mode 100644 index 75922eba5d..0000000000 --- a/core/rawdb/database.go +++ /dev/null @@ -1,462 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/ethdb/leveldb" - "github.com/ethereum/go-ethereum/ethdb/memorydb" - "github.com/ethereum/go-ethereum/ethdb/pebble" - "github.com/ethereum/go-ethereum/log" - "github.com/olekukonko/tablewriter" -) - -// nofreezedb is a database wrapper that disables freezer data retrievals. -type nofreezedb struct { - ethdb.KeyValueStore -} - -// HasAncient returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) HasAncient(kind string, number uint64) (bool, error) { - return false, errNotSupported -} - -// Ancient returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) Ancient(kind string, number uint64) ([]byte, error) { - return nil, errNotSupported -} - -// AncientRange returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) AncientRange(kind string, start, max, maxByteSize uint64) ([][]byte, error) { - return nil, errNotSupported -} - -// Ancients returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) Ancients() (uint64, error) { - return 0, errNotSupported -} - -// Tail returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) Tail() (uint64, error) { - return 0, errNotSupported -} - -// AncientSize returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) AncientSize(kind string) (uint64, error) { - return 0, errNotSupported -} - -// ModifyAncients is not supported. -func (db *nofreezedb) ModifyAncients(func(ethdb.AncientWriteOp) error) (int64, error) { - return 0, errNotSupported -} - -// TruncateHead returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) TruncateHead(items uint64) (uint64, error) { - return 0, errNotSupported -} - -// TruncateTail returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) TruncateTail(items uint64) (uint64, error) { - return 0, errNotSupported -} - -// Sync returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) Sync() error { - return errNotSupported -} - -func (db *nofreezedb) ReadAncients(fn func(reader ethdb.AncientReaderOp) error) (err error) { - // Unlike other ancient-related methods, this method does not return - // errNotSupported when invoked. - // The reason for this is that the caller might want to do several things: - // 1. Check if something is in the freezer, - // 2. If not, check leveldb. - // - // This will work, since the ancient-checks inside 'fn' will return errors, - // and the leveldb work will continue. - // - // If we instead were to return errNotSupported here, then the caller would - // have to explicitly check for that, having an extra clause to do the - // non-ancient operations. - return fn(db) -} - -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (db *nofreezedb) MigrateTable(kind string, convert convertLegacyFn) error { - return errNotSupported -} - -// AncientDatadir returns an error as we don't have a backing chain freezer. -func (db *nofreezedb) AncientDatadir() (string, error) { - return "", errNotSupported -} - -// NewDatabase creates a high level database on top of a given key-value data -// store without a freezer moving immutable chain segments into cold storage. -func NewDatabase(db ethdb.KeyValueStore) ethdb.Database { - return &nofreezedb{KeyValueStore: db} -} - -// NewMemoryDatabase creates an ephemeral in-memory key-value database without a -// freezer moving immutable chain segments into cold storage. -func NewMemoryDatabase() ethdb.Database { - return NewDatabase(memorydb.New()) -} - -// NewMemoryDatabaseWithCap creates an ephemeral in-memory key-value database -// with an initial starting capacity, but without a freezer moving immutable -// chain segments into cold storage. -func NewMemoryDatabaseWithCap(size int) ethdb.Database { - return NewDatabase(memorydb.NewWithCap(size)) -} - -// NewLevelDBDatabase creates a persistent key-value database without a freezer -// moving immutable chain segments into cold storage. -func NewLevelDBDatabase(file string, cache int, handles int, namespace string, readonly bool) (ethdb.Database, error) { - db, err := leveldb.New(file, cache, handles, namespace, readonly) - if err != nil { - return nil, err - } - log.Info("Using LevelDB as the backing database") - return NewDatabase(db), nil -} - -// NewPebbleDBDatabase creates a persistent key-value database without a freezer -// moving immutable chain segments into cold storage. -func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly, ephemeral bool) (ethdb.Database, error) { - db, err := pebble.New(file, cache, handles, namespace, readonly, ephemeral) - if err != nil { - return nil, err - } - return NewDatabase(db), nil -} - -const ( - dbPebble = "pebble" - dbLeveldb = "leveldb" -) - -// PreexistingDatabase checks the given data directory whether a database is already -// instantiated at that location, and if so, returns the type of database (or the -// empty string). -func PreexistingDatabase(path string) string { - if _, err := os.Stat(filepath.Join(path, "CURRENT")); err != nil { - return "" // No pre-existing db - } - if matches, err := filepath.Glob(filepath.Join(path, "OPTIONS*")); len(matches) > 0 || err != nil { - if err != nil { - panic(err) // only possible if the pattern is malformed - } - return dbPebble - } - return dbLeveldb -} - -// OpenOptions contains the options to apply when opening a database. -// OBS: If AncientsDirectory is empty, it indicates that no freezer is to be used. -type OpenOptions struct { - Type string // "leveldb" | "pebble" - Directory string // the datadir - Namespace string // the namespace for database relevant metrics - Cache int // the capacity(in megabytes) of the data caching - Handles int // number of files to be open simultaneously - ReadOnly bool - // Ephemeral means that filesystem sync operations should be avoided: data integrity in the face of - // a crash is not important. This option should typically be used in tests. - Ephemeral bool -} - -// openKeyValueDatabase opens a disk-based key-value database, e.g. leveldb or pebble. -// -// type == null type != null -// +---------------------------------------- -// db is non-existent | pebble default | specified type -// db is existent | from db | specified type (if compatible) -func openKeyValueDatabase(o OpenOptions) (ethdb.Database, error) { - // Reject any unsupported database type - if len(o.Type) != 0 && o.Type != dbLeveldb && o.Type != dbPebble { - return nil, fmt.Errorf("unknown db.engine %v", o.Type) - } - // Retrieve any pre-existing database's type and use that or the requested one - // as long as there's no conflict between the two types - existingDb := PreexistingDatabase(o.Directory) - if len(existingDb) != 0 && len(o.Type) != 0 && o.Type != existingDb { - return nil, fmt.Errorf("db.engine choice was %v but found pre-existing %v database in specified data directory", o.Type, existingDb) - } - if o.Type == dbPebble || existingDb == dbPebble { - log.Info("Using pebble as the backing database") - return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) - } - if o.Type == dbLeveldb || existingDb == dbLeveldb { - log.Info("Using leveldb as the backing database") - return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) - } - // No pre-existing database, no user-requested one either. Default to Pebble. - log.Info("Defaulting to pebble as the backing database") - return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) -} - -// Open opens both a disk-based key-value database such as leveldb or pebble, but also -// integrates it with a freezer database -- if the AncientDir option has been -// set on the provided OpenOptions. -// The passed o.AncientDir indicates the path of root ancient directory where -// the chain freezer can be opened. -func Open(o OpenOptions) (ethdb.Database, error) { - kvdb, err := openKeyValueDatabase(o) - if err != nil { - return nil, err - } - return kvdb, nil -} - -type counter uint64 - -func (c counter) String() string { - return fmt.Sprintf("%d", c) -} - -func (c counter) Percentage(current uint64) string { - return fmt.Sprintf("%d", current*100/uint64(c)) -} - -// stat stores sizes and count for a parameter -type stat struct { - size common.StorageSize - count counter -} - -// Add size to the stat and increase the counter by 1 -func (s *stat) Add(size common.StorageSize) { - s.size += size - s.count++ -} - -func (s *stat) Size() string { - return s.size.String() -} - -func (s *stat) Count() string { - return s.count.String() -} - -// InspectDatabase traverses the entire database and checks the size -// of all different categories of data. -func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { - it := db.NewIterator(keyPrefix, keyStart) - defer it.Release() - - var ( - count int64 - start = time.Now() - logged = time.Now() - - // Key-value store statistics - headers stat - bodies stat - receipts stat - numHashPairings stat - hashNumPairings stat - legacyTries stat - stateLookups stat - accountTries stat - storageTries stat - codes stat - txLookups stat - accountSnaps stat - storageSnaps stat - preimages stat - bloomBits stat - cliqueSnaps stat - - // State sync statistics - codeToFetch stat - syncProgress stat - syncSegments stat - syncPerformed stat - - // Les statistic - chtTrieNodes stat - bloomTrieNodes stat - - // Meta- and unaccounted data - metadata stat - unaccounted stat - - // Totals - total common.StorageSize - ) - // Inspect key-value database first. - for it.Next() { - var ( - key = it.Key() - size = common.StorageSize(len(key) + len(it.Value())) - ) - total += size - switch { - case bytes.HasPrefix(key, headerPrefix) && len(key) == (len(headerPrefix)+8+common.HashLength): - headers.Add(size) - case bytes.HasPrefix(key, blockBodyPrefix) && len(key) == (len(blockBodyPrefix)+8+common.HashLength): - bodies.Add(size) - case bytes.HasPrefix(key, blockReceiptsPrefix) && len(key) == (len(blockReceiptsPrefix)+8+common.HashLength): - receipts.Add(size) - case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerHashSuffix): - numHashPairings.Add(size) - case bytes.HasPrefix(key, headerNumberPrefix) && len(key) == (len(headerNumberPrefix)+common.HashLength): - hashNumPairings.Add(size) - case IsLegacyTrieNode(key, it.Value()): - legacyTries.Add(size) - case bytes.HasPrefix(key, stateIDPrefix) && len(key) == len(stateIDPrefix)+common.HashLength: - stateLookups.Add(size) - case IsAccountTrieNode(key): - accountTries.Add(size) - case IsStorageTrieNode(key): - storageTries.Add(size) - case bytes.HasPrefix(key, CodePrefix) && len(key) == len(CodePrefix)+common.HashLength: - codes.Add(size) - case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength): - txLookups.Add(size) - case bytes.HasPrefix(key, SnapshotAccountPrefix) && len(key) == (len(SnapshotAccountPrefix)+common.HashLength): - accountSnaps.Add(size) - case bytes.HasPrefix(key, SnapshotStoragePrefix) && len(key) == (len(SnapshotStoragePrefix)+2*common.HashLength): - storageSnaps.Add(size) - case bytes.HasPrefix(key, PreimagePrefix) && len(key) == (len(PreimagePrefix)+common.HashLength): - preimages.Add(size) - case bytes.HasPrefix(key, configPrefix) && len(key) == (len(configPrefix)+common.HashLength): - metadata.Add(size) - case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength): - bloomBits.Add(size) - case bytes.HasPrefix(key, BloomBitsIndexPrefix): - bloomBits.Add(size) - case bytes.HasPrefix(key, syncStorageTriesPrefix) && len(key) == syncStorageTriesKeyLength: - syncProgress.Add(size) - case bytes.HasPrefix(key, syncSegmentsPrefix) && len(key) == syncSegmentsKeyLength: - syncSegments.Add(size) - case bytes.HasPrefix(key, CodeToFetchPrefix) && len(key) == codeToFetchKeyLength: - codeToFetch.Add(size) - case bytes.HasPrefix(key, syncPerformedPrefix) && len(key) == syncPerformedKeyLength: - syncPerformed.Add(size) - default: - var accounted bool - for _, meta := range [][]byte{ - databaseVersionKey, headHeaderKey, headBlockKey, - snapshotRootKey, snapshotBlockHashKey, snapshotGeneratorKey, - uncleanShutdownKey, syncRootKey, txIndexTailKey, - persistentStateIDKey, trieJournalKey, - } { - if bytes.Equal(key, meta) { - metadata.Add(size) - accounted = true - break - } - } - if !accounted { - unaccounted.Add(size) - } - } - count++ - if count%1000 == 0 && time.Since(logged) > 8*time.Second { - log.Info("Inspecting database", "count", count, "elapsed", common.PrettyDuration(time.Since(start))) - logged = time.Now() - } - } - // Display the database statistic. - stats := [][]string{ - {"Key-Value store", "Headers", headers.Size(), headers.Count()}, - {"Key-Value store", "Bodies", bodies.Size(), bodies.Count()}, - {"Key-Value store", "Receipt lists", receipts.Size(), receipts.Count()}, - {"Key-Value store", "Block number->hash", numHashPairings.Size(), numHashPairings.Count()}, - {"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()}, - {"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, - {"Key-Value store", "Bloombit index", bloomBits.Size(), bloomBits.Count()}, - {"Key-Value store", "Contract codes", codes.Size(), codes.Count()}, - {"Key-Value store", "Hash trie nodes", legacyTries.Size(), legacyTries.Count()}, - {"Key-Value store", "Path trie state lookups", stateLookups.Size(), stateLookups.Count()}, - {"Key-Value store", "Path trie account nodes", accountTries.Size(), accountTries.Count()}, - {"Key-Value store", "Path trie storage nodes", storageTries.Size(), storageTries.Count()}, - {"Key-Value store", "Trie preimages", preimages.Size(), preimages.Count()}, - {"Key-Value store", "Account snapshot", accountSnaps.Size(), accountSnaps.Count()}, - {"Key-Value store", "Storage snapshot", storageSnaps.Size(), storageSnaps.Count()}, - {"Key-Value store", "Clique snapshots", cliqueSnaps.Size(), cliqueSnaps.Count()}, - {"Key-Value store", "Singleton metadata", metadata.Size(), metadata.Count()}, - {"Light client", "CHT trie nodes", chtTrieNodes.Size(), chtTrieNodes.Count()}, - {"Light client", "Bloom trie nodes", bloomTrieNodes.Size(), bloomTrieNodes.Count()}, - {"State sync", "Trie segments", syncSegments.Size(), syncSegments.Count()}, - {"State sync", "Storage tries to fetch", syncProgress.Size(), syncProgress.Count()}, - {"State sync", "Code to fetch", codeToFetch.Size(), codeToFetch.Count()}, - {"State sync", "Block numbers synced to", syncPerformed.Size(), syncPerformed.Count()}, - } - table := tablewriter.NewWriter(os.Stdout) - table.SetHeader([]string{"Database", "Category", "Size", "Items"}) - table.SetFooter([]string{"", "Total", total.String(), " "}) - table.AppendBulk(stats) - table.Render() - - if unaccounted.size > 0 { - log.Error("Database contains unaccounted data", "size", unaccounted.size, "count", unaccounted.count) - } - return nil -} - -// ClearPrefix removes all keys in db that begin with prefix and match an -// expected key length. [keyLen] should include the length of the prefix. -func ClearPrefix(db ethdb.KeyValueStore, prefix []byte, keyLen int) error { - it := db.NewIterator(prefix, nil) - defer it.Release() - - batch := db.NewBatch() - for it.Next() { - key := common.CopyBytes(it.Key()) - if len(key) != keyLen { - // avoid deleting keys that do not match the expected length - continue - } - if err := batch.Delete(key); err != nil { - return err - } - if batch.ValueSize() > ethdb.IdealBatchSize { - if err := batch.Write(); err != nil { - return err - } - batch.Reset() - } - } - if err := it.Error(); err != nil { - return err - } - return batch.Write() -} - -/// TODO: Consider adding ReadChainMetadata diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go deleted file mode 100644 index 622cbb3ff9..0000000000 --- a/core/rawdb/freezer.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -// convertLegacyFn takes a raw freezer entry in an older format and -// returns it in the new format. -type convertLegacyFn = func([]byte) ([]byte, error) diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go deleted file mode 100644 index bc999be25b..0000000000 --- a/core/rawdb/freezer_table.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import "errors" - -var ( - // errNotSupported is returned if the database doesn't support the required operation. - errNotSupported = errors.New("this operation is not supported") -) diff --git a/core/rawdb/key_length_iterator.go b/core/rawdb/key_length_iterator.go deleted file mode 100644 index fe95d719f0..0000000000 --- a/core/rawdb/key_length_iterator.go +++ /dev/null @@ -1,57 +0,0 @@ -// (c) 2022, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import "github.com/ethereum/go-ethereum/ethdb" - -// KeyLengthIterator is a wrapper for a database iterator that ensures only key-value pairs -// with a specific key length will be returned. -type KeyLengthIterator struct { - requiredKeyLength int - ethdb.Iterator -} - -// NewKeyLengthIterator returns a wrapped version of the iterator that will only return key-value -// pairs where keys with a specific key length will be returned. -func NewKeyLengthIterator(it ethdb.Iterator, keyLen int) ethdb.Iterator { - return &KeyLengthIterator{ - Iterator: it, - requiredKeyLength: keyLen, - } -} - -func (it *KeyLengthIterator) Next() bool { - // Return true as soon as a key with the required key length is discovered - for it.Iterator.Next() { - if len(it.Iterator.Key()) == it.requiredKeyLength { - return true - } - } - - // Return false when we exhaust the keys in the underlying iterator. - return false -} diff --git a/core/rawdb/key_length_iterator_test.go b/core/rawdb/key_length_iterator_test.go deleted file mode 100644 index 654efc5b55..0000000000 --- a/core/rawdb/key_length_iterator_test.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "encoding/binary" - "testing" -) - -func TestKeyLengthIterator(t *testing.T) { - db := NewMemoryDatabase() - - keyLen := 8 - expectedKeys := make(map[string]struct{}) - for i := 0; i < 100; i++ { - key := make([]byte, keyLen) - binary.BigEndian.PutUint64(key, uint64(i)) - if err := db.Put(key, []byte{0x1}); err != nil { - t.Fatal(err) - } - expectedKeys[string(key)] = struct{}{} - - longerKey := make([]byte, keyLen*2) - binary.BigEndian.PutUint64(longerKey, uint64(i)) - if err := db.Put(longerKey, []byte{0x1}); err != nil { - t.Fatal(err) - } - } - - it := NewKeyLengthIterator(db.NewIterator(nil, nil), keyLen) - for it.Next() { - key := it.Key() - _, exists := expectedKeys[string(key)] - if !exists { - t.Fatalf("Found unexpected key %d", binary.BigEndian.Uint64(key)) - } - delete(expectedKeys, string(key)) - if len(key) != keyLen { - t.Fatalf("Found unexpected key in key length iterator with length %d", len(key)) - } - } - - if len(expectedKeys) != 0 { - t.Fatalf("Expected all keys of length %d to be removed from expected keys during iteration", keyLen) - } -} diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go deleted file mode 100644 index 8d79dbc1c4..0000000000 --- a/core/rawdb/schema.go +++ /dev/null @@ -1,310 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package rawdb contains a collection of low level database accessors. -package rawdb - -import ( - "bytes" - "encoding/binary" - - "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -// The fields below define the low level database schema prefixing. -var ( - // databaseVersionKey tracks the current database version. - databaseVersionKey = []byte("DatabaseVersion") - - // headHeaderKey tracks the latest known header's hash. - headHeaderKey = []byte("LastHeader") - - // headBlockKey tracks the latest known full block's hash. - headBlockKey = []byte("LastBlock") - - // persistentStateIDKey tracks the id of latest stored state(for path-based only). - persistentStateIDKey = []byte("LastStateID") - - // snapshotRootKey tracks the hash of the last snapshot. - snapshotRootKey = []byte("SnapshotRoot") - - // snapshotBlockHashKey tracks the block hash of the last snapshot. - snapshotBlockHashKey = []byte("SnapshotBlockHash") - - // snapshotGeneratorKey tracks the snapshot generation marker across restarts. - snapshotGeneratorKey = []byte("SnapshotGenerator") - - // trieJournalKey tracks the in-memory trie node layers across restarts. - trieJournalKey = []byte("TrieJournal") - - // txIndexTailKey tracks the oldest block whose transactions have been indexed. - txIndexTailKey = []byte("TransactionIndexTail") - - // uncleanShutdownKey tracks the list of local crashes - uncleanShutdownKey = []byte("unclean-shutdown") // config prefix for the db - - // offlinePruningKey tracks runs of offline pruning - offlinePruningKey = []byte("OfflinePruning") - - // populateMissingTriesKey tracks runs of trie backfills - populateMissingTriesKey = []byte("PopulateMissingTries") - - // pruningDisabledKey tracks whether the node has ever run in archival mode - // to ensure that a user does not accidentally corrupt an archival node. - pruningDisabledKey = []byte("PruningDisabled") - - // acceptorTipKey tracks the tip of the last accepted block that has been fully processed. - acceptorTipKey = []byte("AcceptorTipKey") - - // Data item prefixes (use single byte to avoid mixing data types, avoid `i`, used for indexes). - headerPrefix = []byte("h") // headerPrefix + num (uint64 big endian) + hash -> header - headerHashSuffix = []byte("n") // headerPrefix + num (uint64 big endian) + headerHashSuffix -> hash - headerNumberPrefix = []byte("H") // headerNumberPrefix + hash -> num (uint64 big endian) - - blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body - blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts - - txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata - bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits - SnapshotAccountPrefix = []byte("a") // SnapshotAccountPrefix + account hash -> account trie value - SnapshotStoragePrefix = []byte("o") // SnapshotStoragePrefix + account hash + storage hash -> storage trie value - CodePrefix = []byte("c") // CodePrefix + code hash -> account code - - // Path-based storage scheme of merkle patricia trie. - trieNodeAccountPrefix = []byte("A") // trieNodeAccountPrefix + hexPath -> trie node - trieNodeStoragePrefix = []byte("O") // trieNodeStoragePrefix + accountHash + hexPath -> trie node - stateIDPrefix = []byte("L") // stateIDPrefix + state root -> state id - - PreimagePrefix = []byte("secure-key-") // PreimagePrefix + hash -> preimage - configPrefix = []byte("ethereum-config-") // config prefix for the db - - // BloomBitsIndexPrefix is the data table of a chain indexer to track its progress - BloomBitsIndexPrefix = []byte("iB") - - preimageCounter = metrics.NewRegisteredCounter("db/preimage/total", nil) - preimageHitCounter = metrics.NewRegisteredCounter("db/preimage/hits", nil) - - // State sync progress keys and prefixes - syncRootKey = []byte("sync_root") // indicates the root of the main account trie currently being synced - syncStorageTriesPrefix = []byte("sync_storage") // syncStorageTriesPrefix + trie root + account hash: indicates a storage trie must be fetched for the account - syncSegmentsPrefix = []byte("sync_segments") // syncSegmentsPrefix + trie root + 32-byte start key: indicates the trie at root has a segment starting at the specified key - CodeToFetchPrefix = []byte("CP") // CodeToFetchPrefix + code hash -> empty value tracks the outstanding code hashes we need to fetch. - - // State sync progress key lengths - syncStorageTriesKeyLength = len(syncStorageTriesPrefix) + 2*common.HashLength - syncSegmentsKeyLength = len(syncSegmentsPrefix) + 2*common.HashLength - codeToFetchKeyLength = len(CodeToFetchPrefix) + common.HashLength - - // State sync metadata - syncPerformedPrefix = []byte("sync_performed") - syncPerformedKeyLength = len(syncPerformedPrefix) + wrappers.LongLen // prefix + block number as uint64 -) - -// LegacyTxLookupEntry is the legacy TxLookupEntry definition with some unnecessary -// fields. -type LegacyTxLookupEntry struct { - BlockHash common.Hash - BlockIndex uint64 - Index uint64 -} - -// encodeBlockNumber encodes a block number as big endian uint64 -func encodeBlockNumber(number uint64) []byte { - enc := make([]byte, 8) - binary.BigEndian.PutUint64(enc, number) - return enc -} - -// headerKeyPrefix = headerPrefix + num (uint64 big endian) -func headerKeyPrefix(number uint64) []byte { - return append(headerPrefix, encodeBlockNumber(number)...) -} - -// headerKey = headerPrefix + num (uint64 big endian) + hash -func headerKey(number uint64, hash common.Hash) []byte { - return append(append(headerPrefix, encodeBlockNumber(number)...), hash.Bytes()...) -} - -// headerHashKey = headerPrefix + num (uint64 big endian) + headerHashSuffix -func headerHashKey(number uint64) []byte { - return append(append(headerPrefix, encodeBlockNumber(number)...), headerHashSuffix...) -} - -// headerNumberKey = headerNumberPrefix + hash -func headerNumberKey(hash common.Hash) []byte { - return append(headerNumberPrefix, hash.Bytes()...) -} - -// blockBodyKey = blockBodyPrefix + num (uint64 big endian) + hash -func blockBodyKey(number uint64, hash common.Hash) []byte { - return append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...) -} - -// blockReceiptsKey = blockReceiptsPrefix + num (uint64 big endian) + hash -func blockReceiptsKey(number uint64, hash common.Hash) []byte { - return append(append(blockReceiptsPrefix, encodeBlockNumber(number)...), hash.Bytes()...) -} - -// txLookupKey = txLookupPrefix + hash -func txLookupKey(hash common.Hash) []byte { - return append(txLookupPrefix, hash.Bytes()...) -} - -// accountSnapshotKey = SnapshotAccountPrefix + hash -func accountSnapshotKey(hash common.Hash) []byte { - return append(SnapshotAccountPrefix, hash.Bytes()...) -} - -// storageSnapshotKey = SnapshotStoragePrefix + account hash + storage hash -func storageSnapshotKey(accountHash, storageHash common.Hash) []byte { - buf := make([]byte, len(SnapshotStoragePrefix)+common.HashLength+common.HashLength) - n := copy(buf, SnapshotStoragePrefix) - n += copy(buf[n:], accountHash.Bytes()) - copy(buf[n:], storageHash.Bytes()) - return buf -} - -// storageSnapshotsKey = SnapshotStoragePrefix + account hash + storage hash -func storageSnapshotsKey(accountHash common.Hash) []byte { - return append(SnapshotStoragePrefix, accountHash.Bytes()...) -} - -// bloomBitsKey = bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -func bloomBitsKey(bit uint, section uint64, hash common.Hash) []byte { - key := append(append(bloomBitsPrefix, make([]byte, 10)...), hash.Bytes()...) - - binary.BigEndian.PutUint16(key[1:], uint16(bit)) - binary.BigEndian.PutUint64(key[3:], section) - - return key -} - -// preimageKey = preimagePrefix + hash -func preimageKey(hash common.Hash) []byte { - return append(PreimagePrefix, hash.Bytes()...) -} - -// codeKey = CodePrefix + hash -func codeKey(hash common.Hash) []byte { - return append(CodePrefix, hash.Bytes()...) -} - -// IsCodeKey reports whether the given byte slice is the key of contract code, -// if so return the raw code hash as well. -func IsCodeKey(key []byte) (bool, []byte) { - if bytes.HasPrefix(key, CodePrefix) && len(key) == common.HashLength+len(CodePrefix) { - return true, key[len(CodePrefix):] - } - return false, nil -} - -// configKey = configPrefix + hash -func configKey(hash common.Hash) []byte { - return append(configPrefix, hash.Bytes()...) -} - -// stateIDKey = stateIDPrefix + root (32 bytes) -func stateIDKey(root common.Hash) []byte { - return append(stateIDPrefix, root.Bytes()...) -} - -// accountTrieNodeKey = trieNodeAccountPrefix + nodePath. -func accountTrieNodeKey(path []byte) []byte { - return append(trieNodeAccountPrefix, path...) -} - -// storageTrieNodeKey = trieNodeStoragePrefix + accountHash + nodePath. -func storageTrieNodeKey(accountHash common.Hash, path []byte) []byte { - buf := make([]byte, len(trieNodeStoragePrefix)+common.HashLength+len(path)) - n := copy(buf, trieNodeStoragePrefix) - n += copy(buf[n:], accountHash.Bytes()) - copy(buf[n:], path) - return buf -} - -// IsLegacyTrieNode reports whether a provided database entry is a legacy trie -// node. The characteristics of legacy trie node are: -// - the key length is 32 bytes -// - the key is the hash of val -func IsLegacyTrieNode(key []byte, val []byte) bool { - if len(key) != common.HashLength { - return false - } - return bytes.Equal(key, crypto.Keccak256(val)) -} - -// ResolveAccountTrieNodeKey reports whether a provided database entry is an -// account trie node in path-based state scheme, and returns the resolved -// node path if so. -func ResolveAccountTrieNodeKey(key []byte) (bool, []byte) { - if !bytes.HasPrefix(key, trieNodeAccountPrefix) { - return false, nil - } - // The remaining key should only consist a hex node path - // whose length is in the range 0 to 64 (64 is excluded - // since leaves are always wrapped with shortNode). - if len(key) >= len(trieNodeAccountPrefix)+common.HashLength*2 { - return false, nil - } - return true, key[len(trieNodeAccountPrefix):] -} - -// IsAccountTrieNode reports whether a provided database entry is an account -// trie node in path-based state scheme. -func IsAccountTrieNode(key []byte) bool { - ok, _ := ResolveAccountTrieNodeKey(key) - return ok -} - -// ResolveStorageTrieNode reports whether a provided database entry is a storage -// trie node in path-based state scheme, and returns the resolved account hash -// and node path if so. -func ResolveStorageTrieNode(key []byte) (bool, common.Hash, []byte) { - if !bytes.HasPrefix(key, trieNodeStoragePrefix) { - return false, common.Hash{}, nil - } - // The remaining key consists of 2 parts: - // - 32 bytes account hash - // - hex node path whose length is in the range 0 to 64 - if len(key) < len(trieNodeStoragePrefix)+common.HashLength { - return false, common.Hash{}, nil - } - if len(key) >= len(trieNodeStoragePrefix)+common.HashLength+common.HashLength*2 { - return false, common.Hash{}, nil - } - accountHash := common.BytesToHash(key[len(trieNodeStoragePrefix) : len(trieNodeStoragePrefix)+common.HashLength]) - return true, accountHash, key[len(trieNodeStoragePrefix)+common.HashLength:] -} - -// IsStorageTrieNode reports whether a provided database entry is a storage -// trie node in path-based state scheme. -func IsStorageTrieNode(key []byte) bool { - ok, _, _ := ResolveStorageTrieNode(key) - return ok -} diff --git a/core/rawdb/table.go b/core/rawdb/table.go deleted file mode 100644 index 5dc709080c..0000000000 --- a/core/rawdb/table.go +++ /dev/null @@ -1,317 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "github.com/ethereum/go-ethereum/ethdb" -) - -// table is a wrapper around a database that prefixes each key access with a pre- -// configured string. -type table struct { - db ethdb.Database - prefix string -} - -// NewTable returns a database object that prefixes all keys with a given string. -func NewTable(db ethdb.Database, prefix string) ethdb.Database { - return &table{ - db: db, - prefix: prefix, - } -} - -// Close is a noop to implement the Database interface. -func (t *table) Close() error { - return nil -} - -// Has retrieves if a prefixed version of a key is present in the database. -func (t *table) Has(key []byte) (bool, error) { - return t.db.Has(append([]byte(t.prefix), key...)) -} - -// Get retrieves the given prefixed key if it's present in the database. -func (t *table) Get(key []byte) ([]byte, error) { - return t.db.Get(append([]byte(t.prefix), key...)) -} - -// HasAncient is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) HasAncient(kind string, number uint64) (bool, error) { - return t.db.HasAncient(kind, number) -} - -// Ancient is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) Ancient(kind string, number uint64) ([]byte, error) { - return t.db.Ancient(kind, number) -} - -// AncientRange is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) { - return t.db.AncientRange(kind, start, count, maxBytes) -} - -// Ancients is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) Ancients() (uint64, error) { - return t.db.Ancients() -} - -// Tail is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) Tail() (uint64, error) { - return t.db.Tail() -} - -// AncientSize is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) AncientSize(kind string) (uint64, error) { - return t.db.AncientSize(kind) -} - -// ModifyAncients runs an ancient write operation on the underlying database. -func (t *table) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (int64, error) { - return t.db.ModifyAncients(fn) -} - -func (t *table) ReadAncients(fn func(reader ethdb.AncientReaderOp) error) (err error) { - return t.db.ReadAncients(fn) -} - -// TruncateHead is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) TruncateHead(items uint64) (uint64, error) { - return t.db.TruncateHead(items) -} - -// TruncateTail is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) TruncateTail(items uint64) (uint64, error) { - return t.db.TruncateTail(items) -} - -// Sync is a noop passthrough that just forwards the request to the underlying -// database. -func (t *table) Sync() error { - return t.db.Sync() -} - -// MigrateTable processes the entries in a given table in sequence -// converting them to a new format if they're of an old format. -func (t *table) MigrateTable(kind string, convert convertLegacyFn) error { - return t.db.MigrateTable(kind, convert) -} - -// AncientDatadir returns the ancient datadir of the underlying database. -func (t *table) AncientDatadir() (string, error) { - return t.db.AncientDatadir() -} - -// Put inserts the given value into the database at a prefixed version of the -// provided key. -func (t *table) Put(key []byte, value []byte) error { - return t.db.Put(append([]byte(t.prefix), key...), value) -} - -// Delete removes the given prefixed key from the database. -func (t *table) Delete(key []byte) error { - return t.db.Delete(append([]byte(t.prefix), key...)) -} - -// NewIterator creates a binary-alphabetical iterator over a subset -// of database content with a particular key prefix, starting at a particular -// initial key (or after, if it does not exist). -func (t *table) NewIterator(prefix []byte, start []byte) ethdb.Iterator { - innerPrefix := append([]byte(t.prefix), prefix...) - iter := t.db.NewIterator(innerPrefix, start) - return &tableIterator{ - iter: iter, - prefix: t.prefix, - } -} - -// Stat returns a particular internal stat of the database. -func (t *table) Stat(property string) (string, error) { - return t.db.Stat(property) -} - -// Compact flattens the underlying data store for the given key range. In essence, -// deleted and overwritten versions are discarded, and the data is rearranged to -// reduce the cost of operations needed to access them. -// -// A nil start is treated as a key before all keys in the data store; a nil limit -// is treated as a key after all keys in the data store. If both is nil then it -// will compact entire data store. -func (t *table) Compact(start []byte, limit []byte) error { - // If no start was specified, use the table prefix as the first value - if start == nil { - start = []byte(t.prefix) - } else { - start = append([]byte(t.prefix), start...) - } - // If no limit was specified, use the first element not matching the prefix - // as the limit - if limit == nil { - limit = []byte(t.prefix) - for i := len(limit) - 1; i >= 0; i-- { - // Bump the current character, stopping if it doesn't overflow - limit[i]++ - if limit[i] > 0 { - break - } - // Character overflown, proceed to the next or nil if the last - if i == 0 { - limit = nil - } - } - } else { - limit = append([]byte(t.prefix), limit...) - } - // Range correctly calculated based on table prefix, delegate down - return t.db.Compact(start, limit) -} - -// NewBatch creates a write-only database that buffers changes to its host db -// until a final write is called, each operation prefixing all keys with the -// pre-configured string. -func (t *table) NewBatch() ethdb.Batch { - return &tableBatch{t.db.NewBatch(), t.prefix} -} - -// NewBatchWithSize creates a write-only database batch with pre-allocated buffer. -func (t *table) NewBatchWithSize(size int) ethdb.Batch { - return &tableBatch{t.db.NewBatchWithSize(size), t.prefix} -} - -// NewSnapshot creates a database snapshot based on the current state. -// The created snapshot will not be affected by all following mutations -// happened on the database. -func (t *table) NewSnapshot() (ethdb.Snapshot, error) { - return t.db.NewSnapshot() -} - -// tableBatch is a wrapper around a database batch that prefixes each key access -// with a pre-configured string. -type tableBatch struct { - batch ethdb.Batch - prefix string -} - -// Put inserts the given value into the batch for later committing. -func (b *tableBatch) Put(key, value []byte) error { - return b.batch.Put(append([]byte(b.prefix), key...), value) -} - -// Delete inserts a key removal into the batch for later committing. -func (b *tableBatch) Delete(key []byte) error { - return b.batch.Delete(append([]byte(b.prefix), key...)) -} - -// ValueSize retrieves the amount of data queued up for writing. -func (b *tableBatch) ValueSize() int { - return b.batch.ValueSize() -} - -// Write flushes any accumulated data to disk. -func (b *tableBatch) Write() error { - return b.batch.Write() -} - -// Reset resets the batch for reuse. -func (b *tableBatch) Reset() { - b.batch.Reset() -} - -// tableReplayer is a wrapper around a batch replayer which truncates -// the added prefix. -type tableReplayer struct { - w ethdb.KeyValueWriter - prefix string -} - -// Put implements the interface KeyValueWriter. -func (r *tableReplayer) Put(key []byte, value []byte) error { - trimmed := key[len(r.prefix):] - return r.w.Put(trimmed, value) -} - -// Delete implements the interface KeyValueWriter. -func (r *tableReplayer) Delete(key []byte) error { - trimmed := key[len(r.prefix):] - return r.w.Delete(trimmed) -} - -// Replay replays the batch contents. -func (b *tableBatch) Replay(w ethdb.KeyValueWriter) error { - return b.batch.Replay(&tableReplayer{w: w, prefix: b.prefix}) -} - -// tableIterator is a wrapper around a database iterator that prefixes each key access -// with a pre-configured string. -type tableIterator struct { - iter ethdb.Iterator - prefix string -} - -// Next moves the iterator to the next key/value pair. It returns whether the -// iterator is exhausted. -func (iter *tableIterator) Next() bool { - return iter.iter.Next() -} - -// Error returns any accumulated error. Exhausting all the key/value pairs -// is not considered to be an error. -func (iter *tableIterator) Error() error { - return iter.iter.Error() -} - -// Key returns the key of the current key/value pair, or nil if done. The caller -// should not modify the contents of the returned slice, and its contents may -// change on the next call to Next. -func (iter *tableIterator) Key() []byte { - key := iter.iter.Key() - if key == nil { - return nil - } - return key[len(iter.prefix):] -} - -// Value returns the value of the current key/value pair, or nil if done. The -// caller should not modify the contents of the returned slice, and its contents -// may change on the next call to Next. -func (iter *tableIterator) Value() []byte { - return iter.iter.Value() -} - -// Release releases associated resources. Release should always succeed and can -// be called multiple times without causing error. -func (iter *tableIterator) Release() { - iter.iter.Release() -} diff --git a/core/rawdb/table_test.go b/core/rawdb/table_test.go deleted file mode 100644 index 9cb913c2a1..0000000000 --- a/core/rawdb/table_test.go +++ /dev/null @@ -1,138 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package rawdb - -import ( - "bytes" - "testing" - - "github.com/ethereum/go-ethereum/ethdb" -) - -func TestTableDatabase(t *testing.T) { testTableDatabase(t, "prefix") } -func TestEmptyPrefixTableDatabase(t *testing.T) { testTableDatabase(t, "") } - -type testReplayer struct { - puts [][]byte - dels [][]byte -} - -func (r *testReplayer) Put(key []byte, value []byte) error { - r.puts = append(r.puts, key) - return nil -} - -func (r *testReplayer) Delete(key []byte) error { - r.dels = append(r.dels, key) - return nil -} - -func testTableDatabase(t *testing.T, prefix string) { - db := NewTable(NewMemoryDatabase(), prefix) - - var entries = []struct { - key []byte - value []byte - }{ - {[]byte{0x01, 0x02}, []byte{0x0a, 0x0b}}, - {[]byte{0x03, 0x04}, []byte{0x0c, 0x0d}}, - {[]byte{0x05, 0x06}, []byte{0x0e, 0x0f}}, - - {[]byte{0xff, 0xff, 0x01}, []byte{0x1a, 0x1b}}, - {[]byte{0xff, 0xff, 0x02}, []byte{0x1c, 0x1d}}, - {[]byte{0xff, 0xff, 0x03}, []byte{0x1e, 0x1f}}, - } - - // Test Put/Get operation - for _, entry := range entries { - db.Put(entry.key, entry.value) - } - for _, entry := range entries { - got, err := db.Get(entry.key) - if err != nil { - t.Fatalf("Failed to get value: %v", err) - } - if !bytes.Equal(got, entry.value) { - t.Fatalf("Value mismatch: want=%v, got=%v", entry.value, got) - } - } - - // Test batch operation - db = NewTable(NewMemoryDatabase(), prefix) - batch := db.NewBatch() - for _, entry := range entries { - batch.Put(entry.key, entry.value) - } - batch.Write() - for _, entry := range entries { - got, err := db.Get(entry.key) - if err != nil { - t.Fatalf("Failed to get value: %v", err) - } - if !bytes.Equal(got, entry.value) { - t.Fatalf("Value mismatch: want=%v, got=%v", entry.value, got) - } - } - - // Test batch replayer - r := &testReplayer{} - batch.Replay(r) - for index, entry := range entries { - got := r.puts[index] - if !bytes.Equal(got, entry.key) { - t.Fatalf("Key mismatch: want=%v, got=%v", entry.key, got) - } - } - - check := func(iter ethdb.Iterator, expCount, index int) { - count := 0 - for iter.Next() { - key, value := iter.Key(), iter.Value() - if !bytes.Equal(key, entries[index].key) { - t.Fatalf("Key mismatch: want=%v, got=%v", entries[index].key, key) - } - if !bytes.Equal(value, entries[index].value) { - t.Fatalf("Value mismatch: want=%v, got=%v", entries[index].value, value) - } - index += 1 - count++ - } - if count != expCount { - t.Fatalf("Wrong number of elems, exp %d got %d", expCount, count) - } - iter.Release() - } - // Test iterators - check(db.NewIterator(nil, nil), 6, 0) - // Test iterators with prefix - check(db.NewIterator([]byte{0xff, 0xff}, nil), 3, 3) - // Test iterators with start point - check(db.NewIterator(nil, []byte{0xff, 0xff, 0x02}), 2, 4) - // Test iterators with prefix and start point - check(db.NewIterator([]byte{0xee}, nil), 0, 0) - check(db.NewIterator(nil, []byte{0x00}), 6, 0) -} diff --git a/core/rlp_test.go b/core/rlp_test.go index d6a36ef6b1..37116ac648 100644 --- a/core/rlp_test.go +++ b/core/rlp_test.go @@ -32,11 +32,11 @@ import ( "testing" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" "golang.org/x/crypto/sha3" ) diff --git a/core/sender_cacher.go b/core/sender_cacher.go index a1c09ec362..0693d3c424 100644 --- a/core/sender_cacher.go +++ b/core/sender_cacher.go @@ -29,7 +29,7 @@ package core import ( "sync" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" ) // txSenderCacherRequest is a request for recovering transaction senders with a diff --git a/core/state/access_list.go b/core/state/access_list.go deleted file mode 100644 index d5044ccc5b..0000000000 --- a/core/state/access_list.go +++ /dev/null @@ -1,146 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "github.com/ethereum/go-ethereum/common" -) - -type accessList struct { - addresses map[common.Address]int - slots []map[common.Hash]struct{} -} - -// ContainsAddress returns true if the address is in the access list. -func (al *accessList) ContainsAddress(address common.Address) bool { - _, ok := al.addresses[address] - return ok -} - -// Contains checks if a slot within an account is present in the access list, returning -// separate flags for the presence of the account and the slot respectively. -func (al *accessList) Contains(address common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) { - idx, ok := al.addresses[address] - if !ok { - // no such address (and hence zero slots) - return false, false - } - if idx == -1 { - // address yes, but no slots - return true, false - } - _, slotPresent = al.slots[idx][slot] - return true, slotPresent -} - -// newAccessList creates a new accessList. -func newAccessList() *accessList { - return &accessList{ - addresses: make(map[common.Address]int), - } -} - -// Copy creates an independent copy of an accessList. -func (a *accessList) Copy() *accessList { - cp := newAccessList() - for k, v := range a.addresses { - cp.addresses[k] = v - } - cp.slots = make([]map[common.Hash]struct{}, len(a.slots)) - for i, slotMap := range a.slots { - newSlotmap := make(map[common.Hash]struct{}, len(slotMap)) - for k := range slotMap { - newSlotmap[k] = struct{}{} - } - cp.slots[i] = newSlotmap - } - return cp -} - -// AddAddress adds an address to the access list, and returns 'true' if the operation -// caused a change (addr was not previously in the list). -func (al *accessList) AddAddress(address common.Address) bool { - if _, present := al.addresses[address]; present { - return false - } - al.addresses[address] = -1 - return true -} - -// AddSlot adds the specified (addr, slot) combo to the access list. -// Return values are: -// - address added -// - slot added -// For any 'true' value returned, a corresponding journal entry must be made. -func (al *accessList) AddSlot(address common.Address, slot common.Hash) (addrChange bool, slotChange bool) { - idx, addrPresent := al.addresses[address] - if !addrPresent || idx == -1 { - // Address not present, or addr present but no slots there - al.addresses[address] = len(al.slots) - slotmap := map[common.Hash]struct{}{slot: {}} - al.slots = append(al.slots, slotmap) - return !addrPresent, true - } - // There is already an (address,slot) mapping - slotmap := al.slots[idx] - if _, ok := slotmap[slot]; !ok { - slotmap[slot] = struct{}{} - // Journal add slot change - return false, true - } - // No changes required - return false, false -} - -// DeleteSlot removes an (address, slot)-tuple from the access list. -// This operation needs to be performed in the same order as the addition happened. -// This method is meant to be used by the journal, which maintains ordering of -// operations. -func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) { - idx, addrOk := al.addresses[address] - // There are two ways this can fail - if !addrOk { - panic("reverting slot change, address not present in list") - } - slotmap := al.slots[idx] - delete(slotmap, slot) - // If that was the last (first) slot, remove it - // Since additions and rollbacks are always performed in order, - // we can delete the item without worrying about screwing up later indices - if len(slotmap) == 0 { - al.slots = al.slots[:idx] - al.addresses[address] = -1 - } -} - -// DeleteAddress removes an address from the access list. This operation -// needs to be performed in the same order as the addition happened. -// This method is meant to be used by the journal, which maintains ordering of -// operations. -func (al *accessList) DeleteAddress(address common.Address) { - delete(al.addresses, address) -} diff --git a/core/state/database.go b/core/state/database.go index e29e9b8d78..fe1fb7a0b0 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -1,4 +1,4 @@ -// (c) 2019-2020, Ava Labs, Inc. +// (c) 2019-2025, Ava Labs, Inc. // // This file is a derived work, based on the go-ethereum library whose original // notices appear below. @@ -27,233 +27,24 @@ package state import ( - "errors" - "fmt" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/utils" - "github.com/ava-labs/coreth/triedb" - "github.com/crate-crypto/go-ipa/banderwagon" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + ethstate "github.com/ava-labs/libevm/core/state" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/triedb" ) -const ( - // Number of codehash->size associations to keep. - codeSizeCacheSize = 100000 - - // Cache size granted for caching clean code. - codeCacheSize = 64 * 1024 * 1024 - - // commitmentSize is the size of commitment stored in cache. - commitmentSize = banderwagon.UncompressedSize - - // Cache item granted for caching commitment results. - commitmentCacheItems = 64 * 1024 * 1024 / (commitmentSize + common.AddressLength) +type ( + Database = ethstate.Database + Trie = ethstate.Trie ) -// Database wraps access to tries and contract code. -type Database interface { - // OpenTrie opens the main account trie. - OpenTrie(root common.Hash) (Trie, error) - - // OpenStorageTrie opens the storage trie of an account. - OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, trie Trie) (Trie, error) - - // CopyTrie returns an independent copy of the given trie. - CopyTrie(Trie) Trie - - // ContractCode retrieves a particular contract's code. - ContractCode(addr common.Address, codeHash common.Hash) ([]byte, error) - - // ContractCodeSize retrieves a particular contracts code's size. - ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) - - // DiskDB returns the underlying key-value disk database. - DiskDB() ethdb.KeyValueStore - - // TrieDB returns the underlying trie database for managing trie nodes. - TrieDB() *triedb.Database -} - -// Trie is a Ethereum Merkle Patricia trie. -type Trie interface { - // GetKey returns the sha3 preimage of a hashed key that was previously used - // to store a value. - // - // TODO(fjl): remove this when StateTrie is removed - GetKey([]byte) []byte - - // GetAccount abstracts an account read from the trie. It retrieves the - // account blob from the trie with provided account address and decodes it - // with associated decoding algorithm. If the specified account is not in - // the trie, nil will be returned. If the trie is corrupted(e.g. some nodes - // are missing or the account blob is incorrect for decoding), an error will - // be returned. - GetAccount(address common.Address) (*types.StateAccount, error) - - // GetStorage returns the value for key stored in the trie. The value bytes - // must not be modified by the caller. If a node was not found in the database, - // a trie.MissingNodeError is returned. - GetStorage(addr common.Address, key []byte) ([]byte, error) - - // UpdateAccount abstracts an account write to the trie. It encodes the - // provided account object with associated algorithm and then updates it - // in the trie with provided address. - UpdateAccount(address common.Address, account *types.StateAccount) error - - // UpdateStorage associates key with value in the trie. If value has length zero, - // any existing value is deleted from the trie. The value bytes must not be modified - // by the caller while they are stored in the trie. If a node was not found in the - // database, a trie.MissingNodeError is returned. - UpdateStorage(addr common.Address, key, value []byte) error - - // DeleteAccount abstracts an account deletion from the trie. - DeleteAccount(address common.Address) error - - // DeleteStorage removes any existing value for key from the trie. If a node - // was not found in the database, a trie.MissingNodeError is returned. - DeleteStorage(addr common.Address, key []byte) error - - // UpdateContractCode abstracts code write to the trie. It is expected - // to be moved to the stateWriter interface when the latter is ready. - UpdateContractCode(address common.Address, codeHash common.Hash, code []byte) error - - // Hash returns the root hash of the trie. It does not write to the database and - // can be used even if the trie doesn't have one. - Hash() common.Hash - - // Commit collects all dirty nodes in the trie and replace them with the - // corresponding node hash. All collected nodes(including dirty leaves if - // collectLeaf is true) will be encapsulated into a nodeset for return. - // The returned nodeset can be nil if the trie is clean(nothing to commit). - // Once the trie is committed, it's not usable anymore. A new trie must - // be created with new root and updated trie database for following usage - Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) - - // NodeIterator returns an iterator that returns nodes of the trie. Iteration - // starts at the key after the given start key. And error will be returned - // if fails to create node iterator. - NodeIterator(startKey []byte) (trie.NodeIterator, error) - - // Prove constructs a Merkle proof for key. The result contains all encoded nodes - // on the path to the value at key. The value itself is also included in the last - // node and can be retrieved by verifying the proof. - // - // If the trie does not contain a value for key, the returned proof contains all - // nodes of the longest existing prefix of the key (at least the root), ending - // with the node that proves the absence of the key. - Prove(key []byte, proofDb ethdb.KeyValueWriter) error -} - -// NewDatabase creates a backing store for state. The returned database is safe for -// concurrent use, but does not retain any recent trie nodes in memory. To keep some -// historical state in memory, use the NewDatabaseWithConfig constructor. -func NewDatabase(db ethdb.Database) Database { - return NewDatabaseWithConfig(db, nil) -} - -// NewDatabaseWithConfig creates a backing store for state. The returned database -// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a -// large memory cache. -func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) Database { - return &cachingDB{ - disk: db, - codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), - codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), - triedb: triedb.NewDatabase(db, config), - } -} - -// NewDatabaseWithNodeDB creates a state database with an already initialized node database. -func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) Database { - return &cachingDB{ - disk: db, - codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), - codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), - triedb: triedb, - } -} - -type cachingDB struct { - disk ethdb.KeyValueStore - codeSizeCache *lru.Cache[common.Hash, int] - codeCache *lru.SizeConstrainedCache[common.Hash, []byte] - triedb *triedb.Database -} - -// OpenTrie opens the main account trie at a specific root hash. -func (db *cachingDB) OpenTrie(root common.Hash) (Trie, error) { - if db.triedb.IsVerkle() { - return trie.NewVerkleTrie(root, db.triedb, utils.NewPointCache(commitmentCacheItems)) - } - tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) - if err != nil { - return nil, err - } - return tr, nil -} - -// OpenStorageTrie opens the storage trie of an account. -func (db *cachingDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, self Trie) (Trie, error) { - // In the verkle case, there is only one tree. But the two-tree structure - // is hardcoded in the codebase. So we need to return the same trie in this - // case. - if db.triedb.IsVerkle() { - return self, nil - } - tr, err := trie.NewStateTrie(trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root), db.triedb) - if err != nil { - return nil, err - } - return tr, nil -} - -// CopyTrie returns an independent copy of the given trie. -func (db *cachingDB) CopyTrie(t Trie) Trie { - switch t := t.(type) { - case *trie.StateTrie: - return t.Copy() - default: - panic(fmt.Errorf("unknown trie type %T", t)) - } -} - -// ContractCode retrieves a particular contract's code. -func (db *cachingDB) ContractCode(address common.Address, codeHash common.Hash) ([]byte, error) { - code, _ := db.codeCache.Get(codeHash) - if len(code) > 0 { - return code, nil - } - code = rawdb.ReadCode(db.disk, codeHash) - if len(code) > 0 { - db.codeCache.Add(codeHash, code) - db.codeSizeCache.Add(codeHash, len(code)) - return code, nil - } - return nil, errors.New("not found") -} - -// ContractCodeSize retrieves a particular contracts code's size. -func (db *cachingDB) ContractCodeSize(addr common.Address, codeHash common.Hash) (int, error) { - if cached, ok := db.codeSizeCache.Get(codeHash); ok { - return cached, nil - } - code, err := db.ContractCode(addr, codeHash) - return len(code), err +func NewDatabase(db ethdb.Database) ethstate.Database { + return ethstate.NewDatabase(db) } -// DiskDB returns the underlying key-value disk database. -func (db *cachingDB) DiskDB() ethdb.KeyValueStore { - return db.disk +func NewDatabaseWithConfig(db ethdb.Database, config *triedb.Config) ethstate.Database { + return ethstate.NewDatabaseWithConfig(db, config) } -// TrieDB retrieves any intermediate trie-node caching layer. -func (db *cachingDB) TrieDB() *triedb.Database { - return db.triedb +func NewDatabaseWithNodeDB(db ethdb.Database, triedb *triedb.Database) ethstate.Database { + return ethstate.NewDatabaseWithNodeDB(db, triedb) } diff --git a/core/state/dump.go b/core/state/dump.go index a18184ca8c..deac606017 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -27,222 +27,12 @@ package state import ( - "encoding/json" - "fmt" - "time" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + ethstate "github.com/ava-labs/libevm/core/state" ) -// DumpConfig is a set of options to control what portions of the state will be -// iterated and collected. -type DumpConfig struct { - SkipCode bool - SkipStorage bool - OnlyWithAddresses bool - Start []byte - Max uint64 -} - -// DumpCollector interface which the state trie calls during iteration -type DumpCollector interface { - // OnRoot is called with the state root - OnRoot(common.Hash) - // OnAccount is called once for each account in the trie - OnAccount(*common.Address, DumpAccount) -} - -// DumpAccount represents an account in the state. -type DumpAccount struct { - Balance string `json:"balance"` - Nonce uint64 `json:"nonce"` - Root hexutil.Bytes `json:"root"` - CodeHash hexutil.Bytes `json:"codeHash"` - Code hexutil.Bytes `json:"code,omitempty"` - IsMultiCoin bool `json:"isMultiCoin"` - Storage map[common.Hash]string `json:"storage,omitempty"` - Address *common.Address `json:"address,omitempty"` // Address only present in iterative (line-by-line) mode - AddressHash hexutil.Bytes `json:"key,omitempty"` // If we don't have address, we can output the key - -} - -// Dump represents the full dump in a collected format, as one large map. -type Dump struct { - Root string `json:"root"` - Accounts map[string]DumpAccount `json:"accounts"` - // Next can be set to represent that this dump is only partial, and Next - // is where an iterator should be positioned in order to continue the dump. - Next []byte `json:"next,omitempty"` // nil if no more accounts -} - -// OnRoot implements DumpCollector interface -func (d *Dump) OnRoot(root common.Hash) { - d.Root = fmt.Sprintf("%x", root) -} - -// OnAccount implements DumpCollector interface -func (d *Dump) OnAccount(addr *common.Address, account DumpAccount) { - if addr == nil { - d.Accounts[fmt.Sprintf("pre(%s)", account.AddressHash)] = account - } - if addr != nil { - d.Accounts[(*addr).String()] = account - } -} - -// iterativeDump is a DumpCollector-implementation which dumps output line-by-line iteratively. -type iterativeDump struct { - *json.Encoder -} - -// OnAccount implements DumpCollector interface -func (d iterativeDump) OnAccount(addr *common.Address, account DumpAccount) { - dumpAccount := &DumpAccount{ - Balance: account.Balance, - Nonce: account.Nonce, - Root: account.Root, - CodeHash: account.CodeHash, - IsMultiCoin: account.IsMultiCoin, - Code: account.Code, - Storage: account.Storage, - AddressHash: account.AddressHash, - Address: addr, - } - d.Encode(dumpAccount) -} - -// OnRoot implements DumpCollector interface -func (d iterativeDump) OnRoot(root common.Hash) { - d.Encode(struct { - Root common.Hash `json:"root"` - }{root}) -} - -// DumpToCollector iterates the state according to the given options and inserts -// the items into a collector for aggregation or serialization. -func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey []byte) { - // Sanitize the input to allow nil configs - if conf == nil { - conf = new(DumpConfig) - } - var ( - missingPreimages int - accounts uint64 - start = time.Now() - logged = time.Now() - ) - log.Info("Trie dumping started", "root", s.trie.Hash()) - c.OnRoot(s.trie.Hash()) - - trieIt, err := s.trie.NodeIterator(conf.Start) - if err != nil { - log.Error("Trie dumping error", "err", err) - return nil - } - it := trie.NewIterator(trieIt) - for it.Next() { - var data types.StateAccount - if err := rlp.DecodeBytes(it.Value, &data); err != nil { - panic(err) - } - var ( - account = DumpAccount{ - Balance: data.Balance.String(), - Nonce: data.Nonce, - Root: data.Root[:], - CodeHash: data.CodeHash, - IsMultiCoin: data.IsMultiCoin, - AddressHash: it.Key, - } - address *common.Address - addr common.Address - addrBytes = s.trie.GetKey(it.Key) - ) - if addrBytes == nil { - missingPreimages++ - if conf.OnlyWithAddresses { - continue - } - } else { - addr = common.BytesToAddress(addrBytes) - address = &addr - account.Address = address - } - obj := newObject(s, addr, &data) - if !conf.SkipCode { - account.Code = obj.Code() - } - if !conf.SkipStorage { - account.Storage = make(map[common.Hash]string) - tr, err := obj.getTrie() - if err != nil { - log.Error("Failed to load storage trie", "err", err) - continue - } - trieIt, err := tr.NodeIterator(nil) - if err != nil { - log.Error("Failed to create trie iterator", "err", err) - continue - } - storageIt := trie.NewIterator(trieIt) - for storageIt.Next() { - _, content, _, err := rlp.Split(storageIt.Value) - if err != nil { - log.Error("Failed to decode the value returned by iterator", "error", err) - continue - } - account.Storage[common.BytesToHash(s.trie.GetKey(storageIt.Key))] = common.Bytes2Hex(content) - } - } - c.OnAccount(address, account) - accounts++ - if time.Since(logged) > 8*time.Second { - log.Info("Trie dumping in progress", "at", it.Key, "accounts", accounts, - "elapsed", common.PrettyDuration(time.Since(start))) - logged = time.Now() - } - if conf.Max > 0 && accounts >= conf.Max { - if it.Next() { - nextKey = it.Key - } - break - } - } - if missingPreimages > 0 { - log.Warn("Dump incomplete due to missing preimages", "missing", missingPreimages) - } - log.Info("Trie dumping complete", "accounts", accounts, - "elapsed", common.PrettyDuration(time.Since(start))) - - return nextKey -} - -// RawDump returns the state. If the processing is aborted e.g. due to options -// reaching Max, the `Next` key is set on the returned Dump. -func (s *StateDB) RawDump(opts *DumpConfig) Dump { - dump := &Dump{ - Accounts: make(map[string]DumpAccount), - } - dump.Next = s.DumpToCollector(dump, opts) - return *dump -} - -// Dump returns a JSON string representing the entire state as a single json-object -func (s *StateDB) Dump(opts *DumpConfig) []byte { - dump := s.RawDump(opts) - json, err := json.MarshalIndent(dump, "", " ") - if err != nil { - log.Error("Error dumping state", "err", err) - } - return json -} - -// IterativeDump dumps out accounts as json-objects, delimited by linebreaks on stdout -func (s *StateDB) IterativeDump(opts *DumpConfig, output *json.Encoder) { - s.DumpToCollector(iterativeDump{output}, opts) -} +type ( + DumpConfig = ethstate.DumpConfig + DumpCollector = ethstate.DumpCollector + DumpAccount = ethstate.DumpAccount + Dump = ethstate.Dump +) diff --git a/core/state/iterator.go b/core/state/iterator.go deleted file mode 100644 index 6db22d9634..0000000000 --- a/core/state/iterator.go +++ /dev/null @@ -1,181 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "bytes" - "errors" - "fmt" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" -) - -// nodeIterator is an iterator to traverse the entire state trie post-order, -// including all of the contract code and contract state tries. Preimage is -// required in order to resolve the contract address. -type nodeIterator struct { - state *StateDB // State being iterated - - stateIt trie.NodeIterator // Primary iterator for the global state trie - dataIt trie.NodeIterator // Secondary iterator for the data trie of a contract - - accountHash common.Hash // Hash of the node containing the account - codeHash common.Hash // Hash of the contract source code - code []byte // Source code associated with a contract - - Hash common.Hash // Hash of the current entry being iterated (nil if not standalone) - Parent common.Hash // Hash of the first full ancestor node (nil if current is the root) - - Error error // Failure set in case of an internal error in the iterator -} - -// newNodeIterator creates an post-order state node iterator. -func newNodeIterator(state *StateDB) *nodeIterator { - return &nodeIterator{ - state: state, - } -} - -// Next moves the iterator to the next node, returning whether there are any -// further nodes. In case of an internal error this method returns false and -// sets the Error field to the encountered failure. -func (it *nodeIterator) Next() bool { - // If the iterator failed previously, don't do anything - if it.Error != nil { - return false - } - // Otherwise step forward with the iterator and report any errors - if err := it.step(); err != nil { - it.Error = err - return false - } - return it.retrieve() -} - -// step moves the iterator to the next entry of the state trie. -func (it *nodeIterator) step() error { - // Abort if we reached the end of the iteration - if it.state == nil { - return nil - } - // Initialize the iterator if we've just started - var err error - if it.stateIt == nil { - it.stateIt, err = it.state.trie.NodeIterator(nil) - if err != nil { - return err - } - } - // If we had data nodes previously, we surely have at least state nodes - if it.dataIt != nil { - if cont := it.dataIt.Next(true); !cont { - if it.dataIt.Error() != nil { - return it.dataIt.Error() - } - it.dataIt = nil - } - return nil - } - // If we had source code previously, discard that - if it.code != nil { - it.code = nil - return nil - } - // Step to the next state trie node, terminating if we're out of nodes - if cont := it.stateIt.Next(true); !cont { - if it.stateIt.Error() != nil { - return it.stateIt.Error() - } - it.state, it.stateIt = nil, nil - return nil - } - // If the state trie node is an internal entry, leave as is - if !it.stateIt.Leaf() { - return nil - } - // Otherwise we've reached an account node, initiate data iteration - var account types.StateAccount - if err := rlp.DecodeBytes(it.stateIt.LeafBlob(), &account); err != nil { - return err - } - // Lookup the preimage of account hash - preimage := it.state.trie.GetKey(it.stateIt.LeafKey()) - if preimage == nil { - return errors.New("account address is not available") - } - address := common.BytesToAddress(preimage) - - // Traverse the storage slots belong to the account - dataTrie, err := it.state.db.OpenStorageTrie(it.state.originalRoot, address, account.Root, it.state.trie) - if err != nil { - return err - } - it.dataIt, err = dataTrie.NodeIterator(nil) - if err != nil { - return err - } - if !it.dataIt.Next(true) { - it.dataIt = nil - } - if !bytes.Equal(account.CodeHash, types.EmptyCodeHash.Bytes()) { - it.codeHash = common.BytesToHash(account.CodeHash) - it.code, err = it.state.db.ContractCode(address, common.BytesToHash(account.CodeHash)) - if err != nil { - return fmt.Errorf("code %x: %v", account.CodeHash, err) - } - } - it.accountHash = it.stateIt.Parent() - return nil -} - -// retrieve pulls and caches the current state entry the iterator is traversing. -// The method returns whether there are any more data left for inspection. -func (it *nodeIterator) retrieve() bool { - // Clear out any previously set values - it.Hash = common.Hash{} - - // If the iteration's done, return no available data - if it.state == nil { - return false - } - // Otherwise retrieve the current entry - switch { - case it.dataIt != nil: - it.Hash, it.Parent = it.dataIt.Hash(), it.dataIt.Parent() - if it.Parent == (common.Hash{}) { - it.Parent = it.accountHash - } - case it.code != nil: - it.Hash, it.Parent = it.codeHash, it.accountHash - case it.stateIt != nil: - it.Hash, it.Parent = it.stateIt.Hash(), it.stateIt.Parent() - } - return true -} diff --git a/core/state/iterator_test.go b/core/state/iterator_test.go deleted file mode 100644 index 53590d040e..0000000000 --- a/core/state/iterator_test.go +++ /dev/null @@ -1,118 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -// Tests that the node iterator indeed walks over the entire database contents. -func TestNodeIteratorCoverage(t *testing.T) { - testNodeIteratorCoverage(t, rawdb.HashScheme) - testNodeIteratorCoverage(t, rawdb.PathScheme) -} - -func testNodeIteratorCoverage(t *testing.T, scheme string) { - // Create some arbitrary test state to iterate - db, sdb, ndb, root, _ := makeTestState(scheme) - ndb.Commit(root, false) - - state, err := New(root, sdb, nil) - if err != nil { - t.Fatalf("failed to create state trie at %x: %v", root, err) - } - // Gather all the node hashes found by the iterator - hashes := make(map[common.Hash]struct{}) - for it := newNodeIterator(state); it.Next(); { - if it.Hash != (common.Hash{}) { - hashes[it.Hash] = struct{}{} - } - } - // Check in-disk nodes - var ( - seenNodes = make(map[common.Hash]struct{}) - seenCodes = make(map[common.Hash]struct{}) - ) - it := db.NewIterator(nil, nil) - for it.Next() { - ok, hash := isTrieNode(scheme, it.Key(), it.Value()) - if !ok { - continue - } - seenNodes[hash] = struct{}{} - } - it.Release() - - // Check in-disk codes - it = db.NewIterator(nil, nil) - for it.Next() { - ok, hash := rawdb.IsCodeKey(it.Key()) - if !ok { - continue - } - if _, ok := hashes[common.BytesToHash(hash)]; !ok { - t.Errorf("state entry not reported %x", it.Key()) - } - seenCodes[common.BytesToHash(hash)] = struct{}{} - } - it.Release() - - // Cross check the iterated hashes and the database/nodepool content - for hash := range hashes { - _, ok := seenNodes[hash] - if !ok { - _, ok = seenCodes[hash] - } - if !ok { - t.Errorf("failed to retrieve reported node %x", hash) - } - } -} - -// isTrieNode is a helper function which reports if the provided -// database entry belongs to a trie node or not. -func isTrieNode(scheme string, key, val []byte) (bool, common.Hash) { - if scheme == rawdb.HashScheme { - if rawdb.IsLegacyTrieNode(key, val) { - return true, common.BytesToHash(key) - } - } else { - ok := rawdb.IsAccountTrieNode(key) - if ok { - return true, crypto.Keccak256Hash(val) - } - ok = rawdb.IsStorageTrieNode(key) - if ok { - return true, crypto.Keccak256Hash(val) - } - } - return false, common.Hash{} -} diff --git a/core/state/journal.go b/core/state/journal.go deleted file mode 100644 index d412716874..0000000000 --- a/core/state/journal.go +++ /dev/null @@ -1,321 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -// journalEntry is a modification entry in the state change journal that can be -// reverted on demand. -type journalEntry interface { - // revert undoes the changes introduced by this journal entry. - revert(*StateDB) - - // dirtied returns the Ethereum address modified by this journal entry. - dirtied() *common.Address -} - -// journal contains the list of state modifications applied since the last state -// commit. These are tracked to be able to be reverted in the case of an execution -// exception or request for reversal. -type journal struct { - entries []journalEntry // Current changes tracked by the journal - dirties map[common.Address]int // Dirty accounts and the number of changes -} - -// newJournal creates a new initialized journal. -func newJournal() *journal { - return &journal{ - dirties: make(map[common.Address]int), - } -} - -// append inserts a new modification entry to the end of the change journal. -func (j *journal) append(entry journalEntry) { - j.entries = append(j.entries, entry) - if addr := entry.dirtied(); addr != nil { - j.dirties[*addr]++ - } -} - -// revert undoes a batch of journalled modifications along with any reverted -// dirty handling too. -func (j *journal) revert(statedb *StateDB, snapshot int) { - for i := len(j.entries) - 1; i >= snapshot; i-- { - // Undo the changes made by the operation - j.entries[i].revert(statedb) - - // Drop any dirty tracking induced by the change - if addr := j.entries[i].dirtied(); addr != nil { - if j.dirties[*addr]--; j.dirties[*addr] == 0 { - delete(j.dirties, *addr) - } - } - } - j.entries = j.entries[:snapshot] -} - -// dirty explicitly sets an address to dirty, even if the change entries would -// otherwise suggest it as clean. This method is an ugly hack to handle the RIPEMD -// precompile consensus exception. -func (j *journal) dirty(addr common.Address) { - j.dirties[addr]++ -} - -// length returns the current number of entries in the journal. -func (j *journal) length() int { - return len(j.entries) -} - -type ( - // Changes to the account trie. - createObjectChange struct { - account *common.Address - } - resetObjectChange struct { - account *common.Address - prev *stateObject - prevdestruct bool - prevAccount []byte - prevStorage map[common.Hash][]byte - - prevAccountOriginExist bool - prevAccountOrigin []byte - prevStorageOrigin map[common.Hash][]byte - } - selfDestructChange struct { - account *common.Address - prev bool // whether account had already self-destructed - prevbalance *uint256.Int - } - - // Changes to individual accounts. - balanceChange struct { - account *common.Address - prev *uint256.Int - } - multiCoinEnable struct { - account *common.Address - } - nonceChange struct { - account *common.Address - prev uint64 - } - storageChange struct { - account *common.Address - key, prevalue common.Hash - } - codeChange struct { - account *common.Address - prevcode, prevhash []byte - } - - // Changes to other state values. - refundChange struct { - prev uint64 - } - addLogChange struct { - txhash common.Hash - } - addPreimageChange struct { - hash common.Hash - } - touchChange struct { - account *common.Address - } - // Changes to the access list - accessListAddAccountChange struct { - address *common.Address - } - accessListAddSlotChange struct { - address *common.Address - slot *common.Hash - } - - transientStorageChange struct { - account *common.Address - key, prevalue common.Hash - } -) - -func (ch createObjectChange) revert(s *StateDB) { - delete(s.stateObjects, *ch.account) - delete(s.stateObjectsDirty, *ch.account) -} - -func (ch createObjectChange) dirtied() *common.Address { - return ch.account -} - -func (ch resetObjectChange) revert(s *StateDB) { - s.setStateObject(ch.prev) - if !ch.prevdestruct { - delete(s.stateObjectsDestruct, ch.prev.address) - } - if ch.prevAccount != nil { - s.accounts[ch.prev.addrHash] = ch.prevAccount - } - if ch.prevStorage != nil { - s.storages[ch.prev.addrHash] = ch.prevStorage - } - if ch.prevAccountOriginExist { - s.accountsOrigin[ch.prev.address] = ch.prevAccountOrigin - } - if ch.prevStorageOrigin != nil { - s.storagesOrigin[ch.prev.address] = ch.prevStorageOrigin - } -} - -func (ch resetObjectChange) dirtied() *common.Address { - return ch.account -} - -func (ch selfDestructChange) revert(s *StateDB) { - obj := s.getStateObject(*ch.account) - if obj != nil { - obj.selfDestructed = ch.prev - obj.setBalance(ch.prevbalance) - } -} - -func (ch selfDestructChange) dirtied() *common.Address { - return ch.account -} - -var ripemd = common.HexToAddress("0000000000000000000000000000000000000003") - -func (ch touchChange) revert(s *StateDB) { -} - -func (ch touchChange) dirtied() *common.Address { - return ch.account -} - -func (ch balanceChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setBalance(ch.prev) -} - -func (ch balanceChange) dirtied() *common.Address { - return ch.account -} - -func (ch multiCoinEnable) revert(s *StateDB) { - s.getStateObject(*ch.account).data.IsMultiCoin = false -} - -func (ch multiCoinEnable) dirtied() *common.Address { - return ch.account -} - -func (ch nonceChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setNonce(ch.prev) -} - -func (ch nonceChange) dirtied() *common.Address { - return ch.account -} - -func (ch codeChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setCode(common.BytesToHash(ch.prevhash), ch.prevcode) -} - -func (ch codeChange) dirtied() *common.Address { - return ch.account -} - -func (ch storageChange) revert(s *StateDB) { - s.getStateObject(*ch.account).setState(ch.key, ch.prevalue) -} - -func (ch storageChange) dirtied() *common.Address { - return ch.account -} - -func (ch transientStorageChange) revert(s *StateDB) { - s.setTransientState(*ch.account, ch.key, ch.prevalue) -} - -func (ch transientStorageChange) dirtied() *common.Address { - return nil -} - -func (ch refundChange) revert(s *StateDB) { - s.refund = ch.prev -} - -func (ch refundChange) dirtied() *common.Address { - return nil -} - -func (ch addLogChange) revert(s *StateDB) { - logs := s.logs[ch.txhash] - if len(logs) == 1 { - delete(s.logs, ch.txhash) - } else { - s.logs[ch.txhash] = logs[:len(logs)-1] - } - s.logSize-- -} - -func (ch addLogChange) dirtied() *common.Address { - return nil -} - -func (ch addPreimageChange) revert(s *StateDB) { - delete(s.preimages, ch.hash) -} - -func (ch addPreimageChange) dirtied() *common.Address { - return nil -} - -func (ch accessListAddAccountChange) revert(s *StateDB) { - /* - One important invariant here, is that whenever a (addr, slot) is added, if the - addr is not already present, the add causes two journal entries: - - one for the address, - - one for the (address,slot) - Therefore, when unrolling the change, we can always blindly delete the - (addr) at this point, since no storage adds can remain when come upon - a single (addr) change. - */ - s.accessList.DeleteAddress(*ch.address) -} - -func (ch accessListAddAccountChange) dirtied() *common.Address { - return nil -} - -func (ch accessListAddSlotChange) revert(s *StateDB) { - s.accessList.DeleteSlot(*ch.address, *ch.slot) -} - -func (ch accessListAddSlotChange) dirtied() *common.Address { - return nil -} diff --git a/core/state/metrics.go b/core/state/metrics.go deleted file mode 100644 index 4fbc86c2f5..0000000000 --- a/core/state/metrics.go +++ /dev/null @@ -1,47 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import "github.com/ava-labs/libevm/metrics" - -var ( - accountUpdatedMeter = metrics.NewRegisteredMeter("state/update/account", nil) - storageUpdatedMeter = metrics.NewRegisteredMeter("state/update/storage", nil) - accountDeletedMeter = metrics.NewRegisteredMeter("state/delete/account", nil) - storageDeletedMeter = metrics.NewRegisteredMeter("state/delete/storage", nil) - accountTrieUpdatedMeter = metrics.NewRegisteredMeter("state/update/accountnodes", nil) - storageTriesUpdatedMeter = metrics.NewRegisteredMeter("state/update/storagenodes", nil) - accountTrieDeletedMeter = metrics.NewRegisteredMeter("state/delete/accountnodes", nil) - storageTriesDeletedMeter = metrics.NewRegisteredMeter("state/delete/storagenodes", nil) - - slotDeletionMaxCount = metrics.NewRegisteredGauge("state/delete/storage/max/slot", nil) - slotDeletionMaxSize = metrics.NewRegisteredGauge("state/delete/storage/max/size", nil) - slotDeletionTimer = metrics.NewRegisteredResettingTimer("state/delete/storage/timer", nil) - slotDeletionCount = metrics.NewRegisteredMeter("state/delete/storage/slot", nil) - slotDeletionSize = metrics.NewRegisteredMeter("state/delete/storage/size", nil) - slotDeletionSkip = metrics.NewRegisteredGauge("state/delete/storage/skip", nil) -) diff --git a/core/state/pruner/bloom.go b/core/state/pruner/bloom.go index b7f673b80d..8231d21b68 100644 --- a/core/state/pruner/bloom.go +++ b/core/state/pruner/bloom.go @@ -31,9 +31,9 @@ import ( "errors" "os" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/log" bloomfilter "github.com/holiman/bloomfilter/v2" ) diff --git a/core/state/pruner/pruner.go b/core/state/pruner/pruner.go index 090b7ac6af..408a0b99c7 100644 --- a/core/state/pruner/pruner.go +++ b/core/state/pruner/pruner.go @@ -37,15 +37,16 @@ import ( "strings" "time" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" ) const ( @@ -217,7 +218,7 @@ func prune(maindb ethdb.Database, stateBloom *stateBloom, bloomPath string, star // Write marker to DB to indicate offline pruning finished successfully. We write before calling os.RemoveAll // to guarantee that if the node dies midway through pruning, then this will run during RecoverPruning. - if err := rawdb.WriteOfflinePruning(maindb); err != nil { + if err := customrawdb.WriteOfflinePruning(maindb); err != nil { return fmt.Errorf("failed to write offline pruning success marker: %w", err) } diff --git a/core/state/snapshot/context.go b/core/state/snapshot/context.go index 35b22c6ea3..45acfbba29 100644 --- a/core/state/snapshot/context.go +++ b/core/state/snapshot/context.go @@ -34,8 +34,8 @@ import ( "golang.org/x/exp/slog" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) // generatorStats is a collection of statistics gathered by the snapshot generator diff --git a/core/state/snapshot/conversion.go b/core/state/snapshot/conversion.go index 64a2cd3421..46da66cbaa 100644 --- a/core/state/snapshot/conversion.go +++ b/core/state/snapshot/conversion.go @@ -35,13 +35,13 @@ import ( "sync" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" ) // trieKV represents a trie key-value pair @@ -92,7 +92,7 @@ func GenerateTrie(snaptree *Tree, root common.Hash, src ethdb.Database, dst ethd rawdb.WriteCode(dst, codeHash, code) } // Then migrate all storage trie nodes into the tmp db. - storageIt, err := snaptree.StorageIterator(root, accountHash, common.Hash{}, false) + storageIt, err := snaptree.StorageIterator(root, accountHash, common.Hash{}) if err != nil { return common.Hash{}, err } diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index d8d3b750e2..e6a9ce8328 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -35,9 +35,9 @@ import ( "sync/atomic" "time" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" bloomfilter "github.com/holiman/bloomfilter/v2" "golang.org/x/exp/slices" ) diff --git a/core/state/snapshot/difflayer_test.go b/core/state/snapshot/difflayer_test.go index 24fc3fdc69..85e774fdec 100644 --- a/core/state/snapshot/difflayer_test.go +++ b/core/state/snapshot/difflayer_test.go @@ -33,9 +33,9 @@ import ( "testing" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb/memorydb" ) func copyDestructs(destructs map[common.Hash]struct{}) map[common.Hash]struct{} { diff --git a/core/state/snapshot/disklayer.go b/core/state/snapshot/disklayer.go index 4f38072637..9ae076b84c 100644 --- a/core/state/snapshot/disklayer.go +++ b/core/state/snapshot/disklayer.go @@ -31,13 +31,13 @@ import ( "sync" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/triedb" ) // diskLayer is a low level persistent snapshot built on top of a key-value store. diff --git a/core/state/snapshot/disklayer_test.go b/core/state/snapshot/disklayer_test.go index 32c04c0a83..a7b24fbfbb 100644 --- a/core/state/snapshot/disklayer_test.go +++ b/core/state/snapshot/disklayer_test.go @@ -30,10 +30,11 @@ import ( "bytes" "testing" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb/memorydb" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb/memorydb" + "github.com/ava-labs/libevm/rlp" ) // reverse reverses the contents of a byte slice. It's used to update random accs @@ -106,7 +107,7 @@ func TestDiskMerge(t *testing.T) { rawdb.WriteAccountSnapshot(db, conNukeCache, conNukeCache[:]) rawdb.WriteStorageSnapshot(db, conNukeCache, conNukeCacheSlot, conNukeCacheSlot[:]) - rawdb.WriteSnapshotBlockHash(db, baseBlockHash) + customrawdb.WriteSnapshotBlockHash(db, baseBlockHash) rawdb.WriteSnapshotRoot(db, baseRoot) // Create a disk layer based on the above and cache in some data @@ -121,7 +122,7 @@ func TestDiskMerge(t *testing.T) { base.Storage(conNukeCache, conNukeCacheSlot) // Modify or delete some accounts, flatten everything onto disk - if err := snaps.Update(diffBlockHash, diffRoot, baseBlockHash, map[common.Hash]struct{}{ + if err := snaps.UpdateWithBlockHashes(diffBlockHash, diffRoot, baseBlockHash, map[common.Hash]struct{}{ accDelNoCache: {}, accDelCache: {}, conNukeNoCache: {}, @@ -297,7 +298,7 @@ func TestDiskPartialMerge(t *testing.T) { insertAccount(conNukeCache, conNukeCache[:]) insertStorage(conNukeCache, conNukeCacheSlot, conNukeCacheSlot[:]) - rawdb.WriteSnapshotBlockHash(db, baseBlockHash) + customrawdb.WriteSnapshotBlockHash(db, baseBlockHash) rawdb.WriteSnapshotRoot(db, baseRoot) // Create a disk layer based on the above using a random progress marker @@ -341,7 +342,7 @@ func TestDiskPartialMerge(t *testing.T) { assertStorage(conNukeCache, conNukeCacheSlot, conNukeCacheSlot[:]) // Modify or delete some accounts, flatten everything onto disk - if err := snaps.Update(diffBlockHash, diffRoot, baseBlockHash, map[common.Hash]struct{}{ + if err := snaps.UpdateWithBlockHashes(diffBlockHash, diffRoot, baseBlockHash, map[common.Hash]struct{}{ accDelNoCache: {}, accDelCache: {}, conNukeNoCache: {}, @@ -452,7 +453,7 @@ func TestDiskGeneratorPersistence(t *testing.T) { rawdb.WriteAccountSnapshot(db, accOne, accOne[:]) rawdb.WriteStorageSnapshot(db, accOne, accOneSlotOne, accOneSlotOne[:]) rawdb.WriteStorageSnapshot(db, accOne, accOneSlotTwo, accOneSlotTwo[:]) - rawdb.WriteSnapshotBlockHash(db, baseBlockHash) + customrawdb.WriteSnapshotBlockHash(db, baseBlockHash) rawdb.WriteSnapshotRoot(db, baseRoot) // Create a disk layer based on all above updates @@ -460,7 +461,7 @@ func TestDiskGeneratorPersistence(t *testing.T) { dl := snaps.disklayer() dl.genMarker = genMarker // Modify or delete some accounts, flatten everything onto disk - if err := snaps.Update(diffBlockHash, diffRoot, baseBlockHash, nil, map[common.Hash][]byte{ + if err := snaps.UpdateWithBlockHashes(diffBlockHash, diffRoot, baseBlockHash, nil, map[common.Hash][]byte{ accTwo: accTwo[:], }, nil); err != nil { t.Fatalf("failed to update snapshot tree: %v", err) @@ -478,7 +479,7 @@ func TestDiskGeneratorPersistence(t *testing.T) { } // Test scenario 2, the disk layer is fully generated // Modify or delete some accounts, flatten everything onto disk - if err := snaps.Update(diffTwoBlockHash, diffTwoRoot, diffBlockHash, nil, map[common.Hash][]byte{ + if err := snaps.UpdateWithBlockHashes(diffTwoBlockHash, diffTwoRoot, diffBlockHash, nil, map[common.Hash][]byte{ accThree: accThree.Bytes(), }, map[common.Hash]map[common.Hash][]byte{ accThree: {accThreeSlot: accThreeSlot.Bytes()}, @@ -527,7 +528,7 @@ func TestDiskSeek(t *testing.T) { baseRoot := randomHash() baseBlockHash := randomHash() - rawdb.WriteSnapshotBlockHash(db, baseBlockHash) + customrawdb.WriteSnapshotBlockHash(db, baseBlockHash) rawdb.WriteSnapshotRoot(db, baseRoot) snaps := NewTestTree(db, baseBlockHash, baseRoot) diff --git a/core/state/snapshot/generate.go b/core/state/snapshot/generate.go index 9d10afd3f9..48e9d6b156 100644 --- a/core/state/snapshot/generate.go +++ b/core/state/snapshot/generate.go @@ -31,15 +31,16 @@ import ( "fmt" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" ) const ( @@ -62,7 +63,7 @@ func generateSnapshot(diskdb ethdb.KeyValueStore, triedb *triedb.Database, cache batch = diskdb.NewBatch() genMarker = []byte{} // Initialized but empty! ) - rawdb.WriteSnapshotBlockHash(batch, blockHash) + customrawdb.WriteSnapshotBlockHash(batch, blockHash) rawdb.WriteSnapshotRoot(batch, root) journalProgress(batch, genMarker, stats) if err := batch.Write(); err != nil { diff --git a/core/state/snapshot/generate_test.go b/core/state/snapshot/generate_test.go index a31756d06b..94549d1f49 100644 --- a/core/state/snapshot/generate_test.go +++ b/core/state/snapshot/generate_test.go @@ -32,17 +32,17 @@ import ( "testing" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/triedb/hashdb" "github.com/ava-labs/coreth/triedb/pathdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/triedb" "github.com/holiman/uint256" "golang.org/x/crypto/sha3" ) @@ -176,9 +176,9 @@ func newHelper(scheme string) *testHelper { diskdb := rawdb.NewMemoryDatabase() config := &triedb.Config{} if scheme == rawdb.PathScheme { - config.PathDB = &pathdb.Config{} // disable caching + config.DBOverride = pathdb.Config{}.BackendConstructor // disable caching } else { - config.HashDB = &hashdb.Config{} // disable caching + config.DBOverride = hashdb.Config{}.BackendConstructor // disable caching } triedb := triedb.NewDatabase(diskdb, config) accTrie, _ := trie.NewStateTrie(trie.StateTrieID(types.EmptyRootHash), triedb) diff --git a/core/state/snapshot/iterator.go b/core/state/snapshot/iterator.go index b7cf84ec91..46da2873f9 100644 --- a/core/state/snapshot/iterator.go +++ b/core/state/snapshot/iterator.go @@ -31,51 +31,23 @@ import ( "fmt" "sort" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + ethsnapshot "github.com/ava-labs/libevm/core/state/snapshot" + "github.com/ava-labs/libevm/ethdb" ) // Iterator is an iterator to step over all the accounts or the specific // storage in a snapshot which may or may not be composed of multiple layers. -type Iterator interface { - // Next steps the iterator forward one element, returning false if exhausted, - // or an error if iteration failed for some reason (e.g. root being iterated - // becomes stale and garbage collected). - Next() bool - - // Error returns any failure that occurred during iteration, which might have - // caused a premature iteration exit (e.g. snapshot stack becoming stale). - Error() error - - // Hash returns the hash of the account or storage slot the iterator is - // currently at. - Hash() common.Hash - - // Release releases associated resources. Release should always succeed and - // can be called multiple times without causing error. - Release() -} +type Iterator = ethsnapshot.Iterator // AccountIterator is an iterator to step over all the accounts in a snapshot, // which may or may not be composed of multiple layers. -type AccountIterator interface { - Iterator - - // Account returns the RLP encoded slim account the iterator is currently at. - // An error will be returned if the iterator becomes invalid - Account() []byte -} +type AccountIterator = ethsnapshot.AccountIterator // StorageIterator is an iterator to step over the specific storage in a snapshot, // which may or may not be composed of multiple layers. -type StorageIterator interface { - Iterator - - // Slot returns the storage slot the iterator is currently at. An error will - // be returned if the iterator becomes invalid - Slot() []byte -} +type StorageIterator = ethsnapshot.StorageIterator // diffAccountIterator is an account iterator that steps over the accounts (both // live and deleted) contained within a single diff layer. Higher order iterators diff --git a/core/state/snapshot/iterator_binary.go b/core/state/snapshot/iterator_binary.go index cff012402c..68f95901f7 100644 --- a/core/state/snapshot/iterator_binary.go +++ b/core/state/snapshot/iterator_binary.go @@ -29,7 +29,7 @@ package snapshot import ( "bytes" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // binaryIterator is a simplistic iterator to step over the accounts or storage diff --git a/core/state/snapshot/iterator_fast.go b/core/state/snapshot/iterator_fast.go index 4e324ee28b..d8dda5f71c 100644 --- a/core/state/snapshot/iterator_fast.go +++ b/core/state/snapshot/iterator_fast.go @@ -31,7 +31,7 @@ import ( "fmt" "sort" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "golang.org/x/exp/slices" ) diff --git a/core/state/snapshot/iterator_test.go b/core/state/snapshot/iterator_test.go index 7fc374a15a..b522ce0db0 100644 --- a/core/state/snapshot/iterator_test.go +++ b/core/state/snapshot/iterator_test.go @@ -34,8 +34,8 @@ import ( "math/rand" "testing" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" ) // TestAccountIteratorBasics tests some simple single-layer(diff and disk) iteration @@ -222,13 +222,13 @@ func TestAccountIteratorTraversal(t *testing.T) { // Create a snapshot tree with a single empty disk layer with the specified root and block hash snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) // Stack three diff layers on top with various overlaps - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xbb", "0xdd", "0xf0"), nil) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0xcc", "0xf0", "0xff"), nil) // Verify the single and multi-layer iterators @@ -263,13 +263,13 @@ func TestStorageIteratorTraversal(t *testing.T) { // Create an empty base layer and a snapshot tree out of it snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) // Stack three diff layers on top with various overlaps - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil)) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x04", "0x05", "0x06"}}, nil)) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x02", "0x03"}}, nil)) // Verify the single and multi-layer iterators @@ -279,7 +279,7 @@ func TestStorageIteratorTraversal(t *testing.T) { verifyIterator(t, 3, diffIter, verifyNothing) verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) - it, _ := snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.Hash{}, false) + it, _ := snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 6, it, verifyStorage) it.Release() @@ -296,7 +296,7 @@ func TestStorageIteratorTraversal(t *testing.T) { } verifyIterator(t, 6, head.(*diffLayer).newBinaryStorageIterator(common.HexToHash("0xaa")), verifyStorage) - it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.Hash{}, false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 6, it, verifyStorage) it.Release() } @@ -342,14 +342,14 @@ func TestAccountIteratorTraversalValues(t *testing.T) { } } // Assemble a stack of snapshots from the account layers - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, a, nil) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, b, nil) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, c, nil) - snaps.Update(common.HexToHash("0x05"), common.HexToHash("0xff05"), common.HexToHash("0x04"), nil, d, nil) - snaps.Update(common.HexToHash("0x06"), common.HexToHash("0xff06"), common.HexToHash("0x05"), nil, e, nil) - snaps.Update(common.HexToHash("0x07"), common.HexToHash("0xff07"), common.HexToHash("0x06"), nil, f, nil) - snaps.Update(common.HexToHash("0x08"), common.HexToHash("0xff08"), common.HexToHash("0x07"), nil, g, nil) - snaps.Update(common.HexToHash("0x09"), common.HexToHash("0xff09"), common.HexToHash("0x08"), nil, h, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, a, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, b, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, c, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x05"), common.HexToHash("0xff05"), common.HexToHash("0x04"), nil, d, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x06"), common.HexToHash("0xff06"), common.HexToHash("0x05"), nil, e, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x07"), common.HexToHash("0xff07"), common.HexToHash("0x06"), nil, f, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x08"), common.HexToHash("0xff08"), common.HexToHash("0x07"), nil, g, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x09"), common.HexToHash("0xff09"), common.HexToHash("0x08"), nil, h, nil) it, _ := snaps.AccountIterator(common.HexToHash("0xff09"), common.Hash{}, false) head := snaps.Snapshot(common.HexToHash("0xff09")) @@ -437,16 +437,16 @@ func TestStorageIteratorTraversalValues(t *testing.T) { } } // Assemble a stack of snapshots from the account layers - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa"), wrapStorage(a)) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xaa"), wrapStorage(b)) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0xaa"), wrapStorage(c)) - snaps.Update(common.HexToHash("0x05"), common.HexToHash("0xff05"), common.HexToHash("0x04"), nil, randomAccountSet("0xaa"), wrapStorage(d)) - snaps.Update(common.HexToHash("0x06"), common.HexToHash("0xff06"), common.HexToHash("0x05"), nil, randomAccountSet("0xaa"), wrapStorage(e)) - snaps.Update(common.HexToHash("0x07"), common.HexToHash("0xff07"), common.HexToHash("0x06"), nil, randomAccountSet("0xaa"), wrapStorage(e)) - snaps.Update(common.HexToHash("0x08"), common.HexToHash("0xff08"), common.HexToHash("0x07"), nil, randomAccountSet("0xaa"), wrapStorage(g)) - snaps.Update(common.HexToHash("0x09"), common.HexToHash("0xff09"), common.HexToHash("0x08"), nil, randomAccountSet("0xaa"), wrapStorage(h)) - - it, _ := snaps.StorageIterator(common.HexToHash("0xff09"), common.HexToHash("0xaa"), common.Hash{}, false) + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa"), wrapStorage(a)) + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xaa"), wrapStorage(b)) + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0xaa"), wrapStorage(c)) + snaps.UpdateWithBlockHashes(common.HexToHash("0x05"), common.HexToHash("0xff05"), common.HexToHash("0x04"), nil, randomAccountSet("0xaa"), wrapStorage(d)) + snaps.UpdateWithBlockHashes(common.HexToHash("0x06"), common.HexToHash("0xff06"), common.HexToHash("0x05"), nil, randomAccountSet("0xaa"), wrapStorage(e)) + snaps.UpdateWithBlockHashes(common.HexToHash("0x07"), common.HexToHash("0xff07"), common.HexToHash("0x06"), nil, randomAccountSet("0xaa"), wrapStorage(e)) + snaps.UpdateWithBlockHashes(common.HexToHash("0x08"), common.HexToHash("0xff08"), common.HexToHash("0x07"), nil, randomAccountSet("0xaa"), wrapStorage(g)) + snaps.UpdateWithBlockHashes(common.HexToHash("0x09"), common.HexToHash("0xff09"), common.HexToHash("0x08"), nil, randomAccountSet("0xaa"), wrapStorage(h)) + + it, _ := snaps.StorageIterator(common.HexToHash("0xff09"), common.HexToHash("0xaa"), common.Hash{}) head := snaps.Snapshot(common.HexToHash("0xff09")) for it.Next() { hash := it.Hash() @@ -474,7 +474,7 @@ func TestStorageIteratorTraversalValues(t *testing.T) { } } - it, _ = snaps.StorageIterator(common.HexToHash("0xff09"), common.HexToHash("0xaa"), common.Hash{}, false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff09"), common.HexToHash("0xaa"), common.Hash{}) for it.Next() { hash := it.Hash() want, err := head.Storage(common.HexToHash("0xaa"), hash) @@ -503,7 +503,7 @@ func TestAccountIteratorLargeTraversal(t *testing.T) { // Build up a large stack of snapshots snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) for i := 1; i < 128; i++ { - snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0xff%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil) + snaps.UpdateWithBlockHashes(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0xff%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil) } // Iterate the entire stack and ensure everything is hit only once head := snaps.Snapshot(common.HexToHash("0xff80")) @@ -543,13 +543,13 @@ func TestAccountIteratorFlattening(t *testing.T) { // Create an empty base layer and a snapshot tree out of it snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) // Create a stack of diffs on top - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xbb", "0xdd", "0xf0"), nil) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0xcc", "0xf0", "0xff"), nil) // Create an iterator and flatten the data from underneath it @@ -568,13 +568,13 @@ func TestAccountIteratorFlattening(t *testing.T) { func TestAccountIteratorSeek(t *testing.T) { // Create a snapshot stack with some initial data snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa", "0xee", "0xff", "0xf0"), nil) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xbb", "0xdd", "0xf0"), nil) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0xcc", "0xf0", "0xff"), nil) // Account set is now @@ -623,13 +623,13 @@ func TestStorageIteratorSeek(t *testing.T) { // Create a snapshot stack with some initial data snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) // Stack three diff layers on top with various overlaps - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil)) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x05", "0x06"}}, nil)) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x05", "0x08"}}, nil)) // Account set is now @@ -637,35 +637,35 @@ func TestStorageIteratorSeek(t *testing.T) { // 03: 01, 02, 03, 05 (, 05), 06 // 04: 01(, 01), 02, 03, 05(, 05, 05), 06, 08 // Construct various iterators and ensure their traversal is correct - it, _ := snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x01"), false) + it, _ := snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x01")) defer it.Release() verifyIterator(t, 3, it, verifyStorage) // expected: 01, 03, 05 - it, _ = snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x02"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x02")) defer it.Release() verifyIterator(t, 2, it, verifyStorage) // expected: 03, 05 - it, _ = snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x5"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x5")) defer it.Release() verifyIterator(t, 1, it, verifyStorage) // expected: 05 - it, _ = snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x6"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff02"), common.HexToHash("0xaa"), common.HexToHash("0x6")) defer it.Release() verifyIterator(t, 0, it, verifyStorage) // expected: nothing - it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x01"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x01")) defer it.Release() verifyIterator(t, 6, it, verifyStorage) // expected: 01, 02, 03, 05, 06, 08 - it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x05"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x05")) defer it.Release() verifyIterator(t, 3, it, verifyStorage) // expected: 05, 06, 08 - it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x08"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x08")) defer it.Release() verifyIterator(t, 1, it, verifyStorage) // expected: 08 - it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x09"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.HexToHash("0x09")) defer it.Release() verifyIterator(t, 0, it, verifyStorage) // expected: nothing } @@ -677,17 +677,17 @@ func TestAccountIteratorDeletions(t *testing.T) { // Create an empty base layer and a snapshot tree out of it snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) // Stack three diff layers on top with various overlaps - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0x11", "0x22", "0x33"), nil) deleted := common.HexToHash("0x22") destructed := map[common.Hash]struct{}{ deleted: {}, } - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), destructed, randomAccountSet("0x11", "0x33"), nil) - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, randomAccountSet("0x33", "0x44", "0x55"), nil) // The output should be 11,33,44,55 @@ -714,19 +714,19 @@ func TestStorageIteratorDeletions(t *testing.T) { // Create an empty base layer and a snapshot tree out of it snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) // Stack three diff layers on top with various overlaps - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x01", "0x03", "0x05"}}, nil)) - snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x02", "0x04", "0x06"}}, [][]string{{"0x01", "0x03"}})) // The output should be 02,04,05,06 - it, _ := snaps.StorageIterator(common.HexToHash("0xff03"), common.HexToHash("0xaa"), common.Hash{}, false) + it, _ := snaps.StorageIterator(common.HexToHash("0xff03"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 4, it, verifyStorage) it.Release() // The output should be 04,05,06 - it, _ = snaps.StorageIterator(common.HexToHash("0xff03"), common.HexToHash("0xaa"), common.HexToHash("0x03"), false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff03"), common.HexToHash("0xaa"), common.HexToHash("0x03")) verifyIterator(t, 3, it, verifyStorage) it.Release() @@ -734,24 +734,24 @@ func TestStorageIteratorDeletions(t *testing.T) { destructed := map[common.Hash]struct{}{ common.HexToHash("0xaa"): {}, } - snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), destructed, nil, nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), destructed, nil, nil) - it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.Hash{}, false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff04"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 0, it, verifyStorage) it.Release() // Re-insert the slots of the same account - snaps.Update(common.HexToHash("0x05"), common.HexToHash("0xff05"), common.HexToHash("0x04"), nil, + snaps.UpdateWithBlockHashes(common.HexToHash("0x05"), common.HexToHash("0xff05"), common.HexToHash("0x04"), nil, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x07", "0x08", "0x09"}}, nil)) // The output should be 07,08,09 - it, _ = snaps.StorageIterator(common.HexToHash("0xff05"), common.HexToHash("0xaa"), common.Hash{}, false) + it, _ = snaps.StorageIterator(common.HexToHash("0xff05"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 3, it, verifyStorage) it.Release() // Destruct the whole storage but re-create the account in the same layer - snaps.Update(common.HexToHash("0x06"), common.HexToHash("0xff06"), common.HexToHash("0x05"), destructed, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, nil)) - it, _ = snaps.StorageIterator(common.HexToHash("0xff06"), common.HexToHash("0xaa"), common.Hash{}, false) + snaps.UpdateWithBlockHashes(common.HexToHash("0x06"), common.HexToHash("0xff06"), common.HexToHash("0x05"), destructed, randomAccountSet("0xaa"), randomStorageSet([]string{"0xaa"}, [][]string{{"0x11", "0x12"}}, nil)) + it, _ = snaps.StorageIterator(common.HexToHash("0xff06"), common.HexToHash("0xaa"), common.Hash{}) verifyIterator(t, 2, it, verifyStorage) // The output should be 11,12 it.Release() @@ -783,7 +783,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) { // Build up a large stack of snapshots snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) for i := 1; i <= 100; i++ { - snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0xff%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil) + snaps.UpdateWithBlockHashes(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0xff%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(200), nil) } // We call this once before the benchmark, so the creation of // sorted accountlists are not included in the results. @@ -869,9 +869,9 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { } // Build up a large stack of snapshots snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) - snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, makeAccounts(2000), nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, makeAccounts(2000), nil) for i := 2; i <= 100; i++ { - snaps.Update(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0xff%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(20), nil) + snaps.UpdateWithBlockHashes(common.HexToHash(fmt.Sprintf("0x%02x", i+1)), common.HexToHash(fmt.Sprintf("0xff%02x", i+1)), common.HexToHash(fmt.Sprintf("0x%02x", i)), nil, makeAccounts(20), nil) } // We call this once before the benchmark, so the creation of // sorted accountlists are not included in the results. diff --git a/core/state/snapshot/journal.go b/core/state/snapshot/journal.go index 7e5c4c0aa0..1e02492d95 100644 --- a/core/state/snapshot/journal.go +++ b/core/state/snapshot/journal.go @@ -32,12 +32,13 @@ import ( "fmt" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/triedb" ) // journalGenerator is a disk layer entry containing the generator progress marker. @@ -59,7 +60,7 @@ type journalGenerator struct { func loadSnapshot(diskdb ethdb.KeyValueStore, triedb *triedb.Database, cache int, blockHash, root common.Hash, noBuild bool) (snapshot, bool, error) { // Retrieve the block number and hash of the snapshot, failing if no snapshot // is present in the database (or crashed mid-update). - baseBlockHash := rawdb.ReadSnapshotBlockHash(diskdb) + baseBlockHash := customrawdb.ReadSnapshotBlockHash(diskdb) if baseBlockHash == (common.Hash{}) { return nil, false, errors.New("missing or corrupted snapshot, no snapshot block hash") } diff --git a/core/state/snapshot/snapshot.go b/core/state/snapshot/snapshot.go index 53cb8b7ccc..6c5ead709b 100644 --- a/core/state/snapshot/snapshot.go +++ b/core/state/snapshot/snapshot.go @@ -34,13 +34,15 @@ import ( "sync" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/triedb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + ethsnapshot "github.com/ava-labs/libevm/core/state/snapshot" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/libevm/stateconf" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/triedb" ) const ( @@ -54,49 +56,55 @@ const ( skipGenThreshold = 500 * time.Millisecond ) +// ====== If resolving merge conflicts ====== +// +// All calls to metrics.NewRegistered*() for metrics also defined in libevm/core/state/snapshot +// have been replaced with metrics.GetOrRegister*() to get metrics already registered in +// libevm/core/state/snapshot or register them here otherwise. These replacements ensure the +// same metrics are shared between the two packages. var ( - snapshotCleanAccountHitMeter = metrics.NewRegisteredMeter("state/snapshot/clean/account/hit", nil) - snapshotCleanAccountMissMeter = metrics.NewRegisteredMeter("state/snapshot/clean/account/miss", nil) - snapshotCleanAccountInexMeter = metrics.NewRegisteredMeter("state/snapshot/clean/account/inex", nil) - snapshotCleanAccountReadMeter = metrics.NewRegisteredMeter("state/snapshot/clean/account/read", nil) - snapshotCleanAccountWriteMeter = metrics.NewRegisteredMeter("state/snapshot/clean/account/write", nil) - - snapshotCleanStorageHitMeter = metrics.NewRegisteredMeter("state/snapshot/clean/storage/hit", nil) - snapshotCleanStorageMissMeter = metrics.NewRegisteredMeter("state/snapshot/clean/storage/miss", nil) - snapshotCleanStorageInexMeter = metrics.NewRegisteredMeter("state/snapshot/clean/storage/inex", nil) - snapshotCleanStorageReadMeter = metrics.NewRegisteredMeter("state/snapshot/clean/storage/read", nil) - snapshotCleanStorageWriteMeter = metrics.NewRegisteredMeter("state/snapshot/clean/storage/write", nil) - - snapshotDirtyAccountHitMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/account/hit", nil) - snapshotDirtyAccountMissMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/account/miss", nil) - snapshotDirtyAccountInexMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/account/inex", nil) - snapshotDirtyAccountReadMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/account/read", nil) - snapshotDirtyAccountWriteMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/account/write", nil) - - snapshotDirtyStorageHitMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/storage/hit", nil) - snapshotDirtyStorageMissMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/storage/miss", nil) - snapshotDirtyStorageInexMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/storage/inex", nil) - snapshotDirtyStorageReadMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/storage/read", nil) - snapshotDirtyStorageWriteMeter = metrics.NewRegisteredMeter("state/snapshot/dirty/storage/write", nil) - - snapshotDirtyAccountHitDepthHist = metrics.NewRegisteredHistogram("state/snapshot/dirty/account/hit/depth", nil, metrics.NewExpDecaySample(1028, 0.015)) - snapshotDirtyStorageHitDepthHist = metrics.NewRegisteredHistogram("state/snapshot/dirty/storage/hit/depth", nil, metrics.NewExpDecaySample(1028, 0.015)) - - snapshotFlushAccountItemMeter = metrics.NewRegisteredMeter("state/snapshot/flush/account/item", nil) - snapshotFlushAccountSizeMeter = metrics.NewRegisteredMeter("state/snapshot/flush/account/size", nil) - snapshotFlushStorageItemMeter = metrics.NewRegisteredMeter("state/snapshot/flush/storage/item", nil) - snapshotFlushStorageSizeMeter = metrics.NewRegisteredMeter("state/snapshot/flush/storage/size", nil) - - snapshotBloomIndexTimer = metrics.NewRegisteredResettingTimer("state/snapshot/bloom/index", nil) - snapshotBloomErrorGauge = metrics.NewRegisteredGaugeFloat64("state/snapshot/bloom/error", nil) - - snapshotBloomAccountTrueHitMeter = metrics.NewRegisteredMeter("state/snapshot/bloom/account/truehit", nil) - snapshotBloomAccountFalseHitMeter = metrics.NewRegisteredMeter("state/snapshot/bloom/account/falsehit", nil) - snapshotBloomAccountMissMeter = metrics.NewRegisteredMeter("state/snapshot/bloom/account/miss", nil) - - snapshotBloomStorageTrueHitMeter = metrics.NewRegisteredMeter("state/snapshot/bloom/storage/truehit", nil) - snapshotBloomStorageFalseHitMeter = metrics.NewRegisteredMeter("state/snapshot/bloom/storage/falsehit", nil) - snapshotBloomStorageMissMeter = metrics.NewRegisteredMeter("state/snapshot/bloom/storage/miss", nil) + snapshotCleanAccountHitMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/account/hit", nil) + snapshotCleanAccountMissMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/account/miss", nil) + snapshotCleanAccountInexMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/account/inex", nil) + snapshotCleanAccountReadMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/account/read", nil) + snapshotCleanAccountWriteMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/account/write", nil) + + snapshotCleanStorageHitMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/storage/hit", nil) + snapshotCleanStorageMissMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/storage/miss", nil) + snapshotCleanStorageInexMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/storage/inex", nil) + snapshotCleanStorageReadMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/storage/read", nil) + snapshotCleanStorageWriteMeter = metrics.GetOrRegisterMeter("state/snapshot/clean/storage/write", nil) + + snapshotDirtyAccountHitMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/account/hit", nil) + snapshotDirtyAccountMissMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/account/miss", nil) + snapshotDirtyAccountInexMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/account/inex", nil) + snapshotDirtyAccountReadMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/account/read", nil) + snapshotDirtyAccountWriteMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/account/write", nil) + + snapshotDirtyStorageHitMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/storage/hit", nil) + snapshotDirtyStorageMissMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/storage/miss", nil) + snapshotDirtyStorageInexMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/storage/inex", nil) + snapshotDirtyStorageReadMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/storage/read", nil) + snapshotDirtyStorageWriteMeter = metrics.GetOrRegisterMeter("state/snapshot/dirty/storage/write", nil) + + snapshotDirtyAccountHitDepthHist = metrics.GetOrRegisterHistogram("state/snapshot/dirty/account/hit/depth", nil, metrics.NewExpDecaySample(1028, 0.015)) + snapshotDirtyStorageHitDepthHist = metrics.GetOrRegisterHistogram("state/snapshot/dirty/storage/hit/depth", nil, metrics.NewExpDecaySample(1028, 0.015)) + + snapshotFlushAccountItemMeter = metrics.GetOrRegisterMeter("state/snapshot/flush/account/item", nil) + snapshotFlushAccountSizeMeter = metrics.GetOrRegisterMeter("state/snapshot/flush/account/size", nil) + snapshotFlushStorageItemMeter = metrics.GetOrRegisterMeter("state/snapshot/flush/storage/item", nil) + snapshotFlushStorageSizeMeter = metrics.GetOrRegisterMeter("state/snapshot/flush/storage/size", nil) + + snapshotBloomIndexTimer = metrics.GetOrRegisterResettingTimer("state/snapshot/bloom/index", nil) + snapshotBloomErrorGauge = metrics.GetOrRegisterGaugeFloat64("state/snapshot/bloom/error", nil) + + snapshotBloomAccountTrueHitMeter = metrics.GetOrRegisterMeter("state/snapshot/bloom/account/truehit", nil) + snapshotBloomAccountFalseHitMeter = metrics.GetOrRegisterMeter("state/snapshot/bloom/account/falsehit", nil) + snapshotBloomAccountMissMeter = metrics.GetOrRegisterMeter("state/snapshot/bloom/account/miss", nil) + + snapshotBloomStorageTrueHitMeter = metrics.GetOrRegisterMeter("state/snapshot/bloom/storage/truehit", nil) + snapshotBloomStorageFalseHitMeter = metrics.GetOrRegisterMeter("state/snapshot/bloom/storage/falsehit", nil) + snapshotBloomStorageMissMeter = metrics.GetOrRegisterMeter("state/snapshot/bloom/storage/miss", nil) // ErrSnapshotStale is returned from data accessors if the underlying snapshot // layer had been invalidated due to the chain progressing forward far enough @@ -118,28 +126,7 @@ var ( ) // Snapshot represents the functionality supported by a snapshot storage layer. -type Snapshot interface { - // Root returns the root hash for which this snapshot was made. - Root() common.Hash - - // Account directly retrieves the account associated with a particular hash in - // the snapshot slim data format. - Account(hash common.Hash) (*types.SlimAccount, error) - - // AccountRLP directly retrieves the account RLP associated with a particular - // hash in the snapshot slim data format. - AccountRLP(hash common.Hash) ([]byte, error) - - // Storage directly retrieves the storage data associated with a particular hash, - // within a particular account. - Storage(accountHash, storageHash common.Hash) ([]byte, error) - - // AccountIterator creates an account iterator over the account trie given by the provided root hash. - AccountIterator(seek common.Hash) AccountIterator - - // StorageIterator creates a storage iterator over the storage trie given by the provided root hash. - StorageIterator(account common.Hash, seek common.Hash) (StorageIterator, bool) -} +type Snapshot = ethsnapshot.Snapshot // snapshot is the internal version of the snapshot data layer that supports some // additional methods compared to the public API. @@ -164,6 +151,12 @@ type snapshot interface { // Stale return whether this layer has become stale (was flattened across) or // if it's still live. Stale() bool + + // AccountIterator creates an account iterator over an arbitrary layer. + AccountIterator(seek common.Hash) AccountIterator + + // StorageIterator creates a storage iterator over an arbitrary layer. + StorageIterator(account common.Hash, seek common.Hash) (StorageIterator, bool) } // Config includes the configurations for snapshots. @@ -321,9 +314,44 @@ func (t *Tree) Snapshots(blockHash common.Hash, limits int, nodisk bool) []Snaps return ret } +type blockHashes struct { + blockHash common.Hash + parentBlockHash common.Hash +} + +func WithBlockHashes(blockHash, parentBlockHash common.Hash) stateconf.SnapshotUpdateOption { + return stateconf.WithUpdatePayload(blockHashes{blockHash, parentBlockHash}) +} + // Update adds a new snapshot into the tree, if that can be linked to an existing // old parent. It is disallowed to insert a disk layer (the origin of all). -func (t *Tree) Update(blockHash, blockRoot, parentBlockHash common.Hash, destructs map[common.Hash]struct{}, accounts map[common.Hash][]byte, storage map[common.Hash]map[common.Hash][]byte) error { +func (t *Tree) Update( + blockRoot common.Hash, + parentRoot common.Hash, + destructs map[common.Hash]struct{}, + accounts map[common.Hash][]byte, + storage map[common.Hash]map[common.Hash][]byte, + opts ...stateconf.SnapshotUpdateOption, +) error { + if len(opts) == 0 { + return fmt.Errorf("missing block hashes") + } + + payload := stateconf.ExtractUpdatePayload(opts[0]) + p, ok := payload.(blockHashes) + if !ok { + return fmt.Errorf("invalid block hashes payload type: %T", payload) + } + + return t.UpdateWithBlockHashes(p.blockHash, blockRoot, p.parentBlockHash, destructs, accounts, storage) +} + +func (t *Tree) UpdateWithBlockHashes( + blockHash, blockRoot, parentBlockHash common.Hash, + destructs map[common.Hash]struct{}, + accounts map[common.Hash][]byte, + storage map[common.Hash]map[common.Hash][]byte, +) error { t.lock.Lock() defer t.lock.Unlock() @@ -381,6 +409,10 @@ func (t *Tree) verifyIntegrity(base *diskLayer, waitBuild bool) error { return nil } +func (t *Tree) Cap(root common.Hash, layers int) error { + return nil // No-op as this code uses Flatten on block accept instead +} + // Flatten flattens the snapshot for [blockHash] into its parent. if its // parent is not a disk layer, Flatten will return an error. // Note: a blockHash is used instead of a state root so that the exact state @@ -605,7 +637,7 @@ func diffToDisk(bottom *diffLayer) (*diskLayer, bool, error) { base.abortGeneration() // Put the deletion in the batch writer, flush all updates in the final step. - rawdb.DeleteSnapshotBlockHash(batch) + customrawdb.DeleteSnapshotBlockHash(batch) rawdb.DeleteSnapshotRoot(batch) // Mark the original base as stale as we're going to create a new wrapper @@ -697,7 +729,7 @@ func diffToDisk(bottom *diffLayer) (*diskLayer, bool, error) { } } // Update the snapshot block marker and write any remainder data - rawdb.WriteSnapshotBlockHash(batch, bottom.blockHash) + customrawdb.WriteSnapshotBlockHash(batch, bottom.blockHash) rawdb.WriteSnapshotRoot(batch, bottom.root) // Write out the generator progress marker and report @@ -823,7 +855,11 @@ func (t *Tree) AccountIterator(root common.Hash, seek common.Hash, force bool) ( // account. The iterator will be move to the specific start position. When [force] // is true, a new account iterator is created without acquiring the [snapTree] // lock and without confirming that the snapshot on the disk layer is fully generated. -func (t *Tree) StorageIterator(root common.Hash, account common.Hash, seek common.Hash, force bool) (StorageIterator, error) { +func (t *Tree) StorageIterator(root common.Hash, account common.Hash, seek common.Hash) (StorageIterator, error) { + return t.StorageIteratorWithForce(root, account, seek, false) +} + +func (t *Tree) StorageIteratorWithForce(root common.Hash, account common.Hash, seek common.Hash, force bool) (StorageIterator, error) { if !force { ok, err := t.generating() if err != nil { @@ -854,7 +890,7 @@ func (t *Tree) verify(root common.Hash, force bool) error { defer acctIt.Release() got, err := generateTrieRoot(nil, "", acctIt, common.Hash{}, stackTrieGenerate, func(db ethdb.KeyValueWriter, accountHash, codeHash common.Hash, stat *generateStats) (common.Hash, error) { - storageIt, err := t.StorageIterator(root, accountHash, common.Hash{}, force) + storageIt, err := t.StorageIteratorWithForce(root, accountHash, common.Hash{}, force) if err != nil { return common.Hash{}, err } diff --git a/core/state/snapshot/snapshot_ext.go b/core/state/snapshot/snapshot_ext.go index 1274e4805d..8b73f83fcc 100644 --- a/core/state/snapshot/snapshot_ext.go +++ b/core/state/snapshot/snapshot_ext.go @@ -4,8 +4,8 @@ import ( "time" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/ethdb" ) func (t *Tree) DiskAccountIterator(seek common.Hash) AccountIterator { @@ -23,9 +23,19 @@ func (t *Tree) DiskStorageIterator(account common.Hash, seek common.Hash) Storag return it } +type SnapshotIterable interface { + Snapshot + + // AccountIterator creates an account iterator over an arbitrary layer. + AccountIterator(seek common.Hash) AccountIterator + + // StorageIterator creates a storage iterator over an arbitrary layer. + StorageIterator(account common.Hash, seek common.Hash) (StorageIterator, bool) +} + // NewDiskLayer creates a diskLayer for direct access to the contents of the on-disk // snapshot. Does not perform any validation. -func NewDiskLayer(diskdb ethdb.KeyValueStore) Snapshot { +func NewDiskLayer(diskdb ethdb.KeyValueStore) SnapshotIterable { return &diskLayer{ diskdb: diskdb, created: time.Now(), diff --git a/core/state/snapshot/snapshot_test.go b/core/state/snapshot/snapshot_test.go index 67f6ba40f5..06e6d5a1a1 100644 --- a/core/state/snapshot/snapshot_test.go +++ b/core/state/snapshot/snapshot_test.go @@ -33,10 +33,10 @@ import ( "testing" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" "github.com/holiman/uint256" ) @@ -106,7 +106,7 @@ func TestDiskLayerExternalInvalidationFullFlatten(t *testing.T) { accounts := map[common.Hash][]byte{ common.HexToHash("0xa1"): randomAccount(), } - if err := snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } if n := snaps.NumStateLayers(); n != 2 { @@ -147,10 +147,10 @@ func TestDiskLayerExternalInvalidationPartialFlatten(t *testing.T) { accounts := map[common.Hash][]byte{ common.HexToHash("0xa1"): randomAccount(), } - if err := snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } - if err := snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } if n := snaps.NumBlockLayers(); n != 3 { @@ -196,13 +196,13 @@ func TestDiffLayerExternalInvalidationPartialFlatten(t *testing.T) { accounts := map[common.Hash][]byte{ common.HexToHash("0xa1"): randomAccount(), } - if err := snaps.Update(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(common.HexToHash("0x02"), common.HexToHash("0xff02"), common.HexToHash("0x01"), nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } - if err := snaps.Update(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(common.HexToHash("0x03"), common.HexToHash("0xff03"), common.HexToHash("0x02"), nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } - if err := snaps.Update(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(common.HexToHash("0x04"), common.HexToHash("0xff04"), common.HexToHash("0x03"), nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } if n := snaps.NumStateLayers(); n != 4 { @@ -244,12 +244,12 @@ func TestPostFlattenBasicDataAccess(t *testing.T) { // Create a starting base layer and a snapshot tree out of it snaps := NewTestTree(rawdb.NewMemoryDatabase(), common.HexToHash("0x01"), common.HexToHash("0xff01")) // The lowest difflayer - snaps.Update(common.HexToHash("0xa1"), common.HexToHash("0xffa1"), common.HexToHash("0x01"), nil, setAccount("0xa1"), nil) - snaps.Update(common.HexToHash("0xa2"), common.HexToHash("0xffa2"), common.HexToHash("0xa1"), nil, setAccount("0xa2"), nil) - snaps.Update(common.HexToHash("0xb2"), common.HexToHash("0xffb2"), common.HexToHash("0xa1"), nil, setAccount("0xb2"), nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0xa1"), common.HexToHash("0xffa1"), common.HexToHash("0x01"), nil, setAccount("0xa1"), nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0xa2"), common.HexToHash("0xffa2"), common.HexToHash("0xa1"), nil, setAccount("0xa2"), nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0xb2"), common.HexToHash("0xffb2"), common.HexToHash("0xa1"), nil, setAccount("0xb2"), nil) - snaps.Update(common.HexToHash("0xa3"), common.HexToHash("0xffa3"), common.HexToHash("0xa2"), nil, setAccount("0xa3"), nil) - snaps.Update(common.HexToHash("0xb3"), common.HexToHash("0xffb3"), common.HexToHash("0xb2"), nil, setAccount("0xb3"), nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0xa3"), common.HexToHash("0xffa3"), common.HexToHash("0xa2"), nil, setAccount("0xa3"), nil) + snaps.UpdateWithBlockHashes(common.HexToHash("0xb3"), common.HexToHash("0xffb3"), common.HexToHash("0xb2"), nil, setAccount("0xb3"), nil) // checkExist verifies if an account exists in a snapshot checkExist := func(layer Snapshot, key string) error { @@ -434,10 +434,10 @@ func TestTreeFlattenDoesNotDropPendingLayers(t *testing.T) { diffBlockAHash := common.Hash{0xee, 0xee, byte(i)} diffBlockBHash := common.Hash{0xdd, 0xdd, byte(i)} diffBlockRoot := common.Hash{0xff, 0xff, byte(i)} - if err := snaps.Update(diffBlockAHash, diffBlockRoot, parentAHash, nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockAHash, diffBlockRoot, parentAHash, nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } - if err := snaps.Update(diffBlockBHash, diffBlockRoot, parentBHash, nil, accounts, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockBHash, diffBlockRoot, parentBHash, nil, accounts, nil); err != nil { t.Fatalf("failed to create a diff layer: %v", err) } @@ -509,7 +509,7 @@ func TestStaleOriginLayer(t *testing.T) { } // Create diff layer A containing account 0xa1 - if err := snaps.Update(diffBlockHashA, diffRootA, baseBlockHash, nil, accountsA, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockHashA, diffRootA, baseBlockHash, nil, accountsA, nil); err != nil { t.Errorf("failed to create diff layer A: %v", err) } // Flatten account 0xa1 to disk @@ -519,12 +519,12 @@ func TestStaleOriginLayer(t *testing.T) { } // Create diff layer B containing account 0xa2 // The bloom filter should contain only 0xa2. - if err := snaps.Update(diffBlockHashB, diffRootB, diffBlockHashA, nil, accountsB, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockHashB, diffRootB, diffBlockHashA, nil, accountsB, nil); err != nil { t.Errorf("failed to create diff layer B: %v", err) } // Create diff layer C containing account 0xa3 // The bloom filter should contain 0xa2 and 0xa3 - if err := snaps.Update(diffBlockHashC, diffRootC, diffBlockHashB, nil, accountsC, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockHashC, diffRootC, diffBlockHashB, nil, accountsC, nil); err != nil { t.Errorf("failed to create diff layer C: %v", err) } @@ -591,16 +591,16 @@ func TestRebloomOnFlatten(t *testing.T) { } // Build the tree - if err := snaps.Update(diffBlockHashA, diffRootA, baseBlockHash, nil, accountsA, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockHashA, diffRootA, baseBlockHash, nil, accountsA, nil); err != nil { t.Errorf("failed to create diff layer A: %v", err) } - if err := snaps.Update(diffBlockHashB, diffRootB, diffBlockHashA, nil, accountsB, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockHashB, diffRootB, diffBlockHashA, nil, accountsB, nil); err != nil { t.Errorf("failed to create diff layer B: %v", err) } - if err := snaps.Update(diffBlockHashC, diffRootC, diffBlockHashB, nil, accountsC, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockHashC, diffRootC, diffBlockHashB, nil, accountsC, nil); err != nil { t.Errorf("failed to create diff layer C: %v", err) } - if err := snaps.Update(diffBlockHashD, diffRootD, diffBlockHashB, nil, accountsD, nil); err != nil { + if err := snaps.UpdateWithBlockHashes(diffBlockHashD, diffRootD, diffBlockHashB, nil, accountsD, nil); err != nil { t.Errorf("failed to create diff layer D: %v", err) } @@ -687,9 +687,9 @@ func TestReadStateDuringFlattening(t *testing.T) { snaps := NewTestTree(rawdb.NewMemoryDatabase(), baseBlockHash, baseRoot) // 4 layers in total, 3 diff layers and 1 disk layers - snaps.Update(diffBlockHashA, diffRootA, baseBlockHash, nil, setAccount("0xa1"), nil) - snaps.Update(diffBlockHashB, diffRootB, diffBlockHashA, nil, setAccount("0xa2"), nil) - snaps.Update(diffBlockHashC, diffRootC, diffBlockHashB, nil, setAccount("0xa3"), nil) + snaps.UpdateWithBlockHashes(diffBlockHashA, diffRootA, baseBlockHash, nil, setAccount("0xa1"), nil) + snaps.UpdateWithBlockHashes(diffBlockHashB, diffRootB, diffBlockHashA, nil, setAccount("0xa2"), nil) + snaps.UpdateWithBlockHashes(diffBlockHashC, diffRootC, diffBlockHashB, nil, setAccount("0xa3"), nil) // Obtain the topmost snapshot handler for state accessing snap := snaps.Snapshot(diffRootC) diff --git a/core/state/snapshot/utils.go b/core/state/snapshot/utils.go index f9e2db5ad6..020a7aee3c 100644 --- a/core/state/snapshot/utils.go +++ b/core/state/snapshot/utils.go @@ -31,10 +31,10 @@ import ( "fmt" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" ) // CheckDanglingStorage iterates the snap storage data, and verifies that all diff --git a/core/state/snapshot/wipe.go b/core/state/snapshot/wipe.go index 37963032e6..12726a23a8 100644 --- a/core/state/snapshot/wipe.go +++ b/core/state/snapshot/wipe.go @@ -30,10 +30,11 @@ import ( "bytes" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" ) // WipeSnapshot starts a goroutine to iterate over the entire key-value database @@ -43,7 +44,7 @@ import ( func WipeSnapshot(db ethdb.KeyValueStore, full bool) chan struct{} { // Wipe the snapshot root marker synchronously if full { - rawdb.DeleteSnapshotBlockHash(db) + customrawdb.DeleteSnapshotBlockHash(db) rawdb.DeleteSnapshotRoot(db) } // Wipe everything else asynchronously diff --git a/core/state/snapshot/wipe_test.go b/core/state/snapshot/wipe_test.go index 74afec5fce..309ba3de8a 100644 --- a/core/state/snapshot/wipe_test.go +++ b/core/state/snapshot/wipe_test.go @@ -30,9 +30,10 @@ import ( "math/rand" "testing" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb/memorydb" ) // Tests that given a database with random data content, all parts of a snapshot @@ -43,7 +44,7 @@ func TestWipe(t *testing.T) { for i := 0; i < 128; i++ { rawdb.WriteAccountSnapshot(db, randomHash(), randomHash().Bytes()) } - rawdb.WriteSnapshotBlockHash(db, randomHash()) + customrawdb.WriteSnapshotBlockHash(db, randomHash()) rawdb.WriteSnapshotRoot(db, randomHash()) // Add some random non-snapshot data too to make wiping harder @@ -70,7 +71,7 @@ func TestWipe(t *testing.T) { if items := count(); items != 128 { t.Fatalf("snapshot size mismatch: have %d, want %d", items, 128) } - if hash := rawdb.ReadSnapshotBlockHash(db); hash == (common.Hash{}) { + if hash := customrawdb.ReadSnapshotBlockHash(db); hash == (common.Hash{}) { t.Errorf("snapshot block hash marker mismatch: have %#x, want ", hash) } if hash := rawdb.ReadSnapshotRoot(db); hash == (common.Hash{}) { @@ -94,7 +95,7 @@ func TestWipe(t *testing.T) { t.Fatalf("misc item count mismatch: have %d, want %d", items, 1000) } - if hash := rawdb.ReadSnapshotBlockHash(db); hash != (common.Hash{}) { + if hash := customrawdb.ReadSnapshotBlockHash(db); hash != (common.Hash{}) { t.Errorf("snapshot block hash marker remained after wipe: %#x", hash) } if hash := rawdb.ReadSnapshotRoot(db); hash != (common.Hash{}) { diff --git a/core/state/state_object.go b/core/state/state_object.go deleted file mode 100644 index ed3f16ff9e..0000000000 --- a/core/state/state_object.go +++ /dev/null @@ -1,621 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "bytes" - "fmt" - "io" - "math/big" - "time" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "github.com/holiman/uint256" -) - -type Code []byte - -func (c Code) String() string { - return string(c) //strings.Join(Disassemble(c), " ") -} - -type Storage map[common.Hash]common.Hash - -func (s Storage) String() (str string) { - for key, value := range s { - str += fmt.Sprintf("%X : %X\n", key, value) - } - return -} - -func (s Storage) Copy() Storage { - cpy := make(Storage, len(s)) - for key, value := range s { - cpy[key] = value - } - return cpy -} - -// stateObject represents an Ethereum account which is being modified. -// -// The usage pattern is as follows: -// - First you need to obtain a state object. -// - Account values as well as storages can be accessed and modified through the object. -// - Finally, call commit to return the changes of storage trie and update account data. -type stateObject struct { - db *StateDB - address common.Address // address of ethereum account - addrHash common.Hash // hash of ethereum address of the account - origin *types.StateAccount // Account original data without any change applied, nil means it was not existent - data types.StateAccount // Account data with all mutations applied in the scope of block - - // Write caches. - trie Trie // storage trie, which becomes non-nil on first access - code Code // contract bytecode, which gets set when code is loaded - - originStorage Storage // Storage cache of original entries to dedup rewrites - pendingStorage Storage // Storage entries that need to be flushed to disk, at the end of an entire block - dirtyStorage Storage // Storage entries that have been modified in the current transaction execution, reset for every transaction - - // Cache flags. - dirtyCode bool // true if the code was updated - - // Flag whether the account was marked as self-destructed. The self-destructed account - // is still accessible in the scope of same transaction. - selfDestructed bool - - // Flag whether the account was marked as deleted. A self-destructed account - // or an account that is considered as empty will be marked as deleted at - // the end of transaction and no longer accessible anymore. - deleted bool - - // Flag whether the object was created in the current transaction - created bool -} - -// empty returns whether the account is considered empty. -func (s *stateObject) empty() bool { - return s.data.Nonce == 0 && s.data.Balance.IsZero() && bytes.Equal(s.data.CodeHash, types.EmptyCodeHash.Bytes()) && !s.data.IsMultiCoin -} - -// newObject creates a state object. -func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *stateObject { - var ( - origin = acct - created = acct == nil // true if the account was not existent - ) - if acct == nil { - acct = types.NewEmptyStateAccount() - } - return &stateObject{ - db: db, - address: address, - addrHash: crypto.Keccak256Hash(address[:]), - origin: origin, - data: *acct, - originStorage: make(Storage), - pendingStorage: make(Storage), - dirtyStorage: make(Storage), - created: created, - } -} - -// EncodeRLP implements rlp.Encoder. -func (s *stateObject) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, &s.data) -} - -func (s *stateObject) markSelfdestructed() { - s.selfDestructed = true -} - -func (s *stateObject) touch() { - s.db.journal.append(touchChange{ - account: &s.address, - }) - if s.address == ripemd { - // Explicitly put it in the dirty-cache, which is otherwise generated from - // flattened journals. - s.db.journal.dirty(s.address) - } -} - -// getTrie returns the associated storage trie. The trie will be opened -// if it's not loaded previously. An error will be returned if trie can't -// be loaded. -func (s *stateObject) getTrie() (Trie, error) { - if s.trie == nil { - // Try fetching from prefetcher first - if s.data.Root != types.EmptyRootHash && s.db.prefetcher != nil { - // When the miner is creating the pending state, there is no prefetcher - s.trie = s.db.prefetcher.trie(s.addrHash, s.data.Root) - } - if s.trie == nil { - tr, err := s.db.db.OpenStorageTrie(s.db.originalRoot, s.address, s.data.Root, s.db.trie) - if err != nil { - return nil, err - } - s.trie = tr - } - } - return s.trie, nil -} - -// GetState retrieves a value from the account storage trie. -func (s *stateObject) GetState(key common.Hash) common.Hash { - // If we have a dirty value for this state entry, return it - value, dirty := s.dirtyStorage[key] - if dirty { - return value - } - // Otherwise return the entry's original value - return s.GetCommittedState(key) -} - -// GetCommittedState retrieves a value from the committed account storage trie. -func (s *stateObject) GetCommittedState(key common.Hash) common.Hash { - // If we have a pending write or clean cached, return that - if value, pending := s.pendingStorage[key]; pending { - return value - } - if value, cached := s.originStorage[key]; cached { - return value - } - // If the object was destructed in *this* block (and potentially resurrected), - // the storage has been cleared out, and we should *not* consult the previous - // database about any storage values. The only possible alternatives are: - // 1) resurrect happened, and new slot values were set -- those should - // have been handles via pendingStorage above. - // 2) we don't have new values, and can deliver empty response back - if _, destructed := s.db.stateObjectsDestruct[s.address]; destructed { - return common.Hash{} - } - // If no live objects are available, attempt to use snapshots - var ( - enc []byte - err error - value common.Hash - ) - if s.db.snap != nil { - start := time.Now() - enc, err = s.db.snap.Storage(s.addrHash, crypto.Keccak256Hash(key.Bytes())) - if metrics.EnabledExpensive { - s.db.SnapshotStorageReads += time.Since(start) - } - if len(enc) > 0 { - _, content, _, err := rlp.Split(enc) - if err != nil { - s.db.setError(err) - } - value.SetBytes(content) - } - } - // If the snapshot is unavailable or reading from it fails, load from the database. - if s.db.snap == nil || err != nil { - start := time.Now() - tr, err := s.getTrie() - if err != nil { - s.db.setError(err) - return common.Hash{} - } - val, err := tr.GetStorage(s.address, key.Bytes()) - if metrics.EnabledExpensive { - s.db.StorageReads += time.Since(start) - } - if err != nil { - s.db.setError(err) - return common.Hash{} - } - value.SetBytes(val) - } - s.originStorage[key] = value - return value -} - -// SetState updates a value in account storage. -func (s *stateObject) SetState(key, value common.Hash) { - // If the new value is the same as old, don't set - prev := s.GetState(key) - if prev == value { - return - } - // New value is different, update and journal the change - s.db.journal.append(storageChange{ - account: &s.address, - key: key, - prevalue: prev, - }) - s.setState(key, value) -} - -func (s *stateObject) setState(key, value common.Hash) { - s.dirtyStorage[key] = value -} - -// finalise moves all dirty storage slots into the pending area to be hashed or -// committed later. It is invoked at the end of every transaction. -func (s *stateObject) finalise(prefetch bool) { - slotsToPrefetch := make([][]byte, 0, len(s.dirtyStorage)) - for key, value := range s.dirtyStorage { - s.pendingStorage[key] = value - if value != s.originStorage[key] { - slotsToPrefetch = append(slotsToPrefetch, common.CopyBytes(key[:])) // Copy needed for closure - } - } - if s.db.prefetcher != nil && prefetch && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash { - s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, slotsToPrefetch) - } - if len(s.dirtyStorage) > 0 { - s.dirtyStorage = make(Storage) - } -} - -// updateTrie is responsible for persisting cached storage changes into the -// object's storage trie. In case the storage trie is not yet loaded, this -// function will load the trie automatically. If any issues arise during the -// loading or updating of the trie, an error will be returned. Furthermore, -// this function will return the mutated storage trie, or nil if there is no -// storage change at all. -func (s *stateObject) updateTrie() (Trie, error) { - // Make sure all dirty slots are finalized into the pending storage area - s.finalise(false) - - // Short circuit if nothing changed, don't bother with hashing anything - if len(s.pendingStorage) == 0 { - return s.trie, nil - } - // Track the amount of time wasted on updating the storage trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.db.StorageUpdates += time.Since(start) }(time.Now()) - } - // The snapshot storage map for the object - var ( - storage map[common.Hash][]byte - origin map[common.Hash][]byte - ) - tr, err := s.getTrie() - if err != nil { - s.db.setError(err) - return nil, err - } - // Insert all the pending storage updates into the trie - usedStorage := make([][]byte, 0, len(s.pendingStorage)) - for key, value := range s.pendingStorage { - // Skip noop changes, persist actual changes - if value == s.originStorage[key] { - continue - } - prev := s.originStorage[key] - s.originStorage[key] = value - - var encoded []byte // rlp-encoded value to be used by the snapshot - if (value == common.Hash{}) { - if err := tr.DeleteStorage(s.address, key[:]); err != nil { - s.db.setError(err) - return nil, err - } - s.db.StorageDeleted += 1 - } else { - // Encoding []byte cannot fail, ok to ignore the error. - trimmed := common.TrimLeftZeroes(value[:]) - encoded, _ = rlp.EncodeToBytes(trimmed) - if err := tr.UpdateStorage(s.address, key[:], trimmed); err != nil { - s.db.setError(err) - return nil, err - } - s.db.StorageUpdated += 1 - } - // Cache the mutated storage slots until commit - if storage == nil { - if storage = s.db.storages[s.addrHash]; storage == nil { - storage = make(map[common.Hash][]byte) - s.db.storages[s.addrHash] = storage - } - } - khash := crypto.HashData(s.db.hasher, key[:]) - storage[khash] = encoded // encoded will be nil if it's deleted - - // Cache the original value of mutated storage slots - if origin == nil { - if origin = s.db.storagesOrigin[s.address]; origin == nil { - origin = make(map[common.Hash][]byte) - s.db.storagesOrigin[s.address] = origin - } - } - // Track the original value of slot only if it's mutated first time - if _, ok := origin[khash]; !ok { - if prev == (common.Hash{}) { - origin[khash] = nil // nil if it was not present previously - } else { - // Encoding []byte cannot fail, ok to ignore the error. - b, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(prev[:])) - origin[khash] = b - } - } - // Cache the items for preloading - usedStorage = append(usedStorage, common.CopyBytes(key[:])) // Copy needed for closure - } - if s.db.prefetcher != nil { - s.db.prefetcher.used(s.addrHash, s.data.Root, usedStorage) - } - s.pendingStorage = make(Storage) // reset pending map - return tr, nil -} - -// updateRoot flushes all cached storage mutations to trie, recalculating the -// new storage trie root. -func (s *stateObject) updateRoot() { - // Flush cached storage mutations into trie, short circuit if any error - // is occurred or there is not change in the trie. - tr, err := s.updateTrie() - if err != nil || tr == nil { - return - } - // Track the amount of time wasted on hashing the storage trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.db.StorageHashes += time.Since(start) }(time.Now()) - } - s.data.Root = tr.Hash() -} - -// commit obtains a set of dirty storage trie nodes and updates the account data. -// The returned set can be nil if nothing to commit. This function assumes all -// storage mutations have already been flushed into trie by updateRoot. -func (s *stateObject) commit() (*trienode.NodeSet, error) { - // Short circuit if trie is not even loaded, don't bother with committing anything - if s.trie == nil { - s.origin = s.data.Copy() - return nil, nil - } - // Track the amount of time wasted on committing the storage trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.db.StorageCommits += time.Since(start) }(time.Now()) - } - // The trie is currently in an open state and could potentially contain - // cached mutations. Call commit to acquire a set of nodes that have been - // modified, the set can be nil if nothing to commit. - root, nodes, err := s.trie.Commit(false) - if err != nil { - return nil, err - } - s.data.Root = root - - // Update original account data after commit - s.origin = s.data.Copy() - return nodes, nil -} - -// AddBalance adds amount to s's balance. -// It is used to add funds to the destination account of a transfer. -func (s *stateObject) AddBalance(amount *uint256.Int) { - // EIP161: We must check emptiness for the objects such that the account - // clearing (0,0,0 objects) can take effect. - if amount.IsZero() { - if s.empty() { - s.touch() - } - return - } - s.SetBalance(new(uint256.Int).Add(s.Balance(), amount)) -} - -// SubBalance removes amount from s's balance. -// It is used to remove funds from the origin account of a transfer. -func (s *stateObject) SubBalance(amount *uint256.Int) { - if amount.IsZero() { - return - } - s.SetBalance(new(uint256.Int).Sub(s.Balance(), amount)) -} - -func (s *stateObject) SetBalance(amount *uint256.Int) { - s.db.journal.append(balanceChange{ - account: &s.address, - prev: new(uint256.Int).Set(s.data.Balance), - }) - s.setBalance(amount) -} - -// AddBalanceMultiCoin adds amount of coinID to s's balance. -// It is used to add multicoin funds to the destination account of a transfer. -func (s *stateObject) AddBalanceMultiCoin(coinID common.Hash, amount *big.Int, db Database) { - if amount.Sign() == 0 { - if s.empty() { - s.touch() - } - - return - } - s.SetBalanceMultiCoin(coinID, new(big.Int).Add(s.BalanceMultiCoin(coinID, db), amount), db) -} - -// SubBalanceMultiCoin removes amount of coinID from s's balance. -// It is used to remove multicoin funds from the origin account of a transfer. -func (s *stateObject) SubBalanceMultiCoin(coinID common.Hash, amount *big.Int, db Database) { - if amount.Sign() == 0 { - return - } - s.SetBalanceMultiCoin(coinID, new(big.Int).Sub(s.BalanceMultiCoin(coinID, db), amount), db) -} - -func (s *stateObject) SetBalanceMultiCoin(coinID common.Hash, amount *big.Int, db Database) { - s.EnableMultiCoin() - NormalizeCoinID(&coinID) - s.SetState(coinID, common.BigToHash(amount)) -} - -func (s *stateObject) setBalance(amount *uint256.Int) { - s.data.Balance = amount -} - -func (s *stateObject) enableMultiCoin() { - s.data.IsMultiCoin = true -} - -func (s *stateObject) deepCopy(db *StateDB) *stateObject { - obj := &stateObject{ - db: db, - address: s.address, - addrHash: s.addrHash, - origin: s.origin, - data: s.data, - } - if s.trie != nil { - obj.trie = db.db.CopyTrie(s.trie) - } - obj.code = s.code - obj.dirtyStorage = s.dirtyStorage.Copy() - obj.originStorage = s.originStorage.Copy() - obj.pendingStorage = s.pendingStorage.Copy() - obj.selfDestructed = s.selfDestructed - obj.dirtyCode = s.dirtyCode - obj.deleted = s.deleted - return obj -} - -// -// Attribute accessors -// - -// Address returns the address of the contract/account -func (s *stateObject) Address() common.Address { - return s.address -} - -// Code returns the contract code associated with this object, if any. -func (s *stateObject) Code() []byte { - if s.code != nil { - return s.code - } - if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { - return nil - } - code, err := s.db.db.ContractCode(s.address, common.BytesToHash(s.CodeHash())) - if err != nil { - s.db.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) - } - s.code = code - return code -} - -// CodeSize returns the size of the contract code associated with this object, -// or zero if none. This method is an almost mirror of Code, but uses a cache -// inside the database to avoid loading codes seen recently. -func (s *stateObject) CodeSize() int { - if s.code != nil { - return len(s.code) - } - if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { - return 0 - } - size, err := s.db.db.ContractCodeSize(s.address, common.BytesToHash(s.CodeHash())) - if err != nil { - s.db.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) - } - return size -} - -func (s *stateObject) SetCode(codeHash common.Hash, code []byte) { - prevcode := s.Code() - s.db.journal.append(codeChange{ - account: &s.address, - prevhash: s.CodeHash(), - prevcode: prevcode, - }) - s.setCode(codeHash, code) -} - -func (s *stateObject) setCode(codeHash common.Hash, code []byte) { - s.code = code - s.data.CodeHash = codeHash[:] - s.dirtyCode = true -} - -func (s *stateObject) SetNonce(nonce uint64) { - s.db.journal.append(nonceChange{ - account: &s.address, - prev: s.data.Nonce, - }) - s.setNonce(nonce) -} - -func (s *stateObject) setNonce(nonce uint64) { - s.data.Nonce = nonce -} - -func (s *stateObject) CodeHash() []byte { - return s.data.CodeHash -} - -func (s *stateObject) Balance() *uint256.Int { - return s.data.Balance -} - -// NormalizeCoinID ORs the 0th bit of the first byte in -// [coinID], which ensures this bit will be 1 and all other -// bits are left the same. -// This partitions multicoin storage from normal state storage. -func NormalizeCoinID(coinID *common.Hash) { - coinID[0] |= 0x01 -} - -// NormalizeStateKey ANDs the 0th bit of the first byte in -// [key], which ensures this bit will be 0 and all other bits -// are left the same. -// This partitions normal state storage from multicoin storage. -func NormalizeStateKey(key *common.Hash) { - key[0] &= 0xfe -} - -func (s *stateObject) BalanceMultiCoin(coinID common.Hash, db Database) *big.Int { - NormalizeCoinID(&coinID) - return s.GetState(coinID).Big() -} - -func (s *stateObject) EnableMultiCoin() bool { - if s.data.IsMultiCoin { - return false - } - s.db.journal.append(multiCoinEnable{ - account: &s.address, - }) - s.enableMultiCoin() - return true -} - -func (s *stateObject) Nonce() uint64 { - return s.data.Nonce -} - -func (s *stateObject) Root() common.Hash { - return s.data.Root -} diff --git a/core/state/state_object_test.go b/core/state/state_object_test.go index 96132277fe..f5f59acb2f 100644 --- a/core/state/state_object_test.go +++ b/core/state/state_object_test.go @@ -7,7 +7,7 @@ import ( "bytes" "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) func TestStateObjectPartition(t *testing.T) { diff --git a/core/state/state_test.go b/core/state/state_test.go index 3d6dadf209..6bf027ae52 100644 --- a/core/state/state_test.go +++ b/core/state/state_test.go @@ -27,17 +27,12 @@ package state import ( - "bytes" - "encoding/json" "testing" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/holiman/uint256" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" ) type stateEnv struct { @@ -51,103 +46,6 @@ func newStateEnv() *stateEnv { return &stateEnv{db: db, state: sdb} } -func TestDump(t *testing.T) { - db := rawdb.NewMemoryDatabase() - tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) - sdb, _ := New(types.EmptyRootHash, tdb, nil) - s := &stateEnv{db: db, state: sdb} - - // generate a few entries - obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) - obj1.AddBalance(uint256.NewInt(22)) - obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) - obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) - obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) - obj3.SetBalance(uint256.NewInt(44)) - - // write some of them to the trie - s.state.updateStateObject(obj1) - s.state.updateStateObject(obj2) - root, _ := s.state.Commit(0, false) - - // check that DumpToCollector contains the state objects that are in trie - s.state, _ = New(root, tdb, nil) - got := string(s.state.Dump(nil)) - want := `{ - "root": "1d75ab73e172edb7c3b3c0fd004d9896992fb96b617f6f954641d7618159e5e4", - "accounts": { - "0x0000000000000000000000000000000000000001": { - "balance": "22", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "isMultiCoin": false, - "address": "0x0000000000000000000000000000000000000001", - "key": "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d" - }, - "0x0000000000000000000000000000000000000002": { - "balance": "44", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "isMultiCoin": false, - "address": "0x0000000000000000000000000000000000000002", - "key": "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62" - }, - "0x0000000000000000000000000000000000000102": { - "balance": "0", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3", - "code": "0x03030303030303", - "isMultiCoin": false, - "address": "0x0000000000000000000000000000000000000102", - "key": "0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1" - } - } -}` - if got != want { - t.Errorf("DumpToCollector mismatch:\ngot: %s\nwant: %s\n", got, want) - } -} - -func TestIterativeDump(t *testing.T) { - db := rawdb.NewMemoryDatabase() - tdb := NewDatabaseWithConfig(db, &triedb.Config{Preimages: true}) - sdb, _ := New(types.EmptyRootHash, tdb, nil) - s := &stateEnv{db: db, state: sdb} - - // generate a few entries - obj1 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01})) - obj1.AddBalance(uint256.NewInt(22)) - obj2 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x01, 0x02})) - obj2.SetCode(crypto.Keccak256Hash([]byte{3, 3, 3, 3, 3, 3, 3}), []byte{3, 3, 3, 3, 3, 3, 3}) - obj3 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x02})) - obj3.SetBalance(uint256.NewInt(44)) - obj4 := s.state.getOrNewStateObject(common.BytesToAddress([]byte{0x00})) - obj4.AddBalance(uint256.NewInt(1337)) - - // write some of them to the trie - s.state.updateStateObject(obj1) - s.state.updateStateObject(obj2) - root, _ := s.state.Commit(0, false) - s.state, _ = New(root, tdb, nil) - - b := &bytes.Buffer{} - s.state.IterativeDump(nil, json.NewEncoder(b)) - // check that DumpToCollector contains the state objects that are in trie - got := b.String() - want := `{"root":"0x0ffca661efa3b7504ac015083994c94fd7d0d24db60354c717c936afcced762a"} -{"balance":"22","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","isMultiCoin":false,"address":"0x0000000000000000000000000000000000000001","key":"0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d"} -{"balance":"1337","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","isMultiCoin":false,"address":"0x0000000000000000000000000000000000000000","key":"0x5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"} -{"balance":"0","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0x87874902497a5bb968da31a2998d8f22e949d1ef6214bcdedd8bae24cca4b9e3","code":"0x03030303030303","isMultiCoin":false,"address":"0x0000000000000000000000000000000000000102","key":"0xa17eacbc25cda025e81db9c5c62868822c73ce097cee2a63e33a2e41268358a1"} -{"balance":"44","nonce":0,"root":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","isMultiCoin":false,"address":"0x0000000000000000000000000000000000000002","key":"0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62"} -` - if got != want { - t.Errorf("DumpToCollector mismatch:\ngot: %s\nwant: %s\n", got, want) - } -} - func TestNull(t *testing.T) { s := newStateEnv() address := common.HexToAddress("0x823140710bf13990e4500136726d8b55") @@ -205,107 +103,3 @@ func TestSnapshotEmpty(t *testing.T) { s := newStateEnv() s.state.RevertToSnapshot(s.state.Snapshot()) } - -func TestSnapshot2(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - - stateobjaddr0 := common.BytesToAddress([]byte("so0")) - stateobjaddr1 := common.BytesToAddress([]byte("so1")) - var storageaddr common.Hash - - data0 := common.BytesToHash([]byte{17}) - data1 := common.BytesToHash([]byte{18}) - - state.SetState(stateobjaddr0, storageaddr, data0) - state.SetState(stateobjaddr1, storageaddr, data1) - - // db, trie are already non-empty values - so0 := state.getStateObject(stateobjaddr0) - so0.SetBalance(uint256.NewInt(42)) - so0.SetNonce(43) - so0.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e'}), []byte{'c', 'a', 'f', 'e'}) - so0.selfDestructed = false - so0.deleted = false - state.setStateObject(so0) - - root, _ := state.Commit(0, false) - state, _ = New(root, state.db, nil) - - // and one with deleted == true - so1 := state.getStateObject(stateobjaddr1) - so1.SetBalance(uint256.NewInt(52)) - so1.SetNonce(53) - so1.SetCode(crypto.Keccak256Hash([]byte{'c', 'a', 'f', 'e', '2'}), []byte{'c', 'a', 'f', 'e', '2'}) - so1.selfDestructed = true - so1.deleted = true - state.setStateObject(so1) - - so1 = state.getStateObject(stateobjaddr1) - if so1 != nil { - t.Fatalf("deleted object not nil when getting") - } - - snapshot := state.Snapshot() - state.RevertToSnapshot(snapshot) - - so0Restored := state.getStateObject(stateobjaddr0) - // Update lazily-loaded values before comparing. - so0Restored.GetState(storageaddr) - so0Restored.Code() - // non-deleted is equal (restored) - compareStateObjects(so0Restored, so0, t) - - // deleted should be nil, both before and after restore of state copy - so1Restored := state.getStateObject(stateobjaddr1) - if so1Restored != nil { - t.Fatalf("deleted object not nil after restoring snapshot: %+v", so1Restored) - } -} - -func compareStateObjects(so0, so1 *stateObject, t *testing.T) { - if so0.Address() != so1.Address() { - t.Fatalf("Address mismatch: have %v, want %v", so0.address, so1.address) - } - if so0.Balance().Cmp(so1.Balance()) != 0 { - t.Fatalf("Balance mismatch: have %v, want %v", so0.Balance(), so1.Balance()) - } - if so0.Nonce() != so1.Nonce() { - t.Fatalf("Nonce mismatch: have %v, want %v", so0.Nonce(), so1.Nonce()) - } - if so0.data.Root != so1.data.Root { - t.Errorf("Root mismatch: have %x, want %x", so0.data.Root[:], so1.data.Root[:]) - } - if !bytes.Equal(so0.CodeHash(), so1.CodeHash()) { - t.Fatalf("CodeHash mismatch: have %v, want %v", so0.CodeHash(), so1.CodeHash()) - } - if !bytes.Equal(so0.code, so1.code) { - t.Fatalf("Code mismatch: have %v, want %v", so0.code, so1.code) - } - - if len(so1.dirtyStorage) != len(so0.dirtyStorage) { - t.Errorf("Dirty storage size mismatch: have %d, want %d", len(so1.dirtyStorage), len(so0.dirtyStorage)) - } - for k, v := range so1.dirtyStorage { - if so0.dirtyStorage[k] != v { - t.Errorf("Dirty storage key %x mismatch: have %v, want %v", k, so0.dirtyStorage[k], v) - } - } - for k, v := range so0.dirtyStorage { - if so1.dirtyStorage[k] != v { - t.Errorf("Dirty storage key %x mismatch: have %v, want none.", k, v) - } - } - if len(so1.originStorage) != len(so0.originStorage) { - t.Errorf("Origin storage size mismatch: have %d, want %d", len(so1.originStorage), len(so0.originStorage)) - } - for k, v := range so1.originStorage { - if so0.originStorage[k] != v { - t.Errorf("Origin storage key %x mismatch: have %v, want %v", k, so0.originStorage[k], v) - } - } - for k, v := range so0.originStorage { - if so1.originStorage[k] != v { - t.Errorf("Origin storage key %x mismatch: have %v, want none.", k, v) - } - } -} diff --git a/core/state/statedb.go b/core/state/statedb.go index 850859bbdc..cfde4a80a5 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -28,39 +28,15 @@ package state import ( - "fmt" - "maps" "math/big" - "sort" - "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/predicate" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/utils" - "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + ethstate "github.com/ava-labs/libevm/core/state" "github.com/holiman/uint256" ) -const ( - // storageDeleteLimit denotes the highest permissible memory allocation - // employed for contract storage deletion. - storageDeleteLimit = 512 * 1024 * 1024 -) - -type revision struct { - id int - journalIndex int -} - // StateDB structs within the ethereum protocol are used to store anything // within the merkle trie. StateDBs take care of caching and storing // nested states. It's the general query interface to retrieve: @@ -73,134 +49,28 @@ type revision struct { // must be created with new root and updated database for accessing post- // commit states. type StateDB struct { - db Database - prefetcher *triePrefetcher - trie Trie - hasher crypto.KeccakState - snap snapshot.Snapshot // Nil if snapshot is not available - - // originalRoot is the pre-state root, before any changes were made. - // It will be updated when the Commit is called. - originalRoot common.Hash + *ethstate.StateDB - // These maps hold the state changes (including the corresponding - // original value) that occurred in this **block**. - accounts map[common.Hash][]byte // The mutated accounts in 'slim RLP' encoding - storages map[common.Hash]map[common.Hash][]byte // The mutated slots in prefix-zero trimmed rlp format - accountsOrigin map[common.Address][]byte // The original value of mutated accounts in 'slim RLP' encoding - storagesOrigin map[common.Address]map[common.Hash][]byte // The original value of mutated slots in prefix-zero trimmed rlp format - - // This map holds 'live' objects, which will get modified while processing - // a state transition. - stateObjects map[common.Address]*stateObject - stateObjectsPending map[common.Address]struct{} // State objects finalized but not yet written to the trie - stateObjectsDirty map[common.Address]struct{} // State objects modified in the current execution - stateObjectsDestruct map[common.Address]*types.StateAccount // State objects destructed in the block along with its previous value - - // DB error. - // State objects are used by the consensus core and VM which are - // unable to deal with database-level errors. Any error that occurs - // during a database read is memoized here and will eventually be - // returned by StateDB.Commit. Notably, this error is also shared - // by all cached state objects in case the database failure occurs - // when accessing state of accounts. - dbErr error - - // The refund counter, also used by state transitioning. - refund uint64 - - // The tx context and all occurred logs in the scope of transaction. + // The tx context thash common.Hash txIndex int - logs map[common.Hash][]*types.Log - logSize uint - - // Preimages occurred seen by VM in the scope of block. - preimages map[common.Hash][]byte - // Per-transaction access list - accessList *accessList - // Ordered storage slots to be used in predicate verification as set in the tx access list. - // Only set in PrepareAccessList, and un-modified through execution. - predicateStorageSlots map[common.Address][][]byte - - // Transient storage - transientStorage transientStorage - - // Journal of state modifications. This is the backbone of - // Snapshot and RevertToSnapshot. - journal *journal - validRevisions []revision - nextRevisionId int - - // Measurements gathered during execution for debugging purposes - AccountReads time.Duration - AccountHashes time.Duration - AccountUpdates time.Duration - AccountCommits time.Duration - StorageReads time.Duration - StorageHashes time.Duration - StorageUpdates time.Duration - StorageCommits time.Duration - SnapshotAccountReads time.Duration - SnapshotStorageReads time.Duration - SnapshotCommits time.Duration - TrieDBCommits time.Duration - - AccountUpdated int - StorageUpdated int - AccountDeleted int - StorageDeleted int - - // Testing hooks - onCommit func(states *triestate.Set) // Hook invoked when commit is performed + // Some fields remembered as they are used in tests + db Database + snaps ethstate.SnapshotTree } // New creates a new state from a given trie. -func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error) { - var snap snapshot.Snapshot - if snaps != nil { - snap = snaps.Snapshot(root) - } - return NewWithSnapshot(root, db, snap) -} - -// NewWithSnapshot creates a new state from a given trie with the specified [snap] -// If [snap] doesn't have the same root as [root], then NewWithSnapshot will return -// an error. If snap is nil, then no snapshot will be used and CommitWithSnapshot -// cannot be called on the returned StateDB. -func NewWithSnapshot(root common.Hash, db Database, snap snapshot.Snapshot) (*StateDB, error) { - tr, err := db.OpenTrie(root) +func New(root common.Hash, db Database, snaps ethstate.SnapshotTree) (*StateDB, error) { + stateDB, err := ethstate.New(root, db, snaps) if err != nil { return nil, err } - sdb := &StateDB{ - db: db, - trie: tr, - originalRoot: root, - accounts: make(map[common.Hash][]byte), - storages: make(map[common.Hash]map[common.Hash][]byte), - accountsOrigin: make(map[common.Address][]byte), - storagesOrigin: make(map[common.Address]map[common.Hash][]byte), - stateObjects: make(map[common.Address]*stateObject), - stateObjectsPending: make(map[common.Address]struct{}), - stateObjectsDirty: make(map[common.Address]struct{}), - stateObjectsDestruct: make(map[common.Address]*types.StateAccount), - logs: make(map[common.Hash][]*types.Log), - preimages: make(map[common.Hash][]byte), - journal: newJournal(), - predicateStorageSlots: make(map[common.Address][][]byte), - accessList: newAccessList(), - transientStorage: newTransientStorage(), - hasher: crypto.NewKeccakState(), - } - if snap != nil { - if snap.Root() != root { - return nil, fmt.Errorf("cannot create new statedb for root: %s, using snapshot with mismatched root: %s", root, snap.Root().Hex()) - } - sdb.snap = snap - } - return sdb, nil + return &StateDB{ + StateDB: stateDB, + db: db, + snaps: snaps, + }, nil } type workerPool struct { @@ -209,841 +79,62 @@ type workerPool struct { func (wp *workerPool) Done() { // Done is guaranteed to only be called after all work is already complete, - // so Wait()ing is redundant, but it also releases resources. + // so we call Wait for goroutines to finish before returning. wp.BoundedWorkers.Wait() } -func WithConcurrentWorkers(prefetchers int) PrefetcherOption { +func WithConcurrentWorkers(prefetchers int) ethstate.PrefetcherOption { pool := &workerPool{ BoundedWorkers: utils.NewBoundedWorkers(prefetchers), } - return WithWorkerPools(func() WorkerPool { return pool }) -} - -// StartPrefetcher initializes a new trie prefetcher to pull in nodes from the -// state trie concurrently while the state is mutated so that when we reach the -// commit phase, most of the needed data is already hot. -func (s *StateDB) StartPrefetcher(namespace string, opts ...PrefetcherOption) { - if s.prefetcher != nil { - s.prefetcher.close() - s.prefetcher = nil - } - if s.snap != nil { - s.prefetcher = newTriePrefetcher(s.db, s.originalRoot, namespace, opts...) - } -} - -// StopPrefetcher terminates a running prefetcher and reports any leftover stats -// from the gathered metrics. -func (s *StateDB) StopPrefetcher() { - if s.prefetcher != nil { - s.prefetcher.close() - s.prefetcher = nil - } -} - -// setError remembers the first non-nil error it is called with. -func (s *StateDB) setError(err error) { - if s.dbErr == nil { - s.dbErr = err - } -} - -// Error returns the memorized database failure occurred earlier. -func (s *StateDB) Error() error { - return s.dbErr -} - -// AddLog adds a log with the specified parameters to the statedb -// Note: blockNumber is a required argument because StateDB does not -// know the current block number. -func (s *StateDB) AddLog(addr common.Address, topics []common.Hash, data []byte, blockNumber uint64) { - log := &types.Log{ - Address: addr, - Topics: topics, - Data: data, - BlockNumber: blockNumber, - } - s.journal.append(addLogChange{txhash: s.thash}) - - log.TxHash = s.thash - log.TxIndex = uint(s.txIndex) - log.Index = s.logSize - s.logs[s.thash] = append(s.logs[s.thash], log) - s.logSize++ -} - -// GetLogs returns the logs matching the specified transaction hash, and annotates -// them with the given blockNumber and blockHash. -func (s *StateDB) GetLogs(hash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log { - logs := s.logs[hash] - for _, l := range logs { - l.BlockNumber = blockNumber - l.BlockHash = blockHash - } - return logs -} - -func (s *StateDB) Logs() []*types.Log { - var logs []*types.Log - for _, lgs := range s.logs { - logs = append(logs, lgs...) - } - return logs -} - -// GetLogData returns the underlying topics and data from each log included in the StateDB -// Test helper function. -func (s *StateDB) GetLogData() ([][]common.Hash, [][]byte) { - var logData [][]byte - var topics [][]common.Hash - for _, lgs := range s.logs { - for _, log := range lgs { - topics = append(topics, log.Topics) - logData = append(logData, common.CopyBytes(log.Data)) - } - } - return topics, logData -} - -// AddPreimage records a SHA3 preimage seen by the VM. -func (s *StateDB) AddPreimage(hash common.Hash, preimage []byte) { - if _, ok := s.preimages[hash]; !ok { - s.journal.append(addPreimageChange{hash: hash}) - pi := make([]byte, len(preimage)) - copy(pi, preimage) - s.preimages[hash] = pi - } -} - -// Preimages returns a list of SHA3 preimages that have been submitted. -func (s *StateDB) Preimages() map[common.Hash][]byte { - return s.preimages -} - -// AddRefund adds gas to the refund counter -func (s *StateDB) AddRefund(gas uint64) { - s.journal.append(refundChange{prev: s.refund}) - s.refund += gas -} - -// SubRefund removes gas from the refund counter. -// This method will set the refund counter to 0 if the gas is greater than the current refund. -func (s *StateDB) SubRefund(gas uint64) { - s.journal.append(refundChange{prev: s.refund}) - if gas > s.refund { - log.Warn("Setting refund to 0", "currentRefund", s.refund, "gas", gas) - s.refund = 0 - return - } - s.refund -= gas -} - -// Exist reports whether the given account address exists in the state. -// Notably this also returns true for self-destructed accounts. -func (s *StateDB) Exist(addr common.Address) bool { - return s.getStateObject(addr) != nil -} - -// Empty returns whether the state object is either non-existent -// or empty according to the EIP161 specification (balance = nonce = code = 0) -func (s *StateDB) Empty(addr common.Address) bool { - so := s.getStateObject(addr) - return so == nil || so.empty() -} - -// GetBalance retrieves the balance from the given address or 0 if object not found -func (s *StateDB) GetBalance(addr common.Address) *uint256.Int { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.Balance() - } - return common.U2560 + return ethstate.WithWorkerPools(func() ethstate.WorkerPool { return pool }) } // Retrieve the balance from the given address or 0 if object not found func (s *StateDB) GetBalanceMultiCoin(addr common.Address, coinID common.Hash) *big.Int { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.BalanceMultiCoin(coinID, s.db) - } - return new(big.Int).Set(common.Big0) -} - -// GetNonce retrieves the nonce from the given address or 0 if object not found -func (s *StateDB) GetNonce(addr common.Address) uint64 { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.Nonce() - } - - return 0 -} - -// GetStorageRoot retrieves the storage root from the given address or empty -// if object not found. -func (s *StateDB) GetStorageRoot(addr common.Address) common.Hash { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.Root() - } - return common.Hash{} -} - -// TxIndex returns the current transaction index set by Prepare. -func (s *StateDB) TxIndex() int { - return s.txIndex -} - -func (s *StateDB) GetCode(addr common.Address) []byte { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.Code() - } - return nil -} - -func (s *StateDB) GetCodeSize(addr common.Address) int { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.CodeSize() - } - return 0 -} - -func (s *StateDB) GetCodeHash(addr common.Address) common.Hash { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return common.BytesToHash(stateObject.CodeHash()) - } - return common.Hash{} + NormalizeCoinID(&coinID) + return s.StateDB.GetState(addr, coinID).Big() } // GetState retrieves a value from the given account's storage trie. func (s *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash { - stateObject := s.getStateObject(addr) - if stateObject != nil { - NormalizeStateKey(&hash) - return stateObject.GetState(hash) - } - return common.Hash{} -} - -// GetCommittedState retrieves a value from the given account's committed storage trie. -func (s *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.GetCommittedState(hash) - } - return common.Hash{} -} - -// GetCommittedStateAP1 retrieves a value from the given account's committed storage trie. -func (s *StateDB) GetCommittedStateAP1(addr common.Address, hash common.Hash) common.Hash { - stateObject := s.getStateObject(addr) - if stateObject != nil { - NormalizeStateKey(&hash) - return stateObject.GetCommittedState(hash) - } - return common.Hash{} -} - -// Database retrieves the low level database supporting the lower level trie ops. -func (s *StateDB) Database() Database { - return s.db -} - -func (s *StateDB) HasSelfDestructed(addr common.Address) bool { - stateObject := s.getStateObject(addr) - if stateObject != nil { - return stateObject.selfDestructed - } - return false -} - -/* - * SETTERS - */ - -// AddBalance adds amount to the account associated with addr. -func (s *StateDB) AddBalance(addr common.Address, amount *uint256.Int) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.AddBalance(amount) - } -} - -// SubBalance subtracts amount from the account associated with addr. -func (s *StateDB) SubBalance(addr common.Address, amount *uint256.Int) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.SubBalance(amount) - } -} - -func (s *StateDB) SetBalance(addr common.Address, amount *uint256.Int) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.SetBalance(amount) - } + NormalizeStateKey(&hash) + return s.StateDB.GetState(addr, hash) } // AddBalance adds amount to the account associated with addr. func (s *StateDB) AddBalanceMultiCoin(addr common.Address, coinID common.Hash, amount *big.Int) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.AddBalanceMultiCoin(coinID, amount, s.db) - } -} - -// SubBalance subtracts amount from the account associated with addr. -func (s *StateDB) SubBalanceMultiCoin(addr common.Address, coinID common.Hash, amount *big.Int) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.SubBalanceMultiCoin(coinID, amount, s.db) - } -} - -func (s *StateDB) SetBalanceMultiCoin(addr common.Address, coinID common.Hash, amount *big.Int) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.SetBalanceMultiCoin(coinID, amount, s.db) - } -} - -func (s *StateDB) SetNonce(addr common.Address, nonce uint64) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.SetNonce(nonce) - } -} - -func (s *StateDB) SetCode(addr common.Address, code []byte) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - stateObject.SetCode(crypto.Keccak256Hash(code), code) - } -} - -func (s *StateDB) SetState(addr common.Address, key, value common.Hash) { - stateObject := s.getOrNewStateObject(addr) - if stateObject != nil { - NormalizeStateKey(&key) - stateObject.SetState(key, value) - } -} - -// SetStorage replaces the entire storage for the specified account with given -// storage. This function should only be used for debugging and the mutations -// must be discarded afterwards. -func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common.Hash) { - // SetStorage needs to wipe existing storage. We achieve this by pretending - // that the account self-destructed earlier in this block, by flagging - // it in stateObjectsDestruct. The effect of doing so is that storage lookups - // will not hit disk, since it is assumed that the disk-data is belonging - // to a previous incarnation of the object. - // - // TODO(rjl493456442) this function should only be supported by 'unwritable' - // state and all mutations made should all be discarded afterwards. - if _, ok := s.stateObjectsDestruct[addr]; !ok { - s.stateObjectsDestruct[addr] = nil - } - stateObject := s.getOrNewStateObject(addr) - for k, v := range storage { - stateObject.SetState(k, v) - } -} - -// SelfDestruct marks the given account as selfdestructed. -// This clears the account balance. -// -// The account's state object is still available until the state is committed, -// getStateObject will return a non-nil account after SelfDestruct. -func (s *StateDB) SelfDestruct(addr common.Address) { - stateObject := s.getStateObject(addr) - if stateObject == nil { - return - } - s.journal.append(selfDestructChange{ - account: &addr, - prev: stateObject.selfDestructed, - prevbalance: new(uint256.Int).Set(stateObject.Balance()), - }) - stateObject.markSelfdestructed() - stateObject.data.Balance = new(uint256.Int) -} - -func (s *StateDB) Selfdestruct6780(addr common.Address) { - stateObject := s.getStateObject(addr) - if stateObject == nil { + if amount.Sign() == 0 { + s.AddBalance(addr, new(uint256.Int)) // used to cause touch return } - - if stateObject.created { - s.SelfDestruct(addr) + if !ethstate.GetExtra(s.StateDB, customtypes.IsMultiCoinPayloads, addr) { + ethstate.SetExtra(s.StateDB, customtypes.IsMultiCoinPayloads, addr, true) } + newAmount := new(big.Int).Add(s.GetBalanceMultiCoin(addr, coinID), amount) + NormalizeCoinID(&coinID) + s.StateDB.SetState(addr, coinID, common.BigToHash(newAmount)) } -// SetTransientState sets transient storage for a given account. It -// adds the change to the journal so that it can be rolled back -// to its previous value if there is a revert. -func (s *StateDB) SetTransientState(addr common.Address, key, value common.Hash) { - prev := s.GetTransientState(addr, key) - if prev == value { +// SubBalance subtracts amount from the account associated with addr. +func (s *StateDB) SubBalanceMultiCoin(addr common.Address, coinID common.Hash, amount *big.Int) { + if amount.Sign() == 0 { return } - s.journal.append(transientStorageChange{ - account: &addr, - key: key, - prevalue: prev, - }) - s.setTransientState(addr, key, value) -} - -// setTransientState is a lower level setter for transient storage. It -// is called during a revert to prevent modifications to the journal. -func (s *StateDB) setTransientState(addr common.Address, key, value common.Hash) { - s.transientStorage.Set(addr, key, value) -} - -// GetTransientState gets transient storage for a given account. -func (s *StateDB) GetTransientState(addr common.Address, key common.Hash) common.Hash { - return s.transientStorage.Get(addr, key) -} - -// -// Setting, updating & deleting state object methods. -// - -// updateStateObject writes the given object to the trie. -func (s *StateDB) updateStateObject(obj *stateObject) { - // Track the amount of time wasted on updating the account from the trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) - } - // Encode the account and update the account trie - addr := obj.Address() - if err := s.trie.UpdateAccount(addr, &obj.data); err != nil { - s.setError(fmt.Errorf("updateStateObject (%x) error: %v", addr[:], err)) - } - if obj.dirtyCode { - s.trie.UpdateContractCode(obj.Address(), common.BytesToHash(obj.CodeHash()), obj.code) - } - // Cache the data until commit. Note, this update mechanism is not symmetric - // to the deletion, because whereas it is enough to track account updates - // at commit time, deletions need tracking at transaction boundary level to - // ensure we capture state clearing. - s.accounts[obj.addrHash] = types.SlimAccountRLP(obj.data) - - // Track the original value of mutated account, nil means it was not present. - // Skip if it has been tracked (because updateStateObject may be called - // multiple times in a block). - if _, ok := s.accountsOrigin[obj.address]; !ok { - if obj.origin == nil { - s.accountsOrigin[obj.address] = nil - } else { - s.accountsOrigin[obj.address] = types.SlimAccountRLP(*obj.origin) - } + // Note: It's not needed to set the IsMultiCoin (extras) flag here, as this + // call would always be preceded by a call to AddBalanceMultiCoin, which would + // set the extra flag. Seems we should remove the redundant code. + if !ethstate.GetExtra(s.StateDB, customtypes.IsMultiCoinPayloads, addr) { + ethstate.SetExtra(s.StateDB, customtypes.IsMultiCoinPayloads, addr, true) } + newAmount := new(big.Int).Sub(s.GetBalanceMultiCoin(addr, coinID), amount) + NormalizeCoinID(&coinID) + s.StateDB.SetState(addr, coinID, common.BigToHash(newAmount)) } -// deleteStateObject removes the given object from the state trie. -func (s *StateDB) deleteStateObject(obj *stateObject) { - // Track the amount of time wasted on deleting the account from the trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.AccountUpdates += time.Since(start) }(time.Now()) - } - // Delete the account from the trie - addr := obj.Address() - if err := s.trie.DeleteAccount(addr); err != nil { - s.setError(fmt.Errorf("deleteStateObject (%x) error: %v", addr[:], err)) - } -} - -// getStateObject retrieves a state object given by the address, returning nil if -// the object is not found or was deleted in this execution context. If you need -// to differentiate between non-existent/just-deleted, use getDeletedStateObject. -func (s *StateDB) getStateObject(addr common.Address) *stateObject { - if obj := s.getDeletedStateObject(addr); obj != nil && !obj.deleted { - return obj - } - return nil -} - -// getDeletedStateObject is similar to getStateObject, but instead of returning -// nil for a deleted state object, it returns the actual object with the deleted -// flag set. This is needed by the state journal to revert to the correct s- -// destructed object instead of wiping all knowledge about the state object. -func (s *StateDB) getDeletedStateObject(addr common.Address) *stateObject { - // Prefer live objects if any is available - if obj := s.stateObjects[addr]; obj != nil { - return obj - } - // If no live objects are available, attempt to use snapshots - var data *types.StateAccount - if s.snap != nil { - start := time.Now() - acc, err := s.snap.Account(crypto.HashData(s.hasher, addr.Bytes())) - if metrics.EnabledExpensive { - s.SnapshotAccountReads += time.Since(start) - } - if err == nil { - if acc == nil { - return nil - } - data = &types.StateAccount{ - Nonce: acc.Nonce, - Balance: acc.Balance, - CodeHash: acc.CodeHash, - IsMultiCoin: acc.IsMultiCoin, - Root: common.BytesToHash(acc.Root), - } - if len(data.CodeHash) == 0 { - data.CodeHash = types.EmptyCodeHash.Bytes() - } - if data.Root == (common.Hash{}) { - data.Root = types.EmptyRootHash - } - } - } - // If snapshot unavailable or reading from it failed, load from the database - if data == nil { - start := time.Now() - var err error - data, err = s.trie.GetAccount(addr) - if metrics.EnabledExpensive { - s.AccountReads += time.Since(start) - } - if err != nil { - s.setError(fmt.Errorf("getDeleteStateObject (%x) error: %w", addr.Bytes(), err)) - return nil - } - if data == nil { - return nil - } - } - // Insert into the live set - obj := newObject(s, addr, data) - s.setStateObject(obj) - return obj -} - -func (s *StateDB) setStateObject(object *stateObject) { - s.stateObjects[object.Address()] = object -} - -// getOrNewStateObject retrieves a state object or create a new state object if nil. -func (s *StateDB) getOrNewStateObject(addr common.Address) *stateObject { - stateObject := s.getStateObject(addr) - if stateObject == nil { - stateObject, _ = s.createObject(addr) - } - return stateObject -} - -// createObject creates a new state object. If there is an existing account with -// the given address, it is overwritten and returned as the second return value. -func (s *StateDB) createObject(addr common.Address) (newobj, prev *stateObject) { - prev = s.getDeletedStateObject(addr) // Note, prev might have been deleted, we need that! - newobj = newObject(s, addr, nil) - if prev == nil { - s.journal.append(createObjectChange{account: &addr}) - } else { - // The original account should be marked as destructed and all cached - // account and storage data should be cleared as well. Note, it must - // be done here, otherwise the destruction event of "original account" - // will be lost. - _, prevdestruct := s.stateObjectsDestruct[prev.address] - if !prevdestruct { - s.stateObjectsDestruct[prev.address] = prev.origin - } - // There may be some cached account/storage data already since IntermediateRoot - // will be called for each transaction before byzantium fork which will always - // cache the latest account/storage data. - prevAccount, ok := s.accountsOrigin[prev.address] - s.journal.append(resetObjectChange{ - account: &addr, - prev: prev, - prevdestruct: prevdestruct, - prevAccount: s.accounts[prev.addrHash], - prevStorage: s.storages[prev.addrHash], - prevAccountOriginExist: ok, - prevAccountOrigin: prevAccount, - prevStorageOrigin: s.storagesOrigin[prev.address], - }) - delete(s.accounts, prev.addrHash) - delete(s.storages, prev.addrHash) - delete(s.accountsOrigin, prev.address) - delete(s.storagesOrigin, prev.address) - } - s.setStateObject(newobj) - if prev != nil && !prev.deleted { - return newobj, prev - } - return newobj, nil -} - -// CreateAccount explicitly creates a state object. If a state object with the address -// already exists the balance is carried over to the new account. -// -// CreateAccount is called during the EVM CREATE operation. The situation might arise that -// a contract does the following: -// -// 1. sends funds to sha(account ++ (nonce + 1)) -// 2. tx_create(sha(account ++ nonce)) (note that this gets the address of 1) -// -// Carrying over the balance ensures that Ether doesn't disappear. -func (s *StateDB) CreateAccount(addr common.Address) { - newObj, prev := s.createObject(addr) - if prev != nil { - newObj.setBalance(prev.data.Balance) - } -} - -// copyPredicateStorageSlots creates a deep copy of the provided predicateStorageSlots map. -func copyPredicateStorageSlots(predicateStorageSlots map[common.Address][][]byte) map[common.Address][][]byte { - res := make(map[common.Address][][]byte, len(predicateStorageSlots)) - for address, predicates := range predicateStorageSlots { - copiedPredicates := make([][]byte, len(predicates)) - for i, predicateBytes := range predicates { - copiedPredicates[i] = common.CopyBytes(predicateBytes) - } - res[address] = copiedPredicates - } - return res -} - -// Copy creates a deep, independent copy of the state. -// Snapshots of the copied state cannot be applied to the copy. -func (s *StateDB) Copy() *StateDB { - // Copy all the basic fields, initialize the memory ones - state := &StateDB{ - db: s.db, - trie: s.db.CopyTrie(s.trie), - originalRoot: s.originalRoot, - accounts: copySet(s.accounts), - storages: copy2DSet(s.storages), - accountsOrigin: copySet(s.accountsOrigin), - storagesOrigin: copy2DSet(s.storagesOrigin), - stateObjects: make(map[common.Address]*stateObject, len(s.journal.dirties)), - stateObjectsPending: make(map[common.Address]struct{}, len(s.stateObjectsPending)), - stateObjectsDirty: make(map[common.Address]struct{}, len(s.journal.dirties)), - stateObjectsDestruct: maps.Clone(s.stateObjectsDestruct), - refund: s.refund, - logs: make(map[common.Hash][]*types.Log, len(s.logs)), - logSize: s.logSize, - preimages: maps.Clone(s.preimages), - journal: newJournal(), - hasher: crypto.NewKeccakState(), - - // In order for the block producer to be able to use and make additions - // to the snapshot tree, we need to copy that as well. Otherwise, any - // block mined by ourselves will cause gaps in the tree, and force the - // miner to operate trie-backed only. - snap: s.snap, - } - // Copy the dirty states, logs, and preimages - for addr := range s.journal.dirties { - // As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527), - // and in the Finalise-method, there is a case where an object is in the journal but not - // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for - // nil - if object, exist := s.stateObjects[addr]; exist { - // Even though the original object is dirty, we are not copying the journal, - // so we need to make sure that any side-effect the journal would have caused - // during a commit (or similar op) is already applied to the copy. - state.stateObjects[addr] = object.deepCopy(state) - - state.stateObjectsDirty[addr] = struct{}{} // Mark the copy dirty to force internal (code/state) commits - state.stateObjectsPending[addr] = struct{}{} // Mark the copy pending to force external (account) commits - } - } - // Above, we don't copy the actual journal. This means that if the copy - // is copied, the loop above will be a no-op, since the copy's journal - // is empty. Thus, here we iterate over stateObjects, to enable copies - // of copies. - for addr := range s.stateObjectsPending { - if _, exist := state.stateObjects[addr]; !exist { - state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state) - } - state.stateObjectsPending[addr] = struct{}{} - } - for addr := range s.stateObjectsDirty { - if _, exist := state.stateObjects[addr]; !exist { - state.stateObjects[addr] = s.stateObjects[addr].deepCopy(state) - } - state.stateObjectsDirty[addr] = struct{}{} - } - - // Deep copy the logs occurred in the scope of block - for hash, logs := range s.logs { - cpy := make([]*types.Log, len(logs)) - for i, l := range logs { - cpy[i] = new(types.Log) - *cpy[i] = *l - } - state.logs[hash] = cpy - } - // Do we need to copy the access list and transient storage? - // In practice: No. At the start of a transaction, these two lists are empty. - // In practice, we only ever copy state _between_ transactions/blocks, never - // in the middle of a transaction. However, it doesn't cost us much to copy - // empty lists, so we do it anyway to not blow up if we ever decide copy them - // in the middle of a transaction. - state.accessList = s.accessList.Copy() - state.transientStorage = s.transientStorage.Copy() - state.predicateStorageSlots = copyPredicateStorageSlots(s.predicateStorageSlots) - - // If there's a prefetcher running, make an inactive copy of it that can - // only access data but does not actively preload (since the user will not - // know that they need to explicitly terminate an active copy). - if s.prefetcher != nil { - state.prefetcher = s.prefetcher.copy() - } - return state -} - -// Snapshot returns an identifier for the current revision of the state. -func (s *StateDB) Snapshot() int { - id := s.nextRevisionId - s.nextRevisionId++ - s.validRevisions = append(s.validRevisions, revision{id, s.journal.length()}) - return id -} - -// RevertToSnapshot reverts all state changes made since the given revision. -func (s *StateDB) RevertToSnapshot(revid int) { - // Find the snapshot in the stack of valid snapshots. - idx := sort.Search(len(s.validRevisions), func(i int) bool { - return s.validRevisions[i].id >= revid - }) - if idx == len(s.validRevisions) || s.validRevisions[idx].id != revid { - panic(fmt.Errorf("revision id %v cannot be reverted", revid)) - } - snapshot := s.validRevisions[idx].journalIndex - - // Replay the journal to undo changes and remove invalidated snapshots - s.journal.revert(s, snapshot) - s.validRevisions = s.validRevisions[:idx] -} - -// GetRefund returns the current value of the refund counter. -func (s *StateDB) GetRefund() uint64 { - return s.refund -} - -// Finalise finalises the state by removing the destructed objects and clears -// the journal as well as the refunds. Finalise, however, will not push any updates -// into the tries just yet. Only IntermediateRoot or Commit will do that. -func (s *StateDB) Finalise(deleteEmptyObjects bool) { - addressesToPrefetch := make([][]byte, 0, len(s.journal.dirties)) - for addr := range s.journal.dirties { - obj, exist := s.stateObjects[addr] - if !exist { - // ripeMD is 'touched' at block 1714175, in tx 0x1237f737031e40bcde4a8b7e717b2d15e3ecadfe49bb1bbc71ee9deb09c6fcf2 - // That tx goes out of gas, and although the notion of 'touched' does not exist there, the - // touch-event will still be recorded in the journal. Since ripeMD is a special snowflake, - // it will persist in the journal even though the journal is reverted. In this special circumstance, - // it may exist in `s.journal.dirties` but not in `s.stateObjects`. - // Thus, we can safely ignore it here - continue - } - if obj.selfDestructed || (deleteEmptyObjects && obj.empty()) { - obj.deleted = true - - // We need to maintain account deletions explicitly (will remain - // set indefinitely). Note only the first occurred self-destruct - // event is tracked. - if _, ok := s.stateObjectsDestruct[obj.address]; !ok { - s.stateObjectsDestruct[obj.address] = obj.origin - } - // Note, we can't do this only at the end of a block because multiple - // transactions within the same block might self destruct and then - // resurrect an account; but the snapshotter needs both events. - delete(s.accounts, obj.addrHash) // Clear out any previously updated account data (may be recreated via a resurrect) - delete(s.storages, obj.addrHash) // Clear out any previously updated storage data (may be recreated via a resurrect) - delete(s.accountsOrigin, obj.address) // Clear out any previously updated account data (may be recreated via a resurrect) - delete(s.storagesOrigin, obj.address) // Clear out any previously updated storage data (may be recreated via a resurrect) - } else { - obj.finalise(true) // Prefetch slots in the background - } - obj.created = false - s.stateObjectsPending[addr] = struct{}{} - s.stateObjectsDirty[addr] = struct{}{} - - // At this point, also ship the address off to the precacher. The precacher - // will start loading tries, and when the change is eventually committed, - // the commit-phase will be a lot faster - addressesToPrefetch = append(addressesToPrefetch, common.CopyBytes(addr[:])) // Copy needed for closure - } - if s.prefetcher != nil && len(addressesToPrefetch) > 0 { - s.prefetcher.prefetch(common.Hash{}, s.originalRoot, common.Address{}, addressesToPrefetch) - } - // Invalidate journal because reverting across transactions is not allowed. - s.clearJournalAndRefund() -} - -// IntermediateRoot computes the current root hash of the state trie. -// It is called in between transactions to get the root hash that -// goes into transaction receipts. -func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { - // Finalise all the dirty storage states and write them into the tries - s.Finalise(deleteEmptyObjects) - - // If there was a trie prefetcher operating, it gets aborted and irrevocably - // modified after we start retrieving tries. Remove it from the statedb after - // this round of use. - // - // This is weird pre-byzantium since the first tx runs with a prefetcher and - // the remainder without, but pre-byzantium even the initial prefetcher is - // useless, so no sleep lost. - prefetcher := s.prefetcher - if s.prefetcher != nil { - defer func() { - s.prefetcher.close() - s.prefetcher = nil - }() - } - // Although naively it makes sense to retrieve the account trie and then do - // the contract storage and account updates sequentially, that short circuits - // the account prefetcher. Instead, let's process all the storage updates - // first, giving the account prefetches just a few more milliseconds of time - // to pull useful data from disk. - for addr := range s.stateObjectsPending { - if obj := s.stateObjects[addr]; !obj.deleted { - obj.updateRoot() - } - } - // Now we're about to start to write changes to the trie. The trie is so far - // _untouched_. We can check with the prefetcher, if it can give us a trie - // which has the same root, but also has some content loaded into it. - if prefetcher != nil { - if trie := prefetcher.trie(common.Hash{}, s.originalRoot); trie != nil { - s.trie = trie - } - } - usedAddrs := make([][]byte, 0, len(s.stateObjectsPending)) - for addr := range s.stateObjectsPending { - if obj := s.stateObjects[addr]; obj.deleted { - s.deleteStateObject(obj) - s.AccountDeleted += 1 - } else { - s.updateStateObject(obj) - s.AccountUpdated += 1 - } - usedAddrs = append(usedAddrs, common.CopyBytes(addr[:])) // Copy needed for closure - } - if prefetcher != nil { - prefetcher.used(common.Hash{}, s.originalRoot, usedAddrs) - } - if len(s.stateObjectsPending) > 0 { - s.stateObjectsPending = make(map[common.Address]struct{}) - } - // Track the amount of time wasted on hashing the account trie - if metrics.EnabledExpensive { - defer func(start time.Time) { s.AccountHashes += time.Since(start) }(time.Now()) - } - return s.trie.Hash() +func (s *StateDB) SetState(addr common.Address, key, value common.Hash) { + NormalizeStateKey(&key) + s.StateDB.SetState(addr, key, value) } // SetTxContext sets the current transaction hash and index which are @@ -1052,445 +143,7 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { func (s *StateDB) SetTxContext(thash common.Hash, ti int) { s.thash = thash s.txIndex = ti -} - -func (s *StateDB) clearJournalAndRefund() { - if len(s.journal.entries) > 0 { - s.journal = newJournal() - s.refund = 0 - } - s.validRevisions = s.validRevisions[:0] // Snapshots can be created without journal entries -} - -// fastDeleteStorage is the function that efficiently deletes the storage trie -// of a specific account. It leverages the associated state snapshot for fast -// storage iteration and constructs trie node deletion markers by creating -// stack trie with iterated slots. -func (s *StateDB) fastDeleteStorage(addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) { - iter, _ := s.snap.StorageIterator(addrHash, common.Hash{}) - defer iter.Release() - - var ( - size common.StorageSize - nodes = trienode.NewNodeSet(addrHash) - slots = make(map[common.Hash][]byte) - ) - options := trie.NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - nodes.AddNode(path, trienode.NewDeleted()) - size += common.StorageSize(len(path)) - }) - stack := trie.NewStackTrie(options) - for iter.Next() { - if size > storageDeleteLimit { - return true, size, nil, nil, nil - } - slot := common.CopyBytes(iter.Slot()) - if err := iter.Error(); err != nil { // error might occur after Slot function - return false, 0, nil, nil, err - } - size += common.StorageSize(common.HashLength + len(slot)) - slots[iter.Hash()] = slot - - if err := stack.Update(iter.Hash().Bytes(), slot); err != nil { - return false, 0, nil, nil, err - } - } - if err := iter.Error(); err != nil { // error might occur during iteration - return false, 0, nil, nil, err - } - if stack.Hash() != root { - return false, 0, nil, nil, fmt.Errorf("snapshot is not matched, exp %x, got %x", root, stack.Hash()) - } - return false, size, slots, nodes, nil -} - -// slowDeleteStorage serves as a less-efficient alternative to "fastDeleteStorage," -// employed when the associated state snapshot is not available. It iterates the -// storage slots along with all internal trie nodes via trie directly. -func (s *StateDB) slowDeleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, common.StorageSize, map[common.Hash][]byte, *trienode.NodeSet, error) { - tr, err := s.db.OpenStorageTrie(s.originalRoot, addr, root, s.trie) - if err != nil { - return false, 0, nil, nil, fmt.Errorf("failed to open storage trie, err: %w", err) - } - it, err := tr.NodeIterator(nil) - if err != nil { - return false, 0, nil, nil, fmt.Errorf("failed to open storage iterator, err: %w", err) - } - var ( - size common.StorageSize - nodes = trienode.NewNodeSet(addrHash) - slots = make(map[common.Hash][]byte) - ) - for it.Next(true) { - if size > storageDeleteLimit { - return true, size, nil, nil, nil - } - if it.Leaf() { - slots[common.BytesToHash(it.LeafKey())] = common.CopyBytes(it.LeafBlob()) - size += common.StorageSize(common.HashLength + len(it.LeafBlob())) - continue - } - if it.Hash() == (common.Hash{}) { - continue - } - size += common.StorageSize(len(it.Path())) - nodes.AddNode(it.Path(), trienode.NewDeleted()) - } - if err := it.Error(); err != nil { - return false, 0, nil, nil, err - } - return false, size, slots, nodes, nil -} - -// deleteStorage is designed to delete the storage trie of a designated account. -// It could potentially be terminated if the storage size is excessively large, -// potentially leading to an out-of-memory panic. The function will make an attempt -// to utilize an efficient strategy if the associated state snapshot is reachable; -// otherwise, it will resort to a less-efficient approach. -func (s *StateDB) deleteStorage(addr common.Address, addrHash common.Hash, root common.Hash) (bool, map[common.Hash][]byte, *trienode.NodeSet, error) { - var ( - start = time.Now() - err error - aborted bool - size common.StorageSize - slots map[common.Hash][]byte - nodes *trienode.NodeSet - ) - // The fast approach can be failed if the snapshot is not fully - // generated, or it's internally corrupted. Fallback to the slow - // one just in case. - if s.snap != nil { - aborted, size, slots, nodes, err = s.fastDeleteStorage(addrHash, root) - } - if s.snap == nil || err != nil { - aborted, size, slots, nodes, err = s.slowDeleteStorage(addr, addrHash, root) - } - if err != nil { - return false, nil, nil, err - } - if metrics.EnabledExpensive { - if aborted { - slotDeletionSkip.Inc(1) - } - n := int64(len(slots)) - - slotDeletionMaxCount.UpdateIfGt(int64(len(slots))) - slotDeletionMaxSize.UpdateIfGt(int64(size)) - - slotDeletionTimer.UpdateSince(start) - slotDeletionCount.Mark(n) - slotDeletionSize.Mark(int64(size)) - } - return aborted, slots, nodes, nil -} - -// handleDestruction processes all destruction markers and deletes the account -// and associated storage slots if necessary. There are four possible situations -// here: -// -// - the account was not existent and be marked as destructed -// -// - the account was not existent and be marked as destructed, -// however, it's resurrected later in the same block. -// -// - the account was existent and be marked as destructed -// -// - the account was existent and be marked as destructed, -// however it's resurrected later in the same block. -// -// In case (a), nothing needs be deleted, nil to nil transition can be ignored. -// -// In case (b), nothing needs be deleted, nil is used as the original value for -// newly created account and storages -// -// In case (c), **original** account along with its storages should be deleted, -// with their values be tracked as original value. -// -// In case (d), **original** account along with its storages should be deleted, -// with their values be tracked as original value. -func (s *StateDB) handleDestruction(nodes *trienode.MergedNodeSet) (map[common.Address]struct{}, error) { - // Short circuit if geth is running with hash mode. This procedure can consume - // considerable time and storage deletion isn't supported in hash mode, thus - // preemptively avoiding unnecessary expenses. - incomplete := make(map[common.Address]struct{}) - if s.db.TrieDB().Scheme() == rawdb.HashScheme { - return incomplete, nil - } - for addr, prev := range s.stateObjectsDestruct { - // The original account was non-existing, and it's marked as destructed - // in the scope of block. It can be case (a) or (b). - // - for (a), skip it without doing anything. - // - for (b), track account's original value as nil. It may overwrite - // the data cached in s.accountsOrigin set by 'updateStateObject'. - addrHash := crypto.Keccak256Hash(addr[:]) - if prev == nil { - if _, ok := s.accounts[addrHash]; ok { - s.accountsOrigin[addr] = nil // case (b) - } - continue - } - // It can overwrite the data in s.accountsOrigin set by 'updateStateObject'. - s.accountsOrigin[addr] = types.SlimAccountRLP(*prev) // case (c) or (d) - - // Short circuit if the storage was empty. - if prev.Root == types.EmptyRootHash { - continue - } - // Remove storage slots belong to the account. - aborted, slots, set, err := s.deleteStorage(addr, addrHash, prev.Root) - if err != nil { - return nil, fmt.Errorf("failed to delete storage, err: %w", err) - } - // The storage is too huge to handle, skip it but mark as incomplete. - // For case (d), the account is resurrected might with a few slots - // created. In this case, wipe the entire storage state diff because - // of aborted deletion. - if aborted { - incomplete[addr] = struct{}{} - delete(s.storagesOrigin, addr) - continue - } - if s.storagesOrigin[addr] == nil { - s.storagesOrigin[addr] = slots - } else { - // It can overwrite the data in s.storagesOrigin[addrHash] set by - // 'object.updateTrie'. - for key, val := range slots { - s.storagesOrigin[addr][key] = val - } - } - if err := nodes.Merge(set); err != nil { - return nil, err - } - } - return incomplete, nil -} - -// Commit writes the state to the underlying in-memory trie database. -func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, error) { - return s.commit(block, deleteEmptyObjects, nil, common.Hash{}, common.Hash{}) -} - -// CommitWithSnap writes the state to the underlying in-memory trie database and -// generates a snapshot layer for the newly committed state. -func (s *StateDB) CommitWithSnap(block uint64, deleteEmptyObjects bool, snaps *snapshot.Tree, blockHash, parentHash common.Hash) (common.Hash, error) { - return s.commit(block, deleteEmptyObjects, snaps, blockHash, parentHash) -} - -// Once the state is committed, tries cached in stateDB (including account -// trie, storage tries) will no longer be functional. A new state instance -// must be created with new root and updated database for accessing post- -// commit states. -// -// The associated block number of the state transition is also provided -// for more chain context. -func (s *StateDB) commit(block uint64, deleteEmptyObjects bool, snaps *snapshot.Tree, blockHash, parentHash common.Hash) (common.Hash, error) { - // Short circuit in case any database failure occurred earlier. - if s.dbErr != nil { - return common.Hash{}, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) - } - // Finalize any pending changes and merge everything into the tries - s.IntermediateRoot(deleteEmptyObjects) - - // Commit objects to the trie, measuring the elapsed time - var ( - accountTrieNodesUpdated int - accountTrieNodesDeleted int - storageTrieNodesUpdated int - storageTrieNodesDeleted int - nodes = trienode.NewMergedNodeSet() - codeWriter = s.db.DiskDB().NewBatch() - ) - // Handle all state deletions first - incomplete, err := s.handleDestruction(nodes) - if err != nil { - return common.Hash{}, err - } - // Handle all state updates afterwards - for addr := range s.stateObjectsDirty { - obj := s.stateObjects[addr] - if obj.deleted { - continue - } - // Write any contract code associated with the state object - if obj.code != nil && obj.dirtyCode { - rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code) - obj.dirtyCode = false - } - // Write any storage changes in the state object to its storage trie - set, err := obj.commit() - if err != nil { - return common.Hash{}, err - } - // Merge the dirty nodes of storage trie into global set. It is possible - // that the account was destructed and then resurrected in the same block. - // In this case, the node set is shared by both accounts. - if set != nil { - if err := nodes.Merge(set); err != nil { - return common.Hash{}, err - } - updates, deleted := set.Size() - storageTrieNodesUpdated += updates - storageTrieNodesDeleted += deleted - } - } - if codeWriter.ValueSize() > 0 { - if err := codeWriter.Write(); err != nil { - log.Crit("Failed to commit dirty codes", "error", err) - } - } - // Write the account trie changes, measuring the amount of wasted time - var start time.Time - if metrics.EnabledExpensive { - start = time.Now() - } - root, set, err := s.trie.Commit(true) - if err != nil { - return common.Hash{}, err - } - // Merge the dirty nodes of account trie into global set - if set != nil { - if err := nodes.Merge(set); err != nil { - return common.Hash{}, err - } - accountTrieNodesUpdated, accountTrieNodesDeleted = set.Size() - } - if metrics.EnabledExpensive { - s.AccountCommits += time.Since(start) - - accountUpdatedMeter.Mark(int64(s.AccountUpdated)) - storageUpdatedMeter.Mark(int64(s.StorageUpdated)) - accountDeletedMeter.Mark(int64(s.AccountDeleted)) - storageDeletedMeter.Mark(int64(s.StorageDeleted)) - accountTrieUpdatedMeter.Mark(int64(accountTrieNodesUpdated)) - accountTrieDeletedMeter.Mark(int64(accountTrieNodesDeleted)) - storageTriesUpdatedMeter.Mark(int64(storageTrieNodesUpdated)) - storageTriesDeletedMeter.Mark(int64(storageTrieNodesDeleted)) - s.AccountUpdated, s.AccountDeleted = 0, 0 - s.StorageUpdated, s.StorageDeleted = 0, 0 - } - // If snapshotting is enabled, update the snapshot tree with this new version - if snaps != nil { - start := time.Now() - if s.snap == nil { - log.Error(fmt.Sprintf("cannot commit with snaps without a pre-existing snap layer, parentHash: %s, blockHash: %s", parentHash, blockHash)) - } - if err := snaps.Update(blockHash, root, parentHash, s.convertAccountSet(s.stateObjectsDestruct), s.accounts, s.storages); err != nil { - log.Warn("Failed to update snapshot tree", "to", root, "err", err) - } - if metrics.EnabledExpensive { - s.SnapshotCommits += time.Since(start) - } - s.snap = nil - } - if root == (common.Hash{}) { - root = types.EmptyRootHash - } - origin := s.originalRoot - if origin == (common.Hash{}) { - origin = types.EmptyRootHash - } - if root != origin { - start := time.Now() - set := triestate.New(s.accountsOrigin, s.storagesOrigin, incomplete) - if err := s.db.TrieDB().Update(root, origin, block, nodes, set); err != nil { - return common.Hash{}, err - } - s.originalRoot = root - if metrics.EnabledExpensive { - s.TrieDBCommits += time.Since(start) - } - if s.onCommit != nil { - s.onCommit(set) - } - } - // Clear all internal flags at the end of commit operation. - s.accounts = make(map[common.Hash][]byte) - s.storages = make(map[common.Hash]map[common.Hash][]byte) - s.accountsOrigin = make(map[common.Address][]byte) - s.storagesOrigin = make(map[common.Address]map[common.Hash][]byte) - s.stateObjectsDirty = make(map[common.Address]struct{}) - s.stateObjectsDestruct = make(map[common.Address]*types.StateAccount) - return root, nil -} - -// Prepare handles the preparatory steps for executing a state transition with. -// This method must be invoked before state transition. -// -// Berlin fork (aka ApricotPhase2): -// - Add sender to access list (2929) -// - Add destination to access list (2929) -// - Add precompiles to access list (2929) -// - Add the contents of the optional tx access list (2930) -// -// Potential EIPs: -// - Reset access list (Berlin/ApricotPhase2) -// - Add coinbase to access list (EIP-3651/Durango) -// - Reset transient storage (EIP-1153) -func (s *StateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dst *common.Address, precompiles []common.Address, list types.AccessList) { - if rules.IsApricotPhase2 { - // Clear out any leftover from previous executions - al := newAccessList() - s.accessList = al - - al.AddAddress(sender) - if dst != nil { - al.AddAddress(*dst) - // If it's a create-tx, the destination will be added inside evm.create - } - for _, addr := range precompiles { - al.AddAddress(addr) - } - for _, el := range list { - al.AddAddress(el.Address) - for _, key := range el.StorageKeys { - al.AddSlot(el.Address, key) - } - } - if rules.IsDurango { // EIP-3651: warm coinbase - al.AddAddress(coinbase) - } - - s.predicateStorageSlots = predicate.PreparePredicateStorageSlots(rules, list) - } - // Reset transient storage at the beginning of transaction execution - s.transientStorage = newTransientStorage() -} - -// AddAddressToAccessList adds the given address to the access list -func (s *StateDB) AddAddressToAccessList(addr common.Address) { - if s.accessList.AddAddress(addr) { - s.journal.append(accessListAddAccountChange{&addr}) - } -} - -// AddSlotToAccessList adds the given (address, slot)-tuple to the access list -func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) { - addrMod, slotMod := s.accessList.AddSlot(addr, slot) - if addrMod { - // In practice, this should not happen, since there is no way to enter the - // scope of 'address' without having the 'address' become already added - // to the access list (via call-variant, create, etc). - // Better safe than sorry, though - s.journal.append(accessListAddAccountChange{&addr}) - } - if slotMod { - s.journal.append(accessListAddSlotChange{ - address: &addr, - slot: &slot, - }) - } -} - -// AddressInAccessList returns true if the given address is in the access list. -func (s *StateDB) AddressInAccessList(addr common.Address) bool { - return s.accessList.ContainsAddress(addr) -} - -// SlotInAccessList returns true if the given (address, slot)-tuple is in the access list. -func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) { - return s.accessList.Contains(addr, slot) + s.StateDB.SetTxContext(thash, ti) } // GetTxHash returns the current tx hash on the StateDB set by SetTxContext. @@ -1498,63 +151,28 @@ func (s *StateDB) GetTxHash() common.Hash { return s.thash } -// GetPredicateStorageSlots returns the storage slots associated with the address, index pair. -// A list of access tuples can be included within transaction types post EIP-2930. The address -// is declared directly on the access tuple and the index is the i'th occurrence of an access -// tuple with the specified address. -// -// Ex. AccessList[[AddrA, Predicate1], [AddrB, Predicate2], [AddrA, Predicate3]] -// In this case, the caller could retrieve predicates 1-3 with the following calls: -// GetPredicateStorageSlots(AddrA, 0) -> Predicate1 -// GetPredicateStorageSlots(AddrB, 0) -> Predicate2 -// GetPredicateStorageSlots(AddrA, 1) -> Predicate3 -func (s *StateDB) GetPredicateStorageSlots(address common.Address, index int) ([]byte, bool) { - predicates, exists := s.predicateStorageSlots[address] - if !exists { - return nil, false - } - if index >= len(predicates) { - return nil, false - } - return predicates[index], true -} - -// convertAccountSet converts a provided account set from address keyed to hash keyed. -func (s *StateDB) convertAccountSet(set map[common.Address]*types.StateAccount) map[common.Hash]struct{} { - ret := make(map[common.Hash]struct{}, len(set)) - for addr := range set { - obj, exist := s.stateObjects[addr] - if !exist { - ret[crypto.Keccak256Hash(addr[:])] = struct{}{} - } else { - ret[obj.addrHash] = struct{}{} - } +func (s *StateDB) Copy() *StateDB { + return &StateDB{ + StateDB: s.StateDB.Copy(), + db: s.db, + snaps: s.snaps, + thash: s.thash, + txIndex: s.txIndex, } - return ret } -// SetPredicateStorageSlots sets the predicate storage slots for the given address -func (s *StateDB) SetPredicateStorageSlots(address common.Address, predicates [][]byte) { - s.predicateStorageSlots[address] = predicates +// NormalizeCoinID ORs the 0th bit of the first byte in +// `coinID`, which ensures this bit will be 1 and all other +// bits are left the same. +// This partitions multicoin storage from normal state storage. +func NormalizeCoinID(coinID *common.Hash) { + coinID[0] |= 0x01 } -// copySet returns a deep-copied set. -func copySet[k comparable](set map[k][]byte) map[k][]byte { - copied := make(map[k][]byte, len(set)) - for key, val := range set { - copied[key] = common.CopyBytes(val) - } - return copied -} - -// copy2DSet returns a two-dimensional deep-copied set. -func copy2DSet[k comparable](set map[k]map[common.Hash][]byte) map[k]map[common.Hash][]byte { - copied := make(map[k]map[common.Hash][]byte, len(set)) - for addr, subset := range set { - copied[addr] = make(map[common.Hash][]byte, len(subset)) - for key, val := range subset { - copied[addr][key] = common.CopyBytes(val) - } - } - return copied +// NormalizeStateKey ANDs the 0th bit of the first byte in +// `key`, which ensures this bit will be 0 and all other bits +// are left the same. +// This partitions normal state storage from multicoin storage. +func NormalizeStateKey(key *common.Hash) { + key[0] &= 0xfe } diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go deleted file mode 100644 index 9cbbffa870..0000000000 --- a/core/state/statedb_fuzz_test.go +++ /dev/null @@ -1,402 +0,0 @@ -// (c) 2024, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see - -package state - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "math" - "math/rand" - "reflect" - "strings" - "testing" - "testing/quick" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ava-labs/coreth/triedb" - "github.com/ava-labs/coreth/triedb/pathdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "github.com/holiman/uint256" -) - -// A stateTest checks that the state changes are correctly captured. Instances -// of this test with pseudorandom content are created by Generate. -// -// The test works as follows: -// -// A list of states are created by applying actions. The state changes between -// each state instance are tracked and be verified. -type stateTest struct { - addrs []common.Address // all account addresses - actions [][]testAction // modifications to the state, grouped by block - chunk int // The number of actions per chunk - err error // failure details are reported through this field -} - -// newStateTestAction creates a random action that changes state. -func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction { - actions := []testAction{ - { - name: "SetBalance", - fn: func(a testAction, s *StateDB) { - s.SetBalance(addr, uint256.NewInt(uint64(a.args[0]))) - }, - args: make([]int64, 1), - }, - { - name: "SetNonce", - fn: func(a testAction, s *StateDB) { - s.SetNonce(addr, uint64(a.args[0])) - }, - args: make([]int64, 1), - }, - { - name: "SetState", - fn: func(a testAction, s *StateDB) { - var key, val common.Hash - binary.BigEndian.PutUint16(key[:], uint16(a.args[0])) - binary.BigEndian.PutUint16(val[:], uint16(a.args[1])) - s.SetState(addr, key, val) - }, - args: make([]int64, 2), - }, - { - name: "SetCode", - fn: func(a testAction, s *StateDB) { - code := make([]byte, 16) - binary.BigEndian.PutUint64(code, uint64(a.args[0])) - binary.BigEndian.PutUint64(code[8:], uint64(a.args[1])) - s.SetCode(addr, code) - }, - args: make([]int64, 2), - }, - { - name: "CreateAccount", - fn: func(a testAction, s *StateDB) { - s.CreateAccount(addr) - }, - }, - { - name: "Selfdestruct", - fn: func(a testAction, s *StateDB) { - s.SelfDestruct(addr) - }, - }, - } - var nonRandom = index != -1 - if index == -1 { - index = r.Intn(len(actions)) - } - action := actions[index] - var names []string - if !action.noAddr { - names = append(names, addr.Hex()) - } - for i := range action.args { - if nonRandom { - action.args[i] = rand.Int63n(10000) + 1 // set balance to non-zero - } else { - action.args[i] = rand.Int63n(10000) - } - names = append(names, fmt.Sprint(action.args[i])) - } - action.name += " " + strings.Join(names, ", ") - return action -} - -// Generate returns a new snapshot test of the given size. All randomness is -// derived from r. -func (*stateTest) Generate(r *rand.Rand, size int) reflect.Value { - addrs := make([]common.Address, 5) - for i := range addrs { - addrs[i][0] = byte(i) - } - actions := make([][]testAction, rand.Intn(5)+1) - - for i := 0; i < len(actions); i++ { - actions[i] = make([]testAction, size) - for j := range actions[i] { - if j == 0 { - // Always include a set balance action to make sure - // the state changes are not empty. - actions[i][j] = newStateTestAction(common.HexToAddress("0xdeadbeef"), r, 0) - continue - } - actions[i][j] = newStateTestAction(addrs[r.Intn(len(addrs))], r, -1) - } - } - chunk := int(math.Sqrt(float64(size))) - if size > 0 && chunk == 0 { - chunk = 1 - } - return reflect.ValueOf(&stateTest{ - addrs: addrs, - actions: actions, - chunk: chunk, - }) -} - -func (test *stateTest) String() string { - out := new(bytes.Buffer) - for i, actions := range test.actions { - fmt.Fprintf(out, "---- block %d ----\n", i) - for j, action := range actions { - if j%test.chunk == 0 { - fmt.Fprintf(out, "---- transaction %d ----\n", j/test.chunk) - } - fmt.Fprintf(out, "%4d: %s\n", j%test.chunk, action.name) - } - } - return out.String() -} - -func (test *stateTest) run() bool { - var ( - roots []common.Hash - accountList []map[common.Address][]byte - storageList []map[common.Address]map[common.Hash][]byte - onCommit = func(states *triestate.Set) { - accountList = append(accountList, copySet(states.Accounts)) - storageList = append(storageList, copy2DSet(states.Storages)) - } - disk = rawdb.NewMemoryDatabase() - tdb = triedb.NewDatabase(disk, &triedb.Config{PathDB: pathdb.Defaults}) - sdb = NewDatabaseWithNodeDB(disk, tdb) - byzantium = rand.Intn(2) == 0 - ) - defer disk.Close() - defer tdb.Close() - - var snaps *snapshot.Tree - if rand.Intn(3) == 0 { - snaps, _ = snapshot.New(snapshot.Config{ - CacheSize: 1, - NoBuild: false, - AsyncBuild: false, - }, disk, tdb, common.Hash{}, types.EmptyRootHash) - } - for i, actions := range test.actions { - root := types.EmptyRootHash - if i != 0 { - root = roots[len(roots)-1] - } - state, err := New(root, sdb, snaps) - if err != nil { - panic(err) - } - state.onCommit = onCommit - - for i, action := range actions { - if i%test.chunk == 0 && i != 0 { - if byzantium { - state.Finalise(true) // call finalise at the transaction boundary - } else { - state.IntermediateRoot(true) // call intermediateRoot at the transaction boundary - } - } - action.fn(action, state) - } - if byzantium { - state.Finalise(true) // call finalise at the transaction boundary - } else { - state.IntermediateRoot(true) // call intermediateRoot at the transaction boundary - } - nroot, err := state.Commit(0, true) // call commit at the block boundary - if err != nil { - panic(err) - } - if nroot == root { - return true // filter out non-change state transition - } - roots = append(roots, nroot) - } - for i := 0; i < len(test.actions); i++ { - root := types.EmptyRootHash - if i != 0 { - root = roots[i-1] - } - test.err = test.verify(root, roots[i], tdb, accountList[i], storageList[i]) - if test.err != nil { - return false - } - } - return true -} - -// verifyAccountCreation this function is called once the state diff says that -// specific account was not present. A serial of checks will be performed to -// ensure the state diff is correct, includes: -// -// - the account was indeed not present in trie -// - the account is present in new trie, nil->nil is regarded as invalid -// - the slots transition is correct -func (test *stateTest) verifyAccountCreation(next common.Hash, db *triedb.Database, otr, ntr *trie.Trie, addr common.Address, slots map[common.Hash][]byte) error { - // Verify account change - addrHash := crypto.Keccak256Hash(addr.Bytes()) - oBlob, err := otr.Get(addrHash.Bytes()) - if err != nil { - return err - } - nBlob, err := ntr.Get(addrHash.Bytes()) - if err != nil { - return err - } - if len(oBlob) != 0 { - return fmt.Errorf("unexpected account in old trie, %x", addrHash) - } - if len(nBlob) == 0 { - return fmt.Errorf("missing account in new trie, %x", addrHash) - } - - // Verify storage changes - var nAcct types.StateAccount - if err := rlp.DecodeBytes(nBlob, &nAcct); err != nil { - return err - } - // Account has no slot, empty slot set is expected - if nAcct.Root == types.EmptyRootHash { - if len(slots) != 0 { - return fmt.Errorf("unexpected slot changes %x", addrHash) - } - return nil - } - // Account has slots, ensure all new slots are contained - st, err := trie.New(trie.StorageTrieID(next, addrHash, nAcct.Root), db) - if err != nil { - return err - } - for key, val := range slots { - st.Update(key.Bytes(), val) - } - if st.Hash() != types.EmptyRootHash { - return errors.New("invalid slot changes") - } - return nil -} - -// verifyAccountUpdate this function is called once the state diff says that -// specific account was present. A serial of checks will be performed to -// ensure the state diff is correct, includes: -// -// - the account was indeed present in trie -// - the account in old trie matches the provided value -// - the slots transition is correct -func (test *stateTest) verifyAccountUpdate(next common.Hash, db *triedb.Database, otr, ntr *trie.Trie, addr common.Address, origin []byte, slots map[common.Hash][]byte) error { - // Verify account change - addrHash := crypto.Keccak256Hash(addr.Bytes()) - oBlob, err := otr.Get(addrHash.Bytes()) - if err != nil { - return err - } - nBlob, err := ntr.Get(addrHash.Bytes()) - if err != nil { - return err - } - if len(oBlob) == 0 { - return fmt.Errorf("missing account in old trie, %x", addrHash) - } - full, err := types.FullAccountRLP(origin) - if err != nil { - return err - } - if !bytes.Equal(full, oBlob) { - return fmt.Errorf("account value is not matched, %x", addrHash) - } - - // Decode accounts - var ( - oAcct types.StateAccount - nAcct types.StateAccount - nRoot common.Hash - ) - if err := rlp.DecodeBytes(oBlob, &oAcct); err != nil { - return err - } - if len(nBlob) == 0 { - nRoot = types.EmptyRootHash - } else { - if err := rlp.DecodeBytes(nBlob, &nAcct); err != nil { - return err - } - nRoot = nAcct.Root - } - - // Verify storage - st, err := trie.New(trie.StorageTrieID(next, addrHash, nRoot), db) - if err != nil { - return err - } - for key, val := range slots { - st.Update(key.Bytes(), val) - } - if st.Hash() != oAcct.Root { - return errors.New("invalid slot changes") - } - return nil -} - -func (test *stateTest) verify(root common.Hash, next common.Hash, db *triedb.Database, accountsOrigin map[common.Address][]byte, storagesOrigin map[common.Address]map[common.Hash][]byte) error { - otr, err := trie.New(trie.StateTrieID(root), db) - if err != nil { - return err - } - ntr, err := trie.New(trie.StateTrieID(next), db) - if err != nil { - return err - } - for addr, account := range accountsOrigin { - var err error - if len(account) == 0 { - err = test.verifyAccountCreation(next, db, otr, ntr, addr, storagesOrigin[addr]) - } else { - err = test.verifyAccountUpdate(next, db, otr, ntr, addr, accountsOrigin[addr], storagesOrigin[addr]) - } - if err != nil { - return err - } - } - return nil -} - -func TestStateChanges(t *testing.T) { - config := &quick.Config{MaxCount: 1000} - err := quick.Check((*stateTest).run, config) - if cerr, ok := err.(*quick.CheckError); ok { - test := cerr.In[0].(*stateTest) - t.Errorf("%v:\n%s", test.err, test) - } else if err != nil { - t.Error(err) - } -} diff --git a/core/state/statedb_multicoin_test.go b/core/state/statedb_multicoin_test.go new file mode 100644 index 0000000000..5cfd06540b --- /dev/null +++ b/core/state/statedb_multicoin_test.go @@ -0,0 +1,155 @@ +// (c) 2019-2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package state + +import ( + "math/big" + "testing" + + "github.com/ava-labs/coreth/core/state/snapshot" + "github.com/ava-labs/coreth/plugin/evm/customtypes" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/crypto" + "github.com/holiman/uint256" + "github.com/stretchr/testify/require" +) + +func TestMultiCoinOperations(t *testing.T) { + s := newStateEnv() + addr := common.Address{1} + assetID := common.Hash{2} + + root, err := s.state.Commit(0, false) + require.NoError(t, err, "committing state") + s.state, err = New(root, s.state.db, s.state.snaps) + require.NoError(t, err, "creating statedb") + + s.state.AddBalance(addr, new(uint256.Int)) + + balance := s.state.GetBalanceMultiCoin(addr, assetID) + require.Equal(t, "0", balance.String(), "expected zero big.Int multicoin balance as string") + + s.state.AddBalanceMultiCoin(addr, assetID, big.NewInt(10)) + s.state.SubBalanceMultiCoin(addr, assetID, big.NewInt(5)) + s.state.AddBalanceMultiCoin(addr, assetID, big.NewInt(3)) + + balance = s.state.GetBalanceMultiCoin(addr, assetID) + require.Equal(t, "8", balance.String(), "unexpected multicoin balance string") +} + +func TestMultiCoinSnapshot(t *testing.T) { + db := rawdb.NewMemoryDatabase() + sdb := NewDatabase(db) + + // Create empty [snapshot.Tree] and [StateDB] + root := common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") + // Use the root as both the stateRoot and blockHash for this test. + snapTree := snapshot.NewTestTree(db, root, root) + + addr := common.Address{1} + assetID1 := common.Hash{1} + assetID2 := common.Hash{2} + + var stateDB *StateDB + assertBalances := func(regular, multicoin1, multicoin2 int64) { + balance := stateDB.GetBalance(addr) + require.Equal(t, uint256.NewInt(uint64(regular)), balance, "incorrect non-multicoin balance") + balanceBig := stateDB.GetBalanceMultiCoin(addr, assetID1) + require.Equal(t, big.NewInt(multicoin1).String(), balanceBig.String(), "incorrect multicoin1 balance") + balanceBig = stateDB.GetBalanceMultiCoin(addr, assetID2) + require.Equal(t, big.NewInt(multicoin2).String(), balanceBig.String(), "incorrect multicoin2 balance") + } + + // Create new state + stateDB, err := New(root, sdb, snapTree) + require.NoError(t, err, "creating statedb") + assertBalances(0, 0, 0) + + stateDB.AddBalance(addr, uint256.NewInt(10)) + assertBalances(10, 0, 0) + + // Commit and get the new root + root, err = stateDB.Commit(0, false, snapshot.WithBlockHashes(common.Hash{}, common.Hash{})) + require.NoError(t, err, "committing statedb") + assertBalances(10, 0, 0) + + // Create a new state from the latest root, add a multicoin balance, and + // commit it to the tree. + stateDB, err = New(root, sdb, snapTree) + require.NoError(t, err, "creating statedb") + stateDB.AddBalanceMultiCoin(addr, assetID1, big.NewInt(10)) + root, err = stateDB.Commit(0, false, snapshot.WithBlockHashes(common.Hash{}, common.Hash{})) + require.NoError(t, err, "committing statedb") + assertBalances(10, 10, 0) + + // Add more layers than the cap and ensure the balances and layers are correct + for i := 0; i < 256; i++ { + stateDB, err = New(root, sdb, snapTree) + require.NoErrorf(t, err, "creating statedb %d", i) + stateDB.AddBalanceMultiCoin(addr, assetID1, big.NewInt(1)) + stateDB.AddBalanceMultiCoin(addr, assetID2, big.NewInt(2)) + root, err = stateDB.Commit(0, false, snapshot.WithBlockHashes(common.Hash{}, common.Hash{})) + require.NoErrorf(t, err, "committing statedb %d", i) + } + assertBalances(10, 266, 512) + + // Do one more add, including the regular balance which is now in the + // collapsed snapshot + stateDB, err = New(root, sdb, snapTree) + require.NoError(t, err, "creating statedb") + stateDB.AddBalance(addr, uint256.NewInt(1)) + stateDB.AddBalanceMultiCoin(addr, assetID1, big.NewInt(1)) + root, err = stateDB.Commit(0, false, snapshot.WithBlockHashes(common.Hash{}, common.Hash{})) + require.NoError(t, err, "committing statedb") + + stateDB, err = New(root, sdb, snapTree) + require.NoError(t, err, "creating statedb") + assertBalances(11, 267, 512) +} + +func TestGenerateMultiCoinAccounts(t *testing.T) { + diskdb := rawdb.NewMemoryDatabase() + database := NewDatabase(diskdb) + + addr := common.BytesToAddress([]byte("addr1")) + addrHash := crypto.Keccak256Hash(addr[:]) + + assetID := common.BytesToHash([]byte("coin1")) + assetBalance := big.NewInt(10) + + stateDB, err := New(common.Hash{}, database, nil) + require.NoError(t, err, "creating statedb") + stateDB.AddBalanceMultiCoin(addr, assetID, assetBalance) + root, err := stateDB.Commit(0, false) + require.NoError(t, err, "committing statedb") + + triedb := database.TrieDB() + err = triedb.Commit(root, true) + require.NoError(t, err, "committing trie") + + // Build snapshot from scratch + snapConfig := snapshot.Config{ + CacheSize: 16, + AsyncBuild: false, + NoBuild: false, + SkipVerify: true, + } + snaps, err := snapshot.New(snapConfig, diskdb, triedb, common.Hash{}, root) + require.NoError(t, err, "rebuilding snapshot") + + // Get latest snapshot and make sure it has the correct account and storage + snap := snaps.Snapshot(root) + snapAccount, err := snap.Account(addrHash) + require.NoError(t, err, "getting account from snapshot") + require.True(t, customtypes.IsMultiCoin(snapAccount), "snap account must be multi-coin") + + NormalizeCoinID(&assetID) + assetHash := crypto.Keccak256Hash(assetID.Bytes()) + storageBytes, err := snap.Storage(addrHash, assetHash) + require.NoError(t, err, "getting storage from snapshot") + + actualAssetBalance := new(big.Int).SetBytes(storageBytes) + require.Equal(t, assetBalance, actualAssetBalance, "incorrect asset balance") +} diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go deleted file mode 100644 index 88799e3c3e..0000000000 --- a/core/state/statedb_test.go +++ /dev/null @@ -1,1355 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "math" - "math/big" - "math/rand" - "reflect" - "strings" - "sync" - "testing" - "testing/quick" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/triedb" - "github.com/ava-labs/coreth/triedb/hashdb" - "github.com/ava-labs/coreth/triedb/pathdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "github.com/holiman/uint256" -) - -// Tests that updating a state trie does not leak any database writes prior to -// actually committing the state. -func TestUpdateLeaks(t *testing.T) { - // Create an empty state database - var ( - db = rawdb.NewMemoryDatabase() - tdb = triedb.NewDatabase(db, nil) - ) - state, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(db, tdb), nil) - - // Update it with some accounts - for i := byte(0); i < 255; i++ { - addr := common.BytesToAddress([]byte{i}) - state.AddBalance(addr, uint256.NewInt(uint64(11*i))) - state.SetNonce(addr, uint64(42*i)) - if i%2 == 0 { - state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i})) - } - if i%3 == 0 { - state.SetCode(addr, []byte{i, i, i, i, i}) - } - } - - root := state.IntermediateRoot(false) - if err := tdb.Commit(root, false); err != nil { - t.Errorf("can not commit trie %v to persistent database", root.Hex()) - } - - // Ensure that no data was leaked into the database - it := db.NewIterator(nil, nil) - for it.Next() { - t.Errorf("State leaked into database: %x -> %x", it.Key(), it.Value()) - } - it.Release() -} - -// Tests that no intermediate state of an object is stored into the database, -// only the one right before the commit. -func TestIntermediateLeaks(t *testing.T) { - // Create two state databases, one transitioning to the final state, the other final from the beginning - transDb := rawdb.NewMemoryDatabase() - finalDb := rawdb.NewMemoryDatabase() - transNdb := triedb.NewDatabase(transDb, nil) - finalNdb := triedb.NewDatabase(finalDb, nil) - transState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(transDb, transNdb), nil) - finalState, _ := New(types.EmptyRootHash, NewDatabaseWithNodeDB(finalDb, finalNdb), nil) - - modify := func(state *StateDB, addr common.Address, i, tweak byte) { - state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak))) - state.SetNonce(addr, uint64(42*i+tweak)) - if i%2 == 0 { - state.SetState(addr, common.Hash{i, i, i, 0}, common.Hash{}) - state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak}) - } - if i%3 == 0 { - state.SetCode(addr, []byte{i, i, i, i, i, tweak}) - } - } - - // Modify the transient state. - for i := byte(0); i < 255; i++ { - modify(transState, common.Address{i}, i, 0) - } - // Write modifications to trie. - transState.IntermediateRoot(false) - - // Overwrite all the data with new values in the transient database. - for i := byte(0); i < 255; i++ { - modify(transState, common.Address{i}, i, 99) - modify(finalState, common.Address{i}, i, 99) - } - - // Commit and cross check the databases. - transRoot, err := transState.Commit(0, false) - if err != nil { - t.Fatalf("failed to commit transition state: %v", err) - } - if err = transNdb.Commit(transRoot, false); err != nil { - t.Errorf("can not commit trie %v to persistent database", transRoot.Hex()) - } - - finalRoot, err := finalState.Commit(0, false) - if err != nil { - t.Fatalf("failed to commit final state: %v", err) - } - if err = finalNdb.Commit(finalRoot, false); err != nil { - t.Errorf("can not commit trie %v to persistent database", finalRoot.Hex()) - } - - it := finalDb.NewIterator(nil, nil) - for it.Next() { - key, fvalue := it.Key(), it.Value() - tvalue, err := transDb.Get(key) - if err != nil { - t.Errorf("entry missing from the transition database: %x -> %x", key, fvalue) - } - if !bytes.Equal(fvalue, tvalue) { - t.Errorf("value mismatch at key %x: %x in transition database, %x in final database", key, tvalue, fvalue) - } - } - it.Release() - - it = transDb.NewIterator(nil, nil) - for it.Next() { - key, tvalue := it.Key(), it.Value() - fvalue, err := finalDb.Get(key) - if err != nil { - t.Errorf("extra entry in the transition database: %x -> %x", key, it.Value()) - } - if !bytes.Equal(fvalue, tvalue) { - t.Errorf("value mismatch at key %x: %x in transition database, %x in final database", key, tvalue, fvalue) - } - } -} - -// TestCopy tests that copying a StateDB object indeed makes the original and -// the copy independent of each other. This test is a regression test against -// https://github.com/ethereum/go-ethereum/pull/15549. -func TestCopy(t *testing.T) { - // Create a random state test to copy and modify "independently" - orig, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - - for i := byte(0); i < 255; i++ { - obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i})) - obj.AddBalance(uint256.NewInt(uint64(i))) - orig.updateStateObject(obj) - } - orig.Finalise(false) - - // Copy the state - copy := orig.Copy() - - // Copy the copy state - ccopy := copy.Copy() - - // modify all in memory - for i := byte(0); i < 255; i++ { - origObj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i})) - copyObj := copy.getOrNewStateObject(common.BytesToAddress([]byte{i})) - ccopyObj := ccopy.getOrNewStateObject(common.BytesToAddress([]byte{i})) - - origObj.AddBalance(uint256.NewInt(2 * uint64(i))) - copyObj.AddBalance(uint256.NewInt(3 * uint64(i))) - ccopyObj.AddBalance(uint256.NewInt(4 * uint64(i))) - - orig.updateStateObject(origObj) - copy.updateStateObject(copyObj) - ccopy.updateStateObject(copyObj) - } - - // Finalise the changes on all concurrently - finalise := func(wg *sync.WaitGroup, db *StateDB) { - defer wg.Done() - db.Finalise(true) - } - - var wg sync.WaitGroup - wg.Add(3) - go finalise(&wg, orig) - go finalise(&wg, copy) - go finalise(&wg, ccopy) - wg.Wait() - - // Verify that the three states have been updated independently - for i := byte(0); i < 255; i++ { - origObj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i})) - copyObj := copy.getOrNewStateObject(common.BytesToAddress([]byte{i})) - ccopyObj := ccopy.getOrNewStateObject(common.BytesToAddress([]byte{i})) - - if want := uint256.NewInt(3 * uint64(i)); origObj.Balance().Cmp(want) != 0 { - t.Errorf("orig obj %d: balance mismatch: have %v, want %v", i, origObj.Balance(), want) - } - if want := uint256.NewInt(4 * uint64(i)); copyObj.Balance().Cmp(want) != 0 { - t.Errorf("copy obj %d: balance mismatch: have %v, want %v", i, copyObj.Balance(), want) - } - if want := uint256.NewInt(5 * uint64(i)); ccopyObj.Balance().Cmp(want) != 0 { - t.Errorf("copy obj %d: balance mismatch: have %v, want %v", i, ccopyObj.Balance(), want) - } - } -} - -func TestSnapshotRandom(t *testing.T) { - config := &quick.Config{MaxCount: 1000} - err := quick.Check((*snapshotTest).run, config) - if cerr, ok := err.(*quick.CheckError); ok { - test := cerr.In[0].(*snapshotTest) - t.Errorf("%v:\n%s", test.err, test) - } else if err != nil { - t.Error(err) - } -} - -// A snapshotTest checks that reverting StateDB snapshots properly undoes all changes -// captured by the snapshot. Instances of this test with pseudorandom content are created -// by Generate. -// -// The test works as follows: -// -// A new state is created and all actions are applied to it. Several snapshots are taken -// in between actions. The test then reverts each snapshot. For each snapshot the actions -// leading up to it are replayed on a fresh, empty state. The behaviour of all public -// accessor methods on the reverted state must match the return value of the equivalent -// methods on the replayed state. -type snapshotTest struct { - addrs []common.Address // all account addresses - actions []testAction // modifications to the state - snapshots []int // actions indexes at which snapshot is taken - err error // failure details are reported through this field -} - -type testAction struct { - name string - fn func(testAction, *StateDB) - args []int64 - noAddr bool -} - -// newTestAction creates a random action that changes state. -func newTestAction(addr common.Address, r *rand.Rand) testAction { - actions := []testAction{ - { - name: "SetBalance", - fn: func(a testAction, s *StateDB) { - s.SetBalance(addr, uint256.NewInt(uint64(a.args[0]))) - }, - args: make([]int64, 1), - }, - { - name: "AddBalance", - fn: func(a testAction, s *StateDB) { - s.AddBalance(addr, uint256.NewInt(uint64(a.args[0]))) - }, - args: make([]int64, 1), - }, - { - name: "SetNonce", - fn: func(a testAction, s *StateDB) { - s.SetNonce(addr, uint64(a.args[0])) - }, - args: make([]int64, 1), - }, - { - name: "SetState", - fn: func(a testAction, s *StateDB) { - var key, val common.Hash - binary.BigEndian.PutUint16(key[:], uint16(a.args[0])) - binary.BigEndian.PutUint16(val[:], uint16(a.args[1])) - s.SetState(addr, key, val) - }, - args: make([]int64, 2), - }, - { - name: "SetCode", - fn: func(a testAction, s *StateDB) { - code := make([]byte, 16) - binary.BigEndian.PutUint64(code, uint64(a.args[0])) - binary.BigEndian.PutUint64(code[8:], uint64(a.args[1])) - s.SetCode(addr, code) - }, - args: make([]int64, 2), - }, - { - name: "CreateAccount", - fn: func(a testAction, s *StateDB) { - s.CreateAccount(addr) - }, - }, - { - name: "SelfDestruct", - fn: func(a testAction, s *StateDB) { - s.SelfDestruct(addr) - }, - }, - { - name: "AddRefund", - fn: func(a testAction, s *StateDB) { - s.AddRefund(uint64(a.args[0])) - }, - args: make([]int64, 1), - noAddr: true, - }, - { - name: "AddLog", - fn: func(a testAction, s *StateDB) { - data := make([]byte, 2) - binary.BigEndian.PutUint16(data, uint16(a.args[0])) - s.AddLog(addr, nil, data, 0) - }, - args: make([]int64, 1), - }, - { - name: "AddPreimage", - fn: func(a testAction, s *StateDB) { - preimage := []byte{1} - hash := common.BytesToHash(preimage) - s.AddPreimage(hash, preimage) - }, - args: make([]int64, 1), - }, - { - name: "AddAddressToAccessList", - fn: func(a testAction, s *StateDB) { - s.AddAddressToAccessList(addr) - }, - }, - { - name: "AddSlotToAccessList", - fn: func(a testAction, s *StateDB) { - s.AddSlotToAccessList(addr, - common.Hash{byte(a.args[0])}) - }, - args: make([]int64, 1), - }, - { - name: "SetTransientState", - fn: func(a testAction, s *StateDB) { - var key, val common.Hash - binary.BigEndian.PutUint16(key[:], uint16(a.args[0])) - binary.BigEndian.PutUint16(val[:], uint16(a.args[1])) - s.SetTransientState(addr, key, val) - }, - args: make([]int64, 2), - }, - } - action := actions[r.Intn(len(actions))] - var nameargs []string - if !action.noAddr { - nameargs = append(nameargs, addr.Hex()) - } - for i := range action.args { - action.args[i] = rand.Int63n(100) - nameargs = append(nameargs, fmt.Sprint(action.args[i])) - } - action.name += strings.Join(nameargs, ", ") - return action -} - -// Generate returns a new snapshot test of the given size. All randomness is -// derived from r. -func (*snapshotTest) Generate(r *rand.Rand, size int) reflect.Value { - // Generate random actions. - addrs := make([]common.Address, 50) - for i := range addrs { - addrs[i][0] = byte(i) - } - actions := make([]testAction, size) - for i := range actions { - addr := addrs[r.Intn(len(addrs))] - actions[i] = newTestAction(addr, r) - } - // Generate snapshot indexes. - nsnapshots := int(math.Sqrt(float64(size))) - if size > 0 && nsnapshots == 0 { - nsnapshots = 1 - } - snapshots := make([]int, nsnapshots) - snaplen := len(actions) / nsnapshots - for i := range snapshots { - // Try to place the snapshots some number of actions apart from each other. - snapshots[i] = (i * snaplen) + r.Intn(snaplen) - } - return reflect.ValueOf(&snapshotTest{addrs, actions, snapshots, nil}) -} - -func (test *snapshotTest) String() string { - out := new(bytes.Buffer) - sindex := 0 - for i, action := range test.actions { - if len(test.snapshots) > sindex && i == test.snapshots[sindex] { - fmt.Fprintf(out, "---- snapshot %d ----\n", sindex) - sindex++ - } - fmt.Fprintf(out, "%4d: %s\n", i, action.name) - } - return out.String() -} - -func (test *snapshotTest) run() bool { - // Run all actions and create snapshots. - var ( - state, _ = New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - snapshotRevs = make([]int, len(test.snapshots)) - sindex = 0 - checkstates = make([]*StateDB, len(test.snapshots)) - ) - for i, action := range test.actions { - if len(test.snapshots) > sindex && i == test.snapshots[sindex] { - snapshotRevs[sindex] = state.Snapshot() - checkstates[sindex] = state.Copy() - sindex++ - } - action.fn(action, state) - } - // Revert all snapshots in reverse order. Each revert must yield a state - // that is equivalent to fresh state with all actions up the snapshot applied. - for sindex--; sindex >= 0; sindex-- { - state.RevertToSnapshot(snapshotRevs[sindex]) - if err := test.checkEqual(state, checkstates[sindex]); err != nil { - test.err = fmt.Errorf("state mismatch after revert to snapshot %d\n%v", sindex, err) - return false - } - } - return true -} - -func forEachStorage(s *StateDB, addr common.Address, cb func(key, value common.Hash) bool) error { - so := s.getStateObject(addr) - if so == nil { - return nil - } - tr, err := so.getTrie() - if err != nil { - return err - } - trieIt, err := tr.NodeIterator(nil) - if err != nil { - return err - } - it := trie.NewIterator(trieIt) - - for it.Next() { - key := common.BytesToHash(s.trie.GetKey(it.Key)) - if value, dirty := so.dirtyStorage[key]; dirty { - if !cb(key, value) { - return nil - } - continue - } - - if len(it.Value) > 0 { - _, content, _, err := rlp.Split(it.Value) - if err != nil { - return err - } - if !cb(key, common.BytesToHash(content)) { - return nil - } - } - } - return nil -} - -// checkEqual checks that methods of state and checkstate return the same values. -func (test *snapshotTest) checkEqual(state, checkstate *StateDB) error { - for _, addr := range test.addrs { - var err error - checkeq := func(op string, a, b interface{}) bool { - if err == nil && !reflect.DeepEqual(a, b) { - err = fmt.Errorf("got %s(%s) == %v, want %v", op, addr.Hex(), a, b) - return false - } - return true - } - // Check basic accessor methods. - checkeq("Exist", state.Exist(addr), checkstate.Exist(addr)) - checkeq("HasSelfdestructed", state.HasSelfDestructed(addr), checkstate.HasSelfDestructed(addr)) - checkeq("GetBalance", state.GetBalance(addr), checkstate.GetBalance(addr)) - checkeq("GetNonce", state.GetNonce(addr), checkstate.GetNonce(addr)) - checkeq("GetCode", state.GetCode(addr), checkstate.GetCode(addr)) - checkeq("GetCodeHash", state.GetCodeHash(addr), checkstate.GetCodeHash(addr)) - checkeq("GetCodeSize", state.GetCodeSize(addr), checkstate.GetCodeSize(addr)) - // Check storage. - if obj := state.getStateObject(addr); obj != nil { - forEachStorage(state, addr, func(key, value common.Hash) bool { - return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value) - }) - forEachStorage(checkstate, addr, func(key, value common.Hash) bool { - return checkeq("GetState("+key.Hex()+")", checkstate.GetState(addr, key), value) - }) - } - if err != nil { - return err - } - } - - if state.GetRefund() != checkstate.GetRefund() { - return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d", - state.GetRefund(), checkstate.GetRefund()) - } - if !reflect.DeepEqual(state.GetLogs(common.Hash{}, 0, common.Hash{}), checkstate.GetLogs(common.Hash{}, 0, common.Hash{})) { - return fmt.Errorf("got GetLogs(common.Hash{}) == %v, want GetLogs(common.Hash{}) == %v", - state.GetLogs(common.Hash{}, 0, common.Hash{}), checkstate.GetLogs(common.Hash{}, 0, common.Hash{})) - } - return nil -} - -func TestTouchDelete(t *testing.T) { - s := newStateEnv() - s.state.getOrNewStateObject(common.Address{}) - root, _ := s.state.Commit(0, false) - s.state, _ = NewWithSnapshot(root, s.state.db, s.state.snap) - - snapshot := s.state.Snapshot() - s.state.AddBalance(common.Address{}, new(uint256.Int)) - - if len(s.state.journal.dirties) != 1 { - t.Fatal("expected one dirty state object") - } - s.state.RevertToSnapshot(snapshot) - if len(s.state.journal.dirties) != 0 { - t.Fatal("expected no dirty state object") - } -} - -// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy. -// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512 -func TestCopyOfCopy(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - addr := common.HexToAddress("aaaa") - state.SetBalance(addr, uint256.NewInt(42)) - - if got := state.Copy().GetBalance(addr).Uint64(); got != 42 { - t.Fatalf("1st copy fail, expected 42, got %v", got) - } - if got := state.Copy().Copy().GetBalance(addr).Uint64(); got != 42 { - t.Fatalf("2nd copy fail, expected 42, got %v", got) - } -} - -// Tests a regression where committing a copy lost some internal meta information, -// leading to corrupted subsequent copies. -// -// See https://github.com/ethereum/go-ethereum/issues/20106. -func TestCopyCommitCopy(t *testing.T) { - tdb := NewDatabase(rawdb.NewMemoryDatabase()) - state, _ := New(types.EmptyRootHash, tdb, nil) - - // Create an account and check if the retrieved balance is correct - addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") - skey := common.HexToHash("aaa") - sval := common.HexToHash("bbb") - - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie - - if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) - } - if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := state.GetState(addr, skey); val != sval { - t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{}) - } - // Copy the non-committed state database and check pre/post commit balance - copyOne := state.Copy() - if balance := copyOne.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("first copy pre-commit balance mismatch: have %v, want %v", balance, 42) - } - if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("first copy pre-commit code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := copyOne.GetState(addr, skey); val != sval { - t.Fatalf("first copy pre-commit non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := copyOne.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("first copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{}) - } - // Copy the copy and check the balance once more - copyTwo := copyOne.Copy() - if balance := copyTwo.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("second copy balance mismatch: have %v, want %v", balance, 42) - } - if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("second copy code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := copyTwo.GetState(addr, skey); val != sval { - t.Fatalf("second copy non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := copyTwo.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("second copy committed storage slot mismatch: have %x, want %x", val, sval) - } - // Commit state, ensure states can be loaded from disk - root, _ := state.Commit(0, false) - state, _ = New(root, tdb, nil) - if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("state post-commit balance mismatch: have %v, want %v", balance, 42) - } - if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("state post-commit code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := state.GetState(addr, skey); val != sval { - t.Fatalf("state post-commit non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := state.GetCommittedState(addr, skey); val != sval { - t.Fatalf("state post-commit committed storage slot mismatch: have %x, want %x", val, sval) - } -} - -// Tests a regression where committing a copy lost some internal meta information, -// leading to corrupted subsequent copies. -// -// See https://github.com/ethereum/go-ethereum/issues/20106. -func TestCopyCopyCommitCopy(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - - // Create an account and check if the retrieved balance is correct - addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") - skey := common.HexToHash("aaa") - sval := common.HexToHash("bbb") - - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie - - if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) - } - if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := state.GetState(addr, skey); val != sval { - t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{}) - } - // Copy the non-committed state database and check pre/post commit balance - copyOne := state.Copy() - if balance := copyOne.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("first copy balance mismatch: have %v, want %v", balance, 42) - } - if code := copyOne.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("first copy code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := copyOne.GetState(addr, skey); val != sval { - t.Fatalf("first copy non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := copyOne.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("first copy committed storage slot mismatch: have %x, want %x", val, common.Hash{}) - } - // Copy the copy and check the balance once more - copyTwo := copyOne.Copy() - if balance := copyTwo.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("second copy pre-commit balance mismatch: have %v, want %v", balance, 42) - } - if code := copyTwo.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("second copy pre-commit code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := copyTwo.GetState(addr, skey); val != sval { - t.Fatalf("second copy pre-commit non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := copyTwo.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("second copy pre-commit committed storage slot mismatch: have %x, want %x", val, common.Hash{}) - } - // Copy the copy-copy and check the balance once more - copyThree := copyTwo.Copy() - if balance := copyThree.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("third copy balance mismatch: have %v, want %v", balance, 42) - } - if code := copyThree.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("third copy code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := copyThree.GetState(addr, skey); val != sval { - t.Fatalf("third copy non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := copyThree.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("third copy committed storage slot mismatch: have %x, want %x", val, sval) - } -} - -// TestCommitCopy tests the copy from a committed state is not functional. -func TestCommitCopy(t *testing.T) { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - - // Create an account and check if the retrieved balance is correct - addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") - skey := common.HexToHash("aaa") - sval := common.HexToHash("bbb") - - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie - - if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { - t.Fatalf("initial balance mismatch: have %v, want %v", balance, 42) - } - if code := state.GetCode(addr); !bytes.Equal(code, []byte("hello")) { - t.Fatalf("initial code mismatch: have %x, want %x", code, []byte("hello")) - } - if val := state.GetState(addr, skey); val != sval { - t.Fatalf("initial non-committed storage slot mismatch: have %x, want %x", val, sval) - } - if val := state.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("initial committed storage slot mismatch: have %x, want %x", val, common.Hash{}) - } - // Copy the committed state database, the copied one is not functional. - state.Commit(0, true) - copied := state.Copy() - if balance := copied.GetBalance(addr); balance.Cmp(uint256.NewInt(0)) != 0 { - t.Fatalf("unexpected balance: have %v", balance) - } - if code := copied.GetCode(addr); code != nil { - t.Fatalf("unexpected code: have %x", code) - } - if val := copied.GetState(addr, skey); val != (common.Hash{}) { - t.Fatalf("unexpected storage slot: have %x", val) - } - if val := copied.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("unexpected storage slot: have %x", val) - } - if !errors.Is(copied.Error(), trie.ErrCommitted) { - t.Fatalf("unexpected state error, %v", copied.Error()) - } -} - -// TestDeleteCreateRevert tests a weird state transition corner case that we hit -// while changing the internals of StateDB. The workflow is that a contract is -// self-destructed, then in a follow-up transaction (but same block) it's created -// again and the transaction reverted. -// -// The original StateDB implementation flushed dirty objects to the tries after -// each transaction, so this works ok. The rework accumulated writes in memory -// first, but the journal wiped the entire state object on create-revert. -func TestDeleteCreateRevert(t *testing.T) { - // Create an initial state with a single contract - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - - addr := common.BytesToAddress([]byte("so")) - state.SetBalance(addr, uint256.NewInt(1)) - - root, _ := state.Commit(0, false) - state, _ = NewWithSnapshot(root, state.db, state.snap) - - // Simulate self-destructing in one transaction, then create-reverting in another - state.SelfDestruct(addr) - state.Finalise(true) - - id := state.Snapshot() - state.SetBalance(addr, uint256.NewInt(2)) - state.RevertToSnapshot(id) - - // Commit the entire state and make sure we don't crash and have the correct state - root, _ = state.Commit(0, true) - state, _ = NewWithSnapshot(root, state.db, state.snap) - - if state.getStateObject(addr) != nil { - t.Fatalf("self-destructed contract came alive") - } -} - -// TestMissingTrieNodes tests that if the StateDB fails to load parts of the trie, -// the Commit operation fails with an error -// If we are missing trie nodes, we should not continue writing to the trie -func TestMissingTrieNodes(t *testing.T) { - testMissingTrieNodes(t, rawdb.HashScheme) - testMissingTrieNodes(t, rawdb.PathScheme) -} - -func testMissingTrieNodes(t *testing.T, scheme string) { - // Create an initial state with a few accounts - var ( - tdb *triedb.Database - memDb = rawdb.NewMemoryDatabase() - ) - if scheme == rawdb.PathScheme { - tdb = triedb.NewDatabase(memDb, &triedb.Config{PathDB: &pathdb.Config{ - CleanCacheSize: 0, - DirtyCacheSize: 0, - }}) // disable caching - } else { - tdb = triedb.NewDatabase(memDb, &triedb.Config{HashDB: &hashdb.Config{ - CleanCacheSize: 0, - }}) // disable caching - } - db := NewDatabaseWithNodeDB(memDb, tdb) - - var root common.Hash - state, _ := New(types.EmptyRootHash, db, nil) - addr := common.BytesToAddress([]byte("so")) - { - state.SetBalance(addr, uint256.NewInt(1)) - state.SetCode(addr, []byte{1, 2, 3}) - a2 := common.BytesToAddress([]byte("another")) - state.SetBalance(a2, uint256.NewInt(100)) - state.SetCode(a2, []byte{1, 2, 4}) - root, _ = state.Commit(0, false) - t.Logf("root: %x", root) - // force-flush - tdb.Commit(root, false) - } - // Create a new state on the old root - state, _ = New(root, db, nil) - // Now we clear out the memdb - it := memDb.NewIterator(nil, nil) - for it.Next() { - k := it.Key() - // Leave the root intact - if !bytes.Equal(k, root[:]) { - t.Logf("key: %x", k) - memDb.Delete(k) - } - } - balance := state.GetBalance(addr) - // The removed elem should lead to it returning zero balance - if exp, got := uint64(0), balance.Uint64(); got != exp { - t.Errorf("expected %d, got %d", exp, got) - } - // Modify the state - state.SetBalance(addr, uint256.NewInt(2)) - root, err := state.Commit(0, false) - if err == nil { - t.Fatalf("expected error, got root :%x", root) - } -} - -func TestStateDBAccessList(t *testing.T) { - // Some helpers - addr := func(a string) common.Address { - return common.HexToAddress(a) - } - slot := func(a string) common.Hash { - return common.HexToHash(a) - } - - memDb := rawdb.NewMemoryDatabase() - db := NewDatabase(memDb) - state, _ := New(types.EmptyRootHash, db, nil) - state.accessList = newAccessList() - - verifyAddrs := func(astrings ...string) { - t.Helper() - // convert to common.Address form - var addresses []common.Address - var addressMap = make(map[common.Address]struct{}) - for _, astring := range astrings { - address := addr(astring) - addresses = append(addresses, address) - addressMap[address] = struct{}{} - } - // Check that the given addresses are in the access list - for _, address := range addresses { - if !state.AddressInAccessList(address) { - t.Fatalf("expected %x to be in access list", address) - } - } - // Check that only the expected addresses are present in the access list - for address := range state.accessList.addresses { - if _, exist := addressMap[address]; !exist { - t.Fatalf("extra address %x in access list", address) - } - } - } - verifySlots := func(addrString string, slotStrings ...string) { - if !state.AddressInAccessList(addr(addrString)) { - t.Fatalf("scope missing address/slots %v", addrString) - } - var address = addr(addrString) - // convert to common.Hash form - var slots []common.Hash - var slotMap = make(map[common.Hash]struct{}) - for _, slotString := range slotStrings { - s := slot(slotString) - slots = append(slots, s) - slotMap[s] = struct{}{} - } - // Check that the expected items are in the access list - for i, s := range slots { - if _, slotPresent := state.SlotInAccessList(address, s); !slotPresent { - t.Fatalf("input %d: scope missing slot %v (address %v)", i, s, addrString) - } - } - // Check that no extra elements are in the access list - index := state.accessList.addresses[address] - if index >= 0 { - stateSlots := state.accessList.slots[index] - for s := range stateSlots { - if _, slotPresent := slotMap[s]; !slotPresent { - t.Fatalf("scope has extra slot %v (address %v)", s, addrString) - } - } - } - } - - state.AddAddressToAccessList(addr("aa")) // 1 - state.AddSlotToAccessList(addr("bb"), slot("01")) // 2,3 - state.AddSlotToAccessList(addr("bb"), slot("02")) // 4 - verifyAddrs("aa", "bb") - verifySlots("bb", "01", "02") - - // Make a copy - stateCopy1 := state.Copy() - if exp, got := 4, state.journal.length(); exp != got { - t.Fatalf("journal length mismatch: have %d, want %d", got, exp) - } - - // same again, should cause no journal entries - state.AddSlotToAccessList(addr("bb"), slot("01")) - state.AddSlotToAccessList(addr("bb"), slot("02")) - state.AddAddressToAccessList(addr("aa")) - if exp, got := 4, state.journal.length(); exp != got { - t.Fatalf("journal length mismatch: have %d, want %d", got, exp) - } - // some new ones - state.AddSlotToAccessList(addr("bb"), slot("03")) // 5 - state.AddSlotToAccessList(addr("aa"), slot("01")) // 6 - state.AddSlotToAccessList(addr("cc"), slot("01")) // 7,8 - state.AddAddressToAccessList(addr("cc")) - if exp, got := 8, state.journal.length(); exp != got { - t.Fatalf("journal length mismatch: have %d, want %d", got, exp) - } - - verifyAddrs("aa", "bb", "cc") - verifySlots("aa", "01") - verifySlots("bb", "01", "02", "03") - verifySlots("cc", "01") - - // now start rolling back changes - state.journal.revert(state, 7) - if _, ok := state.SlotInAccessList(addr("cc"), slot("01")); ok { - t.Fatalf("slot present, expected missing") - } - verifyAddrs("aa", "bb", "cc") - verifySlots("aa", "01") - verifySlots("bb", "01", "02", "03") - - state.journal.revert(state, 6) - if state.AddressInAccessList(addr("cc")) { - t.Fatalf("addr present, expected missing") - } - verifyAddrs("aa", "bb") - verifySlots("aa", "01") - verifySlots("bb", "01", "02", "03") - - state.journal.revert(state, 5) - if _, ok := state.SlotInAccessList(addr("aa"), slot("01")); ok { - t.Fatalf("slot present, expected missing") - } - verifyAddrs("aa", "bb") - verifySlots("bb", "01", "02", "03") - - state.journal.revert(state, 4) - if _, ok := state.SlotInAccessList(addr("bb"), slot("03")); ok { - t.Fatalf("slot present, expected missing") - } - verifyAddrs("aa", "bb") - verifySlots("bb", "01", "02") - - state.journal.revert(state, 3) - if _, ok := state.SlotInAccessList(addr("bb"), slot("02")); ok { - t.Fatalf("slot present, expected missing") - } - verifyAddrs("aa", "bb") - verifySlots("bb", "01") - - state.journal.revert(state, 2) - if _, ok := state.SlotInAccessList(addr("bb"), slot("01")); ok { - t.Fatalf("slot present, expected missing") - } - verifyAddrs("aa", "bb") - - state.journal.revert(state, 1) - if state.AddressInAccessList(addr("bb")) { - t.Fatalf("addr present, expected missing") - } - verifyAddrs("aa") - - state.journal.revert(state, 0) - if state.AddressInAccessList(addr("aa")) { - t.Fatalf("addr present, expected missing") - } - if got, exp := len(state.accessList.addresses), 0; got != exp { - t.Fatalf("expected empty, got %d", got) - } - if got, exp := len(state.accessList.slots), 0; got != exp { - t.Fatalf("expected empty, got %d", got) - } - // Check the copy - // Make a copy - state = stateCopy1 - verifyAddrs("aa", "bb") - verifySlots("bb", "01", "02") - if got, exp := len(state.accessList.addresses), 2; got != exp { - t.Fatalf("expected empty, got %d", got) - } - if got, exp := len(state.accessList.slots), 1; got != exp { - t.Fatalf("expected empty, got %d", got) - } -} - -func TestMultiCoinOperations(t *testing.T) { - s := newStateEnv() - addr := common.Address{1} - assetID := common.Hash{2} - - s.state.getOrNewStateObject(addr) - root, _ := s.state.Commit(0, false) - s.state, _ = NewWithSnapshot(root, s.state.db, s.state.snap) - - s.state.AddBalance(addr, new(uint256.Int)) - - balance := s.state.GetBalanceMultiCoin(addr, assetID) - if balance.Cmp(big.NewInt(0)) != 0 { - t.Fatal("expected zero multicoin balance") - } - - s.state.SetBalanceMultiCoin(addr, assetID, big.NewInt(10)) - s.state.SubBalanceMultiCoin(addr, assetID, big.NewInt(5)) - s.state.AddBalanceMultiCoin(addr, assetID, big.NewInt(3)) - - balance = s.state.GetBalanceMultiCoin(addr, assetID) - if balance.Cmp(big.NewInt(8)) != 0 { - t.Fatal("expected multicoin balance to be 8") - } -} - -func TestMultiCoinSnapshot(t *testing.T) { - db := rawdb.NewMemoryDatabase() - sdb := NewDatabase(db) - - // Create empty snapshot.Tree and StateDB - root := common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - // Use the root as both the stateRoot and blockHash for this test. - snapTree := snapshot.NewTestTree(db, root, root) - - addr := common.Address{1} - assetID1 := common.Hash{1} - assetID2 := common.Hash{2} - - var stateDB *StateDB - assertBalances := func(regular, multicoin1, multicoin2 int64) { - balance := stateDB.GetBalance(addr) - if balance.Cmp(uint256.NewInt(uint64(regular))) != 0 { - t.Fatal("incorrect non-multicoin balance") - } - balanceBig := stateDB.GetBalanceMultiCoin(addr, assetID1) - if balanceBig.Cmp(big.NewInt(multicoin1)) != 0 { - t.Fatal("incorrect multicoin1 balance") - } - balanceBig = stateDB.GetBalanceMultiCoin(addr, assetID2) - if balanceBig.Cmp(big.NewInt(multicoin2)) != 0 { - t.Fatal("incorrect multicoin2 balance") - } - } - - // Create new state - stateDB, _ = New(root, sdb, snapTree) - assertBalances(0, 0, 0) - - stateDB.AddBalance(addr, uint256.NewInt(10)) - assertBalances(10, 0, 0) - - // Commit and get the new root - root, _ = stateDB.Commit(0, false) - assertBalances(10, 0, 0) - - // Create a new state from the latest root, add a multicoin balance, and - // commit it to the tree. - stateDB, _ = New(root, sdb, snapTree) - stateDB.AddBalanceMultiCoin(addr, assetID1, big.NewInt(10)) - root, _ = stateDB.Commit(0, false) - assertBalances(10, 10, 0) - - // Add more layers than the cap and ensure the balances and layers are correct - for i := 0; i < 256; i++ { - stateDB, _ = New(root, sdb, snapTree) - stateDB.AddBalanceMultiCoin(addr, assetID1, big.NewInt(1)) - stateDB.AddBalanceMultiCoin(addr, assetID2, big.NewInt(2)) - root, _ = stateDB.Commit(0, false) - } - assertBalances(10, 266, 512) - - // Do one more add, including the regular balance which is now in the - // collapsed snapshot - stateDB, _ = New(root, sdb, snapTree) - stateDB.AddBalance(addr, uint256.NewInt(1)) - stateDB.AddBalanceMultiCoin(addr, assetID1, big.NewInt(1)) - root, _ = stateDB.Commit(0, false) - stateDB, _ = New(root, sdb, snapTree) - assertBalances(11, 267, 512) -} - -func TestGenerateMultiCoinAccounts(t *testing.T) { - var ( - diskdb = rawdb.NewMemoryDatabase() - database = NewDatabase(diskdb) - - addr = common.BytesToAddress([]byte("addr1")) - addrHash = crypto.Keccak256Hash(addr[:]) - - assetID = common.BytesToHash([]byte("coin1")) - assetBalance = big.NewInt(10) - ) - - stateDB, err := New(common.Hash{}, database, nil) - if err != nil { - t.Fatal(err) - } - stateDB.SetBalanceMultiCoin(addr, assetID, assetBalance) - root, err := stateDB.Commit(0, false) - if err != nil { - t.Fatal(err) - } - - triedb := database.TrieDB() - if err := triedb.Commit(root, true); err != nil { - t.Fatal(err) - } - // Build snapshot from scratch - snapConfig := snapshot.Config{ - CacheSize: 16, - AsyncBuild: false, - NoBuild: false, - SkipVerify: true, - } - snaps, err := snapshot.New(snapConfig, diskdb, triedb, common.Hash{}, root) - if err != nil { - t.Error("Unexpected error while rebuilding snapshot:", err) - } - - // Get latest snapshot and make sure it has the correct account and storage - snap := snaps.Snapshot(root) - snapAccount, err := snap.Account(addrHash) - if err != nil { - t.Fatal(err) - } - if !snapAccount.IsMultiCoin { - t.Fatalf("Expected SnapAccount to return IsMultiCoin: true, found: %v", snapAccount.IsMultiCoin) - } - - NormalizeCoinID(&assetID) - assetHash := crypto.Keccak256Hash(assetID.Bytes()) - storageBytes, err := snap.Storage(addrHash, assetHash) - if err != nil { - t.Fatal(err) - } - - actualAssetBalance := new(big.Int).SetBytes(storageBytes) - if actualAssetBalance.Cmp(assetBalance) != 0 { - t.Fatalf("Expected asset balance: %v, found %v", assetBalance, actualAssetBalance) - } -} - -// Tests that account and storage tries are flushed in the correct order and that -// no data loss occurs. -func TestFlushOrderDataLoss(t *testing.T) { - // Create a state trie with many accounts and slots - var ( - memdb = rawdb.NewMemoryDatabase() - triedb = triedb.NewDatabase(memdb, nil) - statedb = NewDatabaseWithNodeDB(memdb, triedb) - state, _ = New(types.EmptyRootHash, statedb, nil) - ) - for a := byte(0); a < 10; a++ { - state.CreateAccount(common.Address{a}) - for s := byte(0); s < 10; s++ { - state.SetState(common.Address{a}, common.Hash{a, s}, common.Hash{a, s}) - } - } - root, err := state.Commit(0, false) - if err != nil { - t.Fatalf("failed to commit state trie: %v", err) - } - triedb.Reference(root, common.Hash{}) - if err := triedb.Cap(1024); err != nil { - t.Fatalf("failed to cap trie dirty cache: %v", err) - } - if err := triedb.Commit(root, false); err != nil { - t.Fatalf("failed to commit state trie: %v", err) - } - // Reopen the state trie from flushed disk and verify it - state, err = New(root, NewDatabase(memdb), nil) - if err != nil { - t.Fatalf("failed to reopen state trie: %v", err) - } - for a := byte(0); a < 10; a++ { - for s := byte(0); s < 10; s++ { - if have := state.GetState(common.Address{a}, common.Hash{a, s}); have != (common.Hash{a, s}) { - t.Errorf("account %d: slot %d: state mismatch: have %x, want %x", a, s, have, common.Hash{a, s}) - } - } - } -} - -func TestStateDBTransientStorage(t *testing.T) { - memDb := rawdb.NewMemoryDatabase() - db := NewDatabase(memDb) - state, _ := New(types.EmptyRootHash, db, nil) - - key := common.Hash{0x01} - value := common.Hash{0x02} - addr := common.Address{} - - state.SetTransientState(addr, key, value) - if exp, got := 1, state.journal.length(); exp != got { - t.Fatalf("journal length mismatch: have %d, want %d", got, exp) - } - // the retrieved value should equal what was set - if got := state.GetTransientState(addr, key); got != value { - t.Fatalf("transient storage mismatch: have %x, want %x", got, value) - } - - // revert the transient state being set and then check that the - // value is now the empty hash - state.journal.revert(state, 0) - if got, exp := state.GetTransientState(addr, key), (common.Hash{}); exp != got { - t.Fatalf("transient storage mismatch: have %x, want %x", got, exp) - } - - // set transient state and then copy the statedb and ensure that - // the transient state is copied - state.SetTransientState(addr, key, value) - cpy := state.Copy() - if got := cpy.GetTransientState(addr, key); got != value { - t.Fatalf("transient storage mismatch: have %x, want %x", got, value) - } -} - -func TestResetObject(t *testing.T) { - var ( - disk = rawdb.NewMemoryDatabase() - tdb = triedb.NewDatabase(disk, nil) - db = NewDatabaseWithNodeDB(disk, tdb) - snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, common.Hash{}, types.EmptyRootHash) - state, _ = New(types.EmptyRootHash, db, snaps) - addr = common.HexToAddress("0x1") - slotA = common.HexToHash("0x1") - slotB = common.HexToHash("0x2") - ) - // Initialize account with balance and storage in first transaction. - state.SetBalance(addr, uint256.NewInt(1)) - state.SetState(addr, slotA, common.BytesToHash([]byte{0x1})) - state.IntermediateRoot(true) - - // Reset account and mutate balance and storages - state.CreateAccount(addr) - state.SetBalance(addr, uint256.NewInt(2)) - state.SetState(addr, slotB, common.BytesToHash([]byte{0x2})) - root, _ := state.CommitWithSnap(0, true, snaps, common.Hash{}, common.Hash{}) - - // Ensure the original account is wiped properly - snap := snaps.Snapshot(root) - slot, _ := snap.Storage(crypto.Keccak256Hash(addr.Bytes()), crypto.Keccak256Hash(slotA.Bytes())) - if len(slot) != 0 { - t.Fatalf("Unexpected storage slot") - } - slot, _ = snap.Storage(crypto.Keccak256Hash(addr.Bytes()), crypto.Keccak256Hash(slotB.Bytes())) - if !bytes.Equal(slot, []byte{0x2}) { - t.Fatalf("Unexpected storage slot value %v", slot) - } -} - -func TestDeleteStorage(t *testing.T) { - var ( - disk = rawdb.NewMemoryDatabase() - tdb = triedb.NewDatabase(disk, nil) - db = NewDatabaseWithNodeDB(disk, tdb) - snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, common.Hash{}, types.EmptyRootHash) - state, _ = New(types.EmptyRootHash, db, snaps) - addr = common.HexToAddress("0x1") - ) - // Initialize account and populate storage - state.SetBalance(addr, uint256.NewInt(1)) - state.CreateAccount(addr) - for i := 0; i < 1000; i++ { - slot := common.Hash(uint256.NewInt(uint64(i)).Bytes32()) - value := common.Hash(uint256.NewInt(uint64(10 * i)).Bytes32()) - state.SetState(addr, slot, value) - } - root, _ := state.CommitWithSnap(0, true, snaps, common.Hash{}, common.Hash{}) - // Init phase done, create two states, one with snap and one without - fastState, _ := New(root, db, snaps) - slowState, _ := New(root, db, nil) - - obj := fastState.getOrNewStateObject(addr) - storageRoot := obj.data.Root - - _, _, fastNodes, err := fastState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot) - if err != nil { - t.Fatal(err) - } - - _, _, slowNodes, err := slowState.deleteStorage(addr, crypto.Keccak256Hash(addr[:]), storageRoot) - if err != nil { - t.Fatal(err) - } - check := func(set *trienode.NodeSet) string { - var a []string - set.ForEachWithOrder(func(path string, n *trienode.Node) { - if n.Hash != (common.Hash{}) { - t.Fatal("delete should have empty hashes") - } - if len(n.Blob) != 0 { - t.Fatal("delete should have have empty blobs") - } - a = append(a, fmt.Sprintf("%x", path)) - }) - return strings.Join(a, ",") - } - slowRes := check(slowNodes) - fastRes := check(fastNodes) - if slowRes != fastRes { - t.Fatalf("difference found:\nfast: %v\nslow: %v\n", fastRes, slowRes) - } -} diff --git a/core/state/sync_test.go b/core/state/sync_test.go deleted file mode 100644 index 17444dfe89..0000000000 --- a/core/state/sync_test.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "math/big" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/triedb" - "github.com/ava-labs/coreth/triedb/hashdb" - "github.com/ava-labs/coreth/triedb/pathdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/holiman/uint256" -) - -// testAccount is the data associated with an account used by the state tests. -type testAccount struct { - address common.Address - balance *big.Int - nonce uint64 - code []byte -} - -// makeTestState create a sample test state to test node-wise reconstruction. -func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, common.Hash, []*testAccount) { - // Create an empty state - config := &triedb.Config{Preimages: true} - if scheme == rawdb.PathScheme { - config.PathDB = pathdb.Defaults - } else { - config.HashDB = hashdb.Defaults - } - db := rawdb.NewMemoryDatabase() - nodeDb := triedb.NewDatabase(db, config) - sdb := NewDatabaseWithNodeDB(db, nodeDb) - state, _ := New(types.EmptyRootHash, sdb, nil) - - // Fill it with some arbitrary data - var accounts []*testAccount - for i := byte(0); i < 96; i++ { - obj := state.getOrNewStateObject(common.BytesToAddress([]byte{i})) - acc := &testAccount{address: common.BytesToAddress([]byte{i})} - - obj.AddBalance(uint256.NewInt(uint64(11 * i))) - acc.balance = big.NewInt(int64(11 * i)) - - obj.SetNonce(uint64(42 * i)) - acc.nonce = uint64(42 * i) - - if i%3 == 0 { - obj.SetCode(crypto.Keccak256Hash([]byte{i, i, i, i, i}), []byte{i, i, i, i, i}) - acc.code = []byte{i, i, i, i, i} - } - if i%5 == 0 { - for j := byte(0); j < 5; j++ { - hash := crypto.Keccak256Hash([]byte{i, i, i, i, i, j, j}) - obj.SetState(hash, hash) - } - } - accounts = append(accounts, acc) - } - root, _ := state.Commit(0, false) - - // Return the generated state - return db, sdb, nodeDb, root, accounts -} diff --git a/core/state/transient_storage.go b/core/state/transient_storage.go deleted file mode 100644 index b5ee4f461e..0000000000 --- a/core/state/transient_storage.go +++ /dev/null @@ -1,65 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "github.com/ethereum/go-ethereum/common" -) - -// transientStorage is a representation of EIP-1153 "Transient Storage". -type transientStorage map[common.Address]Storage - -// newTransientStorage creates a new instance of a transientStorage. -func newTransientStorage() transientStorage { - return make(transientStorage) -} - -// Set sets the transient-storage `value` for `key` at the given `addr`. -func (t transientStorage) Set(addr common.Address, key, value common.Hash) { - if _, ok := t[addr]; !ok { - t[addr] = make(Storage) - } - t[addr][key] = value -} - -// Get gets the transient storage for `key` at the given `addr`. -func (t transientStorage) Get(addr common.Address, key common.Hash) common.Hash { - val, ok := t[addr] - if !ok { - return common.Hash{} - } - return val[key] -} - -// Copy does a deep copy of the transientStorage -func (t transientStorage) Copy() transientStorage { - storage := make(transientStorage) - for key, value := range t { - storage[key] = value.Copy() - } - return storage -} diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go deleted file mode 100644 index b82edf5be7..0000000000 --- a/core/state/trie_prefetcher.go +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "sync" - - "github.com/ava-labs/coreth/libevm/options" - "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" -) - -var ( - // triePrefetchMetricsPrefix is the prefix under which to publish the metrics. - triePrefetchMetricsPrefix = "trie/prefetch/" -) - -// triePrefetcher is an active prefetcher, which receives accounts or storage -// items and does trie-loading of them. The goal is to get as much useful content -// into the caches as possible. -// -// Note, the prefetcher's API is not thread safe. -type triePrefetcher struct { - db Database // Database to fetch trie nodes through - root common.Hash // Root hash of the account trie for metrics - fetches map[string]Trie // Partially or fully fetched tries. Only populated for inactive copies. - fetchers map[string]*subfetcher // Subfetchers for each trie - - deliveryMissMeter metrics.Meter - accountLoadMeter metrics.Meter - accountDupMeter metrics.Meter - accountSkipMeter metrics.Meter - accountWasteMeter metrics.Meter - storageLoadMeter metrics.Meter - storageDupMeter metrics.Meter - storageSkipMeter metrics.Meter - storageWasteMeter metrics.Meter - - options []PrefetcherOption -} - -func newTriePrefetcher(db Database, root common.Hash, namespace string, opts ...PrefetcherOption) *triePrefetcher { - prefix := triePrefetchMetricsPrefix + namespace - p := &triePrefetcher{ - db: db, - root: root, - fetchers: make(map[string]*subfetcher), // Active prefetchers use the fetchers map - - deliveryMissMeter: metrics.GetOrRegisterMeter(prefix+"/deliverymiss", nil), - accountLoadMeter: metrics.GetOrRegisterMeter(prefix+"/account/load", nil), - accountDupMeter: metrics.GetOrRegisterMeter(prefix+"/account/dup", nil), - accountSkipMeter: metrics.GetOrRegisterMeter(prefix+"/account/skip", nil), - accountWasteMeter: metrics.GetOrRegisterMeter(prefix+"/account/waste", nil), - storageLoadMeter: metrics.GetOrRegisterMeter(prefix+"/storage/load", nil), - storageDupMeter: metrics.GetOrRegisterMeter(prefix+"/storage/dup", nil), - storageSkipMeter: metrics.GetOrRegisterMeter(prefix+"/storage/skip", nil), - storageWasteMeter: metrics.GetOrRegisterMeter(prefix+"/storage/waste", nil), - - options: opts, - } - return p -} - -// close iterates over all the subfetchers, aborts any that were left spinning -// and reports the stats to the metrics subsystem. -func (p *triePrefetcher) close() { - for _, fetcher := range p.fetchers { - fetcher.abort() // safe to do multiple times - - if metrics.Enabled { - if fetcher.root == p.root { - p.accountLoadMeter.Mark(int64(len(fetcher.seen))) - p.accountDupMeter.Mark(int64(fetcher.dups)) - p.accountSkipMeter.Mark(int64(len(fetcher.tasks))) - - for _, key := range fetcher.used { - delete(fetcher.seen, string(key)) - } - p.accountWasteMeter.Mark(int64(len(fetcher.seen))) - } else { - p.storageLoadMeter.Mark(int64(len(fetcher.seen))) - p.storageDupMeter.Mark(int64(fetcher.dups)) - p.storageSkipMeter.Mark(int64(len(fetcher.tasks))) - - for _, key := range fetcher.used { - delete(fetcher.seen, string(key)) - } - p.storageWasteMeter.Mark(int64(len(fetcher.seen))) - } - } - } - p.releaseWorkerPools() - // Clear out all fetchers (will crash on a second call, deliberate) - p.fetchers = nil -} - -// copy creates a deep-but-inactive copy of the trie prefetcher. Any trie data -// already loaded will be copied over, but no goroutines will be started. This -// is mostly used in the miner which creates a copy of it's actively mutated -// state to be sealed while it may further mutate the state. -func (p *triePrefetcher) copy() *triePrefetcher { - copy := &triePrefetcher{ - db: p.db, - root: p.root, - fetches: make(map[string]Trie), // Active prefetchers use the fetches map - - deliveryMissMeter: p.deliveryMissMeter, - accountLoadMeter: p.accountLoadMeter, - accountDupMeter: p.accountDupMeter, - accountSkipMeter: p.accountSkipMeter, - accountWasteMeter: p.accountWasteMeter, - storageLoadMeter: p.storageLoadMeter, - storageDupMeter: p.storageDupMeter, - storageSkipMeter: p.storageSkipMeter, - storageWasteMeter: p.storageWasteMeter, - - options: p.options, - } - // If the prefetcher is already a copy, duplicate the data - if p.fetches != nil { - for root, fetch := range p.fetches { - if fetch == nil { - continue - } - copy.fetches[root] = p.db.CopyTrie(fetch) - } - return copy - } - // Otherwise we're copying an active fetcher, retrieve the current states - for id, fetcher := range p.fetchers { - copy.fetches[id] = fetcher.peek() - } - return copy -} - -// prefetch schedules a batch of trie items to prefetch. -func (p *triePrefetcher) prefetch(owner common.Hash, root common.Hash, addr common.Address, keys [][]byte) { - // If the prefetcher is an inactive one, bail out - if p.fetches != nil { - return - } - // Active fetcher, schedule the retrievals - id := p.trieID(owner, root) - fetcher := p.fetchers[id] - if fetcher == nil { - fetcher = newSubfetcher(p.db, p.root, owner, root, addr, p.options...) - p.fetchers[id] = fetcher - } - fetcher.schedule(keys) -} - -// trie returns the trie matching the root hash, or nil if the prefetcher doesn't -// have it. -func (p *triePrefetcher) trie(owner common.Hash, root common.Hash) Trie { - // If the prefetcher is inactive, return from existing deep copies - id := p.trieID(owner, root) - if p.fetches != nil { - trie := p.fetches[id] - if trie == nil { - p.deliveryMissMeter.Mark(1) - return nil - } - return p.db.CopyTrie(trie) - } - // Otherwise the prefetcher is active, bail if no trie was prefetched for this root - fetcher := p.fetchers[id] - if fetcher == nil { - p.deliveryMissMeter.Mark(1) - return nil - } - // Interrupt the prefetcher if it's by any chance still running and return - // a copy of any pre-loaded trie. - fetcher.abort() // safe to do multiple times - - trie := fetcher.peek() - if trie == nil { - p.deliveryMissMeter.Mark(1) - return nil - } - return trie -} - -// used marks a batch of state items used to allow creating statistics as to -// how useful or wasteful the prefetcher is. -func (p *triePrefetcher) used(owner common.Hash, root common.Hash, used [][]byte) { - if fetcher := p.fetchers[p.trieID(owner, root)]; fetcher != nil { - fetcher.used = used - } -} - -// trieID returns an unique trie identifier consists the trie owner and root hash. -func (p *triePrefetcher) trieID(owner common.Hash, root common.Hash) string { - trieID := make([]byte, common.HashLength*2) - copy(trieID, owner.Bytes()) - copy(trieID[common.HashLength:], root.Bytes()) - return string(trieID) -} - -// subfetcher is a trie fetcher goroutine responsible for pulling entries for a -// single trie. It is spawned when a new root is encountered and lives until the -// main prefetcher is paused and either all requested items are processed or if -// the trie being worked on is retrieved from the prefetcher. -type subfetcher struct { - db Database // Database to load trie nodes through - state common.Hash // Root hash of the state to prefetch - owner common.Hash // Owner of the trie, usually account hash - root common.Hash // Root hash of the trie to prefetch - addr common.Address // Address of the account that the trie belongs to - trie Trie // Trie being populated with nodes - - tasks [][]byte // Items queued up for retrieval - lock sync.Mutex // Lock protecting the task queue - - wake chan struct{} // Wake channel if a new task is scheduled - stop chan struct{} // Channel to interrupt processing - term chan struct{} // Channel to signal interruption - copy chan chan Trie // Channel to request a copy of the current trie - - seen map[string]struct{} // Tracks the entries already loaded - dups int // Number of duplicate preload tasks - used [][]byte // Tracks the entries used in the end - - pool *subfetcherPool -} - -// newSubfetcher creates a goroutine to prefetch state items belonging to a -// particular root hash. -func newSubfetcher(db Database, state common.Hash, owner common.Hash, root common.Hash, addr common.Address, opts ...PrefetcherOption) *subfetcher { - sf := &subfetcher{ - db: db, - state: state, - owner: owner, - root: root, - addr: addr, - wake: make(chan struct{}, 1), - stop: make(chan struct{}), - term: make(chan struct{}), - copy: make(chan chan Trie), - seen: make(map[string]struct{}), - } - options.As[prefetcherConfig](opts...).applyTo(sf) - go sf.loop() - return sf -} - -// schedule adds a batch of trie keys to the queue to prefetch. -func (sf *subfetcher) schedule(keys [][]byte) { - // Append the tasks to the current queue - sf.lock.Lock() - sf.tasks = append(sf.tasks, keys...) - sf.lock.Unlock() - - // Notify the prefetcher, it's fine if it's already terminated - select { - case sf.wake <- struct{}{}: - default: - } -} - -// peek tries to retrieve a deep copy of the fetcher's trie in whatever form it -// is currently. -func (sf *subfetcher) peek() Trie { - ch := make(chan Trie) - select { - case sf.copy <- ch: - // Subfetcher still alive, return copy from it - return <-ch - - case <-sf.term: - // Subfetcher already terminated, return a copy directly - if sf.trie == nil { - return nil - } - return sf.db.CopyTrie(sf.trie) - } -} - -// abort interrupts the subfetcher immediately. It is safe to call abort multiple -// times but it is not thread safe. -func (sf *subfetcher) abort() { - select { - case <-sf.stop: - default: - close(sf.stop) - } - <-sf.term -} - -// loop waits for new tasks to be scheduled and keeps loading them until it runs -// out of tasks or its underlying trie is retrieved for committing. -func (sf *subfetcher) loop() { - // No matter how the loop stops, signal anyone waiting that it's terminated - defer func() { - sf.pool.wait() - close(sf.term) - }() - - // Start by opening the trie and stop processing if it fails - if sf.owner == (common.Hash{}) { - trie, err := sf.db.OpenTrie(sf.root) - if err != nil { - log.Warn("Trie prefetcher failed opening trie", "root", sf.root, "err", err) - return - } - sf.trie = trie - } else { - // The trie argument can be nil as verkle doesn't support prefetching - // yet. TODO FIX IT(rjl493456442), otherwise code will panic here. - trie, err := sf.db.OpenStorageTrie(sf.state, sf.addr, sf.root, nil) - if err != nil { - log.Warn("Trie prefetcher failed opening trie", "root", sf.root, "err", err) - return - } - sf.trie = trie - } - // Trie opened successfully, keep prefetching items - for { - select { - case <-sf.wake: - // Subfetcher was woken up, retrieve any tasks to avoid spinning the lock - sf.lock.Lock() - tasks := sf.tasks - sf.tasks = nil - sf.lock.Unlock() - - // Prefetch any tasks until the loop is interrupted - for _, task := range tasks { - select { - case ch := <-sf.copy: - // Somebody wants a copy of the current trie, grant them - ch <- sf.db.CopyTrie(sf.trie) - - default: - // No termination request yet, prefetch the next entry - if _, ok := sf.seen[string(task)]; ok { - sf.dups++ - } else { - if len(task) == common.AddressLength { - sf.pool.GetAccount(common.BytesToAddress(task)) - } else { - sf.pool.GetStorage(sf.addr, task) - } - sf.seen[string(task)] = struct{}{} - } - } - } - - case ch := <-sf.copy: - // Somebody wants a copy of the current trie, grant them - ch <- sf.db.CopyTrie(sf.trie) - - case <-sf.stop: - //libevm:start - // - // This is copied, with alteration, from ethereum/go-ethereum#29519 - // and can be deleted once we update to include that change. - - // Termination is requested, abort if no more tasks are pending. If - // there are some, exhaust them first. - sf.lock.Lock() - done := len(sf.tasks) == 0 - sf.lock.Unlock() - - if done { - return - } - - select { - case sf.wake <- struct{}{}: - default: - } - //libevm:end - } - } -} diff --git a/core/state/trie_prefetcher.libevm.go b/core/state/trie_prefetcher.libevm.go deleted file mode 100644 index 7a2a35ddc8..0000000000 --- a/core/state/trie_prefetcher.libevm.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2024 the libevm authors. -// -// The libevm additions to go-ethereum are free software: you can redistribute -// them and/or modify them under the terms of the GNU Lesser General Public License -// as published by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// The libevm additions are distributed in the hope that they will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -// General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see -// . - -package state - -import ( - "github.com/ava-labs/coreth/libevm/options" - "github.com/ava-labs/coreth/libevm/sync" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" -) - -// A PrefetcherOption configures behaviour of trie prefetching. -type PrefetcherOption = options.Option[prefetcherConfig] - -type prefetcherConfig struct { - newWorkers func() WorkerPool -} - -// A WorkerPool executes functions asynchronously. Done() is called to signal -// that the pool is no longer needed and that Execute() is guaranteed to not be -// called again. -type WorkerPool interface { - Execute(func()) - Done() -} - -// WithWorkerPools configures trie prefetching to execute asynchronously. The -// provided constructor is called once for each trie being fetched but it MAY -// return the same pool. -func WithWorkerPools(ctor func() WorkerPool) PrefetcherOption { - return options.Func[prefetcherConfig](func(c *prefetcherConfig) { - c.newWorkers = ctor - }) -} - -type subfetcherPool struct { - workers WorkerPool - tries sync.Pool[Trie] - wg sync.WaitGroup -} - -// applyTo configures the [subfetcher] to use a [WorkerPool] if one was provided -// with a [PrefetcherOption]. -func (c *prefetcherConfig) applyTo(sf *subfetcher) { - sf.pool = &subfetcherPool{ - tries: sync.Pool[Trie]{ - // Although the workers may be shared between all subfetchers, each - // MUST have its own Trie pool. - New: func() Trie { - return sf.db.CopyTrie(sf.trie) - }, - }, - } - if c.newWorkers != nil { - sf.pool.workers = c.newWorkers() - } -} - -// releaseWorkerPools calls Done() on all [WorkerPool]s. This MUST only be -// called after [subfetcher.abort] returns on ALL fetchers as a pool is allowed -// to be shared between them. This is because we guarantee in the public API -// that no further calls will be made to Execute() after a call to Done(). -func (p *triePrefetcher) releaseWorkerPools() { - for _, f := range p.fetchers { - if w := f.pool.workers; w != nil { - w.Done() - } - } -} - -func (p *subfetcherPool) wait() { - p.wg.Wait() -} - -// execute runs the provided function with a copy of the subfetcher's Trie. -// Copies are stored in a [sync.Pool] to reduce creation overhead. If p was -// configured with a [WorkerPool] then it is used for function execution, -// otherwise `fn` is just called directly. -func (p *subfetcherPool) execute(fn func(Trie)) { - p.wg.Add(1) - do := func() { - t := p.tries.Get() - fn(t) - p.tries.Put(t) - p.wg.Done() - } - - if w := p.workers; w != nil { - w.Execute(do) - } else { - do() - } -} - -// GetAccount optimistically pre-fetches an account, dropping the returned value -// and logging errors. See [subfetcherPool.execute] re worker pools. -func (p *subfetcherPool) GetAccount(addr common.Address) { - p.execute(func(t Trie) { - if _, err := t.GetAccount(addr); err != nil { - log.Error("account prefetching failed", "address", addr, "err", err) - } - }) -} - -// GetStorage is the storage equivalent of [subfetcherPool.GetAccount]. -func (p *subfetcherPool) GetStorage(addr common.Address, key []byte) { - p.execute(func(t Trie) { - if _, err := t.GetStorage(addr, key); err != nil { - log.Error("storage prefetching failed", "address", addr, "key", key, "err", err) - } - }) -} diff --git a/core/state/trie_prefetcher_extra_test.go b/core/state/trie_prefetcher_extra_test.go deleted file mode 100644 index 968f9916fc..0000000000 --- a/core/state/trie_prefetcher_extra_test.go +++ /dev/null @@ -1,189 +0,0 @@ -// (c) 2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package state - -import ( - "crypto/rand" - "encoding/binary" - "fmt" - "os" - "path" - "strconv" - "testing" - - "github.com/ava-labs/avalanchego/database" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/triedb" - "github.com/ava-labs/coreth/triedb/hashdb" - "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/stretchr/testify/require" -) - -const namespace = "chain" - -// BenchmarkPrefetcherDatabase benchmarks the performance of the trie -// prefetcher. By default, a state with 100k storage keys is created and stored -// in a temporary directory. Setting the TEST_DB_KVS and TEST_DB_DIR environment -// variables modifies the defaults. The benchmark measures the time to update -// the trie after 100, 200, and 500 storage slot updates per iteration, -// simulating a block with that number of storage slot updates. For performance -// reasons, when making changes involving the trie prefetcher, this benchmark -// should be run against a state including around 100m storage entries. -func BenchmarkPrefetcherDatabase(b *testing.B) { - require := require.New(b) - - dir := b.TempDir() - if env := os.Getenv("TEST_DB_DIR"); env != "" { - dir = env - } - wantKVs := 100_000 - if env := os.Getenv("TEST_DB_KVS"); env != "" { - var err error - wantKVs, err = strconv.Atoi(env) - require.NoError(err) - } - - levelDB, err := rawdb.NewLevelDBDatabase(path.Join(dir, "level.db"), 0, 0, "", false) - require.NoError(err) - - root := types.EmptyRootHash - count := uint64(0) - block := uint64(0) - - rootKey := []byte("root") - countKey := []byte("count") - blockKey := []byte("block") - got, err := levelDB.Get(rootKey) - if err == nil { // on success - root = common.BytesToHash(got) - } - got, err = levelDB.Get(countKey) - if err == nil { // on success - count = binary.BigEndian.Uint64(got) - } - got, err = levelDB.Get(blockKey) - if err == nil { // on success - block = binary.BigEndian.Uint64(got) - } - - // Make a trie on the levelDB - address1 := common.Address{42} - address2 := common.Address{43} - addBlock := func(db Database, snaps *snapshot.Tree, kvsPerBlock int, prefetchers int) { - _, root, err = addKVs(db, snaps, address1, address2, root, block, kvsPerBlock, prefetchers) - require.NoError(err) - count += uint64(kvsPerBlock) - block++ - } - - lastCommit := block - commit := func(levelDB ethdb.Database, snaps *snapshot.Tree, db Database) { - require.NoError(db.TrieDB().Commit(root, false)) - - for i := lastCommit + 1; i <= block; i++ { - require.NoError(snaps.Flatten(fakeHash(i))) - } - lastCommit = block - - // update the tracking keys - require.NoError(levelDB.Put(rootKey, root.Bytes())) - require.NoError(database.PutUInt64(levelDB, blockKey, block)) - require.NoError(database.PutUInt64(levelDB, countKey, count)) - } - - tdbConfig := &triedb.Config{ - HashDB: &hashdb.Config{ - CleanCacheSize: 3 * 1024 * 1024 * 1024, - }, - } - db := NewDatabaseWithConfig(levelDB, tdbConfig) - snaps := snapshot.NewTestTree(levelDB, fakeHash(block), root) - for count < uint64(wantKVs) { - previous := root - addBlock(db, snaps, 100_000, 0) // Note this updates root and count - b.Logf("Root: %v, kvs: %d, block: %d", root, count, block) - - // Commit every 10 blocks or on the last iteration - if block%10 == 0 || count >= uint64(wantKVs) { - commit(levelDB, snaps, db) - b.Logf("Root: %v, kvs: %d, block: %d (committed)", root, count, block) - } - if previous != root { - require.NoError(db.TrieDB().Dereference(previous)) - } else { - b.Fatal("root did not change") - } - } - require.NoError(levelDB.Close()) - b.Logf("Starting benchmarks") - b.Logf("Root: %v, kvs: %d, block: %d", root, count, block) - for _, updates := range []int{100, 200, 500} { - for _, prefetchers := range []int{0, 1, 4, 16} { - b.Run(fmt.Sprintf("updates_%d_prefetchers_%d", updates, prefetchers), func(b *testing.B) { - startRoot, startBlock, startCount := root, block, count - defer func() { root, block, count = startRoot, startBlock, startCount }() - - levelDB, err := rawdb.NewLevelDBDatabase(path.Join(dir, "level.db"), 0, 0, "", false) - require.NoError(err) - snaps := snapshot.NewTestTree(levelDB, fakeHash(block), root) - db := NewDatabaseWithConfig(levelDB, tdbConfig) - getMetric := func(metric string) int64 { - meter := metrics.GetOrRegisterMeter(triePrefetchMetricsPrefix+namespace+"/storage/"+metric, nil) - return meter.Snapshot().Count() - } - startLoads := getMetric("load") - for i := 0; i < b.N; i++ { - addBlock(db, snaps, updates, prefetchers) - } - require.NoError(levelDB.Close()) - b.ReportMetric(float64(getMetric("load")-startLoads)/float64(b.N), "loads") - }) - } - } -} - -func fakeHash(block uint64) common.Hash { - return common.BytesToHash(binary.BigEndian.AppendUint64(nil, block)) -} - -// addKVs adds count random key-value pairs to the state trie of address1 and -// address2 (each count/2) and returns the new state db and root. -func addKVs( - db Database, snaps *snapshot.Tree, - address1, address2 common.Address, root common.Hash, block uint64, - count int, prefetchers int, -) (*StateDB, common.Hash, error) { - snap := snaps.Snapshot(root) - if snap == nil { - return nil, common.Hash{}, fmt.Errorf("snapshot not found") - } - statedb, err := NewWithSnapshot(root, db, snap) - if err != nil { - return nil, common.Hash{}, fmt.Errorf("creating state with snapshot: %w", err) - } - if prefetchers > 0 { - statedb.StartPrefetcher(namespace, WithConcurrentWorkers(prefetchers)) - defer statedb.StopPrefetcher() - } - for _, address := range []common.Address{address1, address2} { - statedb.SetNonce(address, 1) - for i := 0; i < count/2; i++ { - key := make([]byte, 32) - value := make([]byte, 32) - rand.Read(key) - rand.Read(value) - - statedb.SetState(address, common.BytesToHash(key), common.BytesToHash(value)) - } - } - root, err = statedb.CommitWithSnap(block+1, true, snaps, fakeHash(block+1), fakeHash(block)) - if err != nil { - return nil, common.Hash{}, fmt.Errorf("committing with snap: %w", err) - } - return statedb, root, nil -} diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go deleted file mode 100644 index 4c1ff686e3..0000000000 --- a/core/state/trie_prefetcher_test.go +++ /dev/null @@ -1,124 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package state - -import ( - "math/big" - "testing" - "time" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -const maxConcurrency = 4 - -func filledStateDB() *StateDB { - state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil) - - // Create an account and check if the retrieved balance is correct - addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe") - skey := common.HexToHash("aaa") - sval := common.HexToHash("bbb") - - state.SetBalance(addr, uint256.NewInt(42)) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata - state.SetState(addr, skey, sval) // Change the storage trie - for i := 0; i < 100; i++ { - sk := common.BigToHash(big.NewInt(int64(i))) - state.SetState(addr, sk, sk) // Change the storage trie - } - return state -} - -func TestCopyAndClose(t *testing.T) { - db := filledStateDB() - prefetcher := newTriePrefetcher(db.db, db.originalRoot, "", WithConcurrentWorkers(maxConcurrency)) - skey := common.HexToHash("aaa") - prefetcher.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - prefetcher.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - time.Sleep(1 * time.Second) - a := prefetcher.trie(common.Hash{}, db.originalRoot) - prefetcher.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - b := prefetcher.trie(common.Hash{}, db.originalRoot) - cpy := prefetcher.copy() - cpy.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - cpy.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - c := cpy.trie(common.Hash{}, db.originalRoot) - prefetcher.close() - cpy2 := cpy.copy() - cpy2.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - d := cpy2.trie(common.Hash{}, db.originalRoot) - cpy.close() - cpy2.close() - if a.Hash() != b.Hash() || a.Hash() != c.Hash() || a.Hash() != d.Hash() { - t.Fatalf("Invalid trie, hashes should be equal: %v %v %v %v", a.Hash(), b.Hash(), c.Hash(), d.Hash()) - } -} - -func TestUseAfterClose(t *testing.T) { - db := filledStateDB() - prefetcher := newTriePrefetcher(db.db, db.originalRoot, "", WithConcurrentWorkers(maxConcurrency)) - skey := common.HexToHash("aaa") - prefetcher.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - a := prefetcher.trie(common.Hash{}, db.originalRoot) - prefetcher.close() - b := prefetcher.trie(common.Hash{}, db.originalRoot) - if a == nil { - t.Fatal("Prefetching before close should not return nil") - } - if b != nil { - t.Fatal("Trie after close should return nil") - } -} - -func TestCopyClose(t *testing.T) { - db := filledStateDB() - prefetcher := newTriePrefetcher(db.db, db.originalRoot, "", WithConcurrentWorkers(maxConcurrency)) - skey := common.HexToHash("aaa") - prefetcher.prefetch(common.Hash{}, db.originalRoot, common.Address{}, [][]byte{skey.Bytes()}) - cpy := prefetcher.copy() - a := prefetcher.trie(common.Hash{}, db.originalRoot) - b := cpy.trie(common.Hash{}, db.originalRoot) - prefetcher.close() - c := prefetcher.trie(common.Hash{}, db.originalRoot) - d := cpy.trie(common.Hash{}, db.originalRoot) - if a == nil { - t.Fatal("Prefetching before close should not return nil") - } - if b == nil { - t.Fatal("Copy trie should return nil") - } - if c != nil { - t.Fatal("Trie after close should return nil") - } - if d == nil { - t.Fatal("Copy trie should not return nil") - } -} diff --git a/core/state_manager.go b/core/state_manager.go index 59447055b7..805c3ffd38 100644 --- a/core/state_manager.go +++ b/core/state_manager.go @@ -31,9 +31,9 @@ import ( "math/rand" "time" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" ) func init() { diff --git a/core/state_manager_test.go b/core/state_manager_test.go index cddb0a6dd8..13033358fc 100644 --- a/core/state_manager_test.go +++ b/core/state_manager_test.go @@ -7,9 +7,9 @@ import ( "math/big" "testing" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/assert" ) diff --git a/core/state_processor.go b/core/state_processor.go index af5b888686..4b00c141db 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -27,20 +27,17 @@ package core import ( - "encoding/json" "fmt" "math/big" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/precompile/contract" - "github.com/ava-labs/coreth/precompile/modules" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" ) // StateProcessor is a basic Processor, which takes care of transitioning @@ -81,7 +78,8 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state ) // Configure any upgrades that should go into effect during this block. - err := ApplyUpgrades(p.config, &parent.Time, block, statedb) + blockContext := NewBlockContext(block.Number(), block.Time()) + err := ApplyUpgrades(p.config, &parent.Time, blockContext, statedb) if err != nil { log.Error("failed to configure precompiles processing block", "hash", block.Hash(), "number", block.NumberU64(), "timestamp", block.Time(), "err", err) return nil, nil, 0, err @@ -92,6 +90,7 @@ func (p *StateProcessor) Process(block *types.Block, parent *types.Header, state vmenv = vm.NewEVM(context, vm.TxContext{}, statedb, p.config, cfg) signer = types.MakeSigner(p.config, header.Number, header.Time) ) + if beaconRoot := block.BeaconRoot(); beaconRoot != nil { ProcessBeaconBlockRoot(*beaconRoot, vmenv, statedb) } @@ -201,62 +200,3 @@ func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *stat _, _, _ = vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560) statedb.Finalise(true) } - -// ApplyPrecompileActivations checks if any of the precompiles specified by the chain config are enabled or disabled by the block -// transition from [parentTimestamp] to the timestamp set in [blockContext]. If this is the case, it calls [Configure] -// to apply the necessary state transitions for the upgrade. -// This function is called within genesis setup to configure the starting state for precompiles enabled at genesis. -// In block processing and building, ApplyUpgrades is called instead which also applies state upgrades. -func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { - blockTimestamp := blockContext.Timestamp() - // Note: RegisteredModules returns precompiles sorted by module addresses. - // This ensures that the order we call Configure for each precompile is consistent. - // This ensures even if precompiles read/write state other than their own they will observe - // an identical global state in a deterministic order when they are configured. - for _, module := range modules.RegisteredModules() { - for _, activatingConfig := range c.GetActivatingPrecompileConfigs(module.Address, parentTimestamp, blockTimestamp, c.PrecompileUpgrades) { - // If this transition activates the upgrade, configure the stateful precompile. - // (or deconfigure it if it is being disabled.) - if activatingConfig.IsDisabled() { - log.Info("Disabling precompile", "name", module.ConfigKey) - statedb.SelfDestruct(module.Address) - // Calling Finalise here effectively commits Suicide call and wipes the contract state. - // This enables re-configuration of the same contract state in the same block. - // Without an immediate Finalise call after the Suicide, a reconfigured precompiled state can be wiped out - // since Suicide will be committed after the reconfiguration. - statedb.Finalise(true) - } else { - var printIntf interface{} - marshalled, err := json.Marshal(activatingConfig) - if err == nil { - printIntf = string(marshalled) - } else { - printIntf = activatingConfig - } - - log.Info("Activating new precompile", "name", module.ConfigKey, "config", printIntf) - // Set the nonce of the precompile's address (as is done when a contract is created) to ensure - // that it is marked as non-empty and will not be cleaned up when the statedb is finalized. - statedb.SetNonce(module.Address, 1) - // Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile - // can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure - // that it does not attempt to invoke a non-existent contract. - statedb.SetCode(module.Address, []byte{0x1}) - if err := module.Configure(c, activatingConfig, statedb, blockContext); err != nil { - return fmt.Errorf("could not configure precompile, name: %s, reason: %w", module.ConfigKey, err) - } - } - } - } - return nil -} - -// ApplyUpgrades checks if any of the precompile or state upgrades specified by the chain config are activated by the block -// transition from [parentTimestamp] to the timestamp set in [header]. If this is the case, it calls [Configure] -// to apply the necessary state transitions for the upgrade. -// This function is called: -// - in block processing to update the state when processing a block. -// - in the miner to apply the state upgrades when producing a block. -func ApplyUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { - return ApplyPrecompileActivations(c, parentTimestamp, blockContext, statedb) -} diff --git a/core/state_processor_ext.go b/core/state_processor_ext.go new file mode 100644 index 0000000000..9145111aa6 --- /dev/null +++ b/core/state_processor_ext.go @@ -0,0 +1,99 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package core + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ava-labs/coreth/core/extstate" + "github.com/ava-labs/coreth/core/state" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/precompile/contract" + "github.com/ava-labs/coreth/precompile/modules" + "github.com/ava-labs/libevm/log" +) + +// ApplyPrecompileActivations checks if any of the precompiles specified by the chain config are enabled or disabled by the block +// transition from `parentTimestamp` to the timestamp set in `blockContext`. If this is the case, it calls [modules.Module]'s Configure +// to apply the necessary state transitions for the upgrade. +// This function is called within genesis setup to configure the starting state for precompiles enabled at genesis. +// In block processing and building, [ApplyUpgrades] is called instead which also applies state upgrades. +func ApplyPrecompileActivations(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { + blockTimestamp := blockContext.Timestamp() + // Note: [modules.RegisteredModules] returns precompiles sorted by module addresses. + // This ensures: + // - the order we call [modules.Module]'s Configure for each precompile is consistent + // - even if precompiles read/write state other than their own they will observe + // an identical global state in a deterministic order when they are configured. + extra := params.GetExtra(c) + for _, module := range modules.RegisteredModules() { + for _, activatingConfig := range extra.GetActivatingPrecompileConfigs(module.Address, parentTimestamp, blockTimestamp, extra.PrecompileUpgrades) { + // If this transition activates the upgrade, configure the stateful precompile. + // (or deconfigure it if it is being disabled.) + if activatingConfig.IsDisabled() { + log.Info("Disabling precompile", "name", module.ConfigKey) + statedb.SelfDestruct(module.Address) + // Calling [state.StateDB]'s Finalise here effectively commits the SelfDestruct call and wipes the contract state. + // This enables re-configuration of the same contract state in the same block. + // Without an immediate Finalise call after the SelfDestruct, a reconfigured precompiled state can be wiped out + // since SelfDestruct will be committed after the reconfiguration. + statedb.Finalise(true) + continue + } + var printIntf interface{} + marshalled, err := json.Marshal(activatingConfig) + if err == nil { + printIntf = string(marshalled) + } else { + printIntf = activatingConfig + } + + log.Info("Activating new precompile", "name", module.ConfigKey, "config", printIntf) + // Set the nonce of the precompile's address (as is done when a contract is created) to ensure + // that it is marked as non-empty and will not be cleaned up when the statedb is finalized. + statedb.SetNonce(module.Address, 1) + // Set the code of the precompile's address to a non-zero length byte slice to ensure that the precompile + // can be called from within Solidity contracts. Solidity adds a check before invoking a contract to ensure + // that it does not attempt to invoke a non-existent contract. + statedb.SetCode(module.Address, []byte{0x1}) + extstatedb := extstate.New(statedb) + if err := module.Configure(params.GetExtra(c), activatingConfig, extstatedb, blockContext); err != nil { + return fmt.Errorf("could not configure precompile, name: %s, reason: %w", module.ConfigKey, err) + } + } + } + return nil +} + +// ApplyUpgrades checks if any of the precompile or state upgrades specified by the chain config are activated by the block +// transition from [parentTimestamp] to the timestamp set in [header]. If this is the case, it calls [Configure] +// to apply the necessary state transitions for the upgrade. +// This function is called: +// - in block processing to update the state when processing a block. +// - in the miner to apply the state upgrades when producing a block. +func ApplyUpgrades(c *params.ChainConfig, parentTimestamp *uint64, blockContext contract.ConfigurationBlockContext, statedb *state.StateDB) error { + return ApplyPrecompileActivations(c, parentTimestamp, blockContext, statedb) +} + +// BlockContext implements [contract.ConfigurationBlockContext]. +type BlockContext struct { + number *big.Int + timestamp uint64 +} + +// NewBlockContext creates a [BlockContext] using the block number +// and block timestamp provided. This function is usually necessary to convert +// a `*types.Block` to be passed as a [contract.ConfigurationBlockContext] +// to [ApplyUpgrades]. +func NewBlockContext(number *big.Int, timestamp uint64) *BlockContext { + return &BlockContext{ + number: number, + timestamp: timestamp, + } +} + +func (bc *BlockContext) Number() *big.Int { return bc.number } +func (bc *BlockContext) Timestamp() uint64 { return bc.timestamp } diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 1254b3d22f..705a6dfe7e 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -35,19 +35,21 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/consensus/misc/eip4844" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" - "github.com/ava-labs/coreth/trie" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/trie" "github.com/holiman/uint256" "golang.org/x/crypto/sha3" ) @@ -118,7 +120,7 @@ func TestStateProcessorErrors(t *testing.T) { Config: config, Timestamp: uint64(upgrade.InitiallyActiveTime.Unix()), Alloc: types.GenesisAlloc{ - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.GenesisAccount{ + common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.Account{ Balance: big.NewInt(4000000000000000000), // 4 ether Nonce: 0, }, @@ -264,24 +266,28 @@ func TestStateProcessorErrors(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() gspec = &Genesis{ - Config: ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), + Config: params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), }, - }, + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + }, + }, + ), Alloc: types.GenesisAlloc{ - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.GenesisAccount{ + common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.Account{ Balance: big.NewInt(1000000000000000000), // 1 ether Nonce: 0, }, @@ -320,7 +326,7 @@ func TestStateProcessorErrors(t *testing.T) { gspec = &Genesis{ Config: config, Alloc: types.GenesisAlloc{ - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.GenesisAccount{ + common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.Account{ Balance: big.NewInt(1000000000000000000), // 1 ether Nonce: 0, Code: common.FromHex("0xB0B0FACE"), @@ -361,8 +367,9 @@ func TestStateProcessorErrors(t *testing.T) { func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Transactions, config *params.ChainConfig) *types.Block { fakeChainReader := newChainMaker(nil, config, engine) time := parent.Time() + 10 - gasLimit, _ := customheader.GasLimit(config, parent.Header(), time) - baseFee, _ := customheader.BaseFee(config, parent.Header(), time) + configExtra := params.GetExtra(config) + gasLimit, _ := customheader.GasLimit(configExtra, parent.Header(), time) + baseFee, _ := customheader.BaseFee(configExtra, parent.Header(), time) header := &types.Header{ ParentHash: parent.Hash(), Coinbase: parent.Coinbase(), @@ -378,9 +385,10 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr UncleHash: types.EmptyUncleHash, BaseFee: baseFee, } - if config.IsApricotPhase4(header.Time) { - header.BlockGasCost = big.NewInt(0) - header.ExtDataGasUsed = big.NewInt(0) + if configExtra.IsApricotPhase4(header.Time) { + headerExtra := customtypes.GetHeaderExtra(header) + headerExtra.BlockGasCost = big.NewInt(0) + headerExtra.ExtDataGasUsed = big.NewInt(0) } var receipts []*types.Receipt // The post-state result doesn't need to be correct (this is a bad block), but we do need something there @@ -399,7 +407,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr cumulativeGas += tx.Gas() nBlobs += len(tx.BlobHashes()) } - header.Extra, _ = customheader.ExtraPrefix(config, parent.Header(), header, nil) + header.Extra, _ = customheader.ExtraPrefix(configExtra, parent.Header(), header, nil) header.Root = common.BytesToHash(hasher.Sum(nil)) if config.IsCancun(header.Number, header.Time) { var pExcess, pUsed = uint64(0), uint64(0) diff --git a/core/state_transition.go b/core/state_transition.go index df8c679a7a..31c5758454 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -31,14 +31,13 @@ import ( "math" "math/big" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/utils" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - cmath "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ava-labs/libevm/common" + cmath "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto/kzg4844" "github.com/holiman/uint256" ) @@ -72,7 +71,7 @@ func (result *ExecutionResult) Return() []byte { // Revert returns the concrete revert reason if the execution is aborted by `REVERT` // opcode. Note the reason can be nil if no data supplied with revert opcode. func (result *ExecutionResult) Revert() []byte { - if result.Err != vmerrs.ErrExecutionReverted { + if result.Err != vm.ErrExecutionReverted { return nil } return common.CopyBytes(result.ReturnData) @@ -113,7 +112,7 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b } gas += z * params.TxDataZeroGas - if isContractCreation && rules.IsDurango { + if isContractCreation && params.GetRulesExtra(rules).IsDurango { lenWords := toWordSize(dataLen) if (math.MaxUint64-gas)/params.InitCodeWordGas < lenWords { return 0, ErrGasUintOverflow @@ -138,7 +137,8 @@ func IntrinsicGas(data []byte, accessList types.AccessList, isContractCreation b func accessListGas(rules params.Rules, accessList types.AccessList) (uint64, error) { var gas uint64 - if !rules.PredicatersExist() { + rulesExtra := params.GetRulesExtra(rules) + if !rulesExtra.PredicatersExist() { gas += uint64(len(accessList)) * params.TxAccessListAddressGas gas += uint64(accessList.StorageKeys()) * params.TxAccessListStorageKeyGas return gas, nil @@ -146,7 +146,7 @@ func accessListGas(rules params.Rules, accessList types.AccessList) (uint64, err for _, accessTuple := range accessList { address := accessTuple.Address - predicaterContract, ok := rules.Predicaters[address] + predicaterContract, ok := rulesExtra.Predicaters[address] if !ok { // Previous access list gas calculation does not use safemath because an overflow would not be possible with // the size of access lists that could be included in a block and standard access list gas costs. @@ -351,13 +351,9 @@ func (st *StateTransition) preCheck() error { return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA, msg.From.Hex(), codeHash) } - // Make sure the sender is not prohibited - if vm.IsProhibited(msg.From) { - return fmt.Errorf("%w: address %v", vmerrs.ErrAddrProhibited, msg.From) - } } // Make sure that transaction gasFeeCap is greater than the baseFee (post london) - if st.evm.ChainConfig().IsApricotPhase3(st.evm.Context.Time) { + if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) { // Skip the checks if gas fields are zero and baseFee was explicitly disabled (eth_call) skipCheck := st.evm.Config.NoBaseFee && msg.GasFeeCap.BitLen() == 0 && msg.GasTipCap.BitLen() == 0 if !skipCheck { @@ -452,7 +448,8 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { var ( msg = st.msg sender = vm.AccountRef(msg.From) - rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, st.evm.Context.Time) + rules = st.evm.ChainConfig().Rules(st.evm.Context.BlockNumber, params.IsMergeTODO, st.evm.Context.Time) + rulesExtra = params.GetRulesExtra(rules) contractCreation = msg.To == nil ) @@ -476,8 +473,8 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { } // Check whether the init code size has been exceeded. - if rules.IsDurango && contractCreation && len(msg.Data) > params.MaxInitCodeSize { - return nil, fmt.Errorf("%w: code size %v limit %v", vmerrs.ErrMaxInitCodeSizeExceeded, len(msg.Data), params.MaxInitCodeSize) + if rulesExtra.IsDurango && contractCreation && len(msg.Data) > params.MaxInitCodeSize { + return nil, fmt.Errorf("%w: code size %v limit %v", vm.ErrMaxInitCodeSizeExceeded, len(msg.Data), params.MaxInitCodeSize) } // Execute the preparatory steps for state transition which includes: @@ -500,7 +497,7 @@ func (st *StateTransition) TransitionDb() (*ExecutionResult, error) { if overflow { return nil, ErrGasUintOverflow } - gasRefund := st.refundGas(rules.IsApricotPhase1) + gasRefund := st.refundGas(rulesExtra.IsApricotPhase1) fee := new(uint256.Int).SetUint64(st.gasUsed()) fee.Mul(fee, price) st.state.AddBalance(st.evm.Context.Coinbase, fee) diff --git a/core/state_transition_test.go b/core/state_transition_test.go index aaa628f814..c2fd593a0a 100644 --- a/core/state_transition_test.go +++ b/core/state_transition_test.go @@ -32,16 +32,16 @@ import ( "testing" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" + "github.com/ava-labs/coreth/nativeasset" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - ethCrypto "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" ) @@ -101,7 +101,7 @@ func executeStateTransitionTest(t *testing.T, st stateTransitionTest) { gspec = &Genesis{ Config: st.config, Alloc: types.GenesisAlloc{ - common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.GenesisAccount{ + common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7"): types.Account{ Balance: big.NewInt(2000000000000000000), // 2 ether Nonce: 0, }, @@ -138,7 +138,7 @@ func TestNativeAssetContractCall(t *testing.T) { data, err := hex.DecodeString("608060405234801561001057600080fd5b5061016e806100206000396000f3fe608060405234801561001057600080fd5b50600073010000000000000000000000000000000000000290508073ffffffffffffffffffffffffffffffffffffffff166040516020016040516020818303038152906040526040516100639190610121565b6000604051808303816000865af19150503d80600081146100a0576040519150601f19603f3d011682016040523d82523d6000602084013e6100a5565b606091505b005b600081519050919050565b600081905092915050565b60005b838110156100db5780820151818401526020810190506100c0565b838111156100ea576000848401525b50505050565b60006100fb826100a7565b61010581856100b2565b93506101158185602086016100bd565b80840191505092915050565b600061012d82846100f0565b91508190509291505056fea2646970667358221220a297c3e133143287abef22b1c1d4e45f588efc3db99a84b364560a2079876fc364736f6c634300080d0033") require.NoError(err) - contractAddr := ethCrypto.CreateAddress(testAddr, 0) + contractAddr := crypto.CreateAddress(testAddr, 0) txs := []*types.Transaction{ makeContractTx(0, common.Big0, 500_000, big.NewInt(ap0.MinGasPrice), data), makeTx(1, contractAddr, common.Big0, 100_000, big.NewInt(ap0.MinGasPrice), nil), // No input data is necessary, since this will hit the contract's fallback function. @@ -236,7 +236,7 @@ func TestNativeAssetContractConstructor(t *testing.T) { func TestNativeAssetDirectEOACall(t *testing.T) { txs := []*types.Transaction{ - makeTx(0, vm.NativeAssetCallAddr, common.Big0, 100_000, big.NewInt(ap0.MinGasPrice), nil), + makeTx(0, nativeasset.NativeAssetCallAddr, common.Big0, 100_000, big.NewInt(ap0.MinGasPrice), nil), } phase6Tests := map[string]stateTransitionTest{ diff --git a/core/test_blockchain.go b/core/test_blockchain.go index f4451774fa..a5dc5be6ce 100644 --- a/core/test_blockchain.go +++ b/core/test_blockchain.go @@ -10,14 +10,14 @@ import ( "time" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb" "github.com/holiman/uint256" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -25,7 +25,7 @@ import ( var TestCallbacks = dummy.ConsensusCallbacks{ OnExtraStateChange: func(block *types.Block, _ *types.Header, sdb *state.StateDB) (*big.Int, *big.Int, error) { - sdb.SetBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(block.Number().Int64())) + sdb.AddBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(block.Number().Int64())) return nil, nil, nil }, OnFinalizeAndAssemble: func( @@ -34,7 +34,7 @@ var TestCallbacks = dummy.ConsensusCallbacks{ sdb *state.StateDB, _ []*types.Transaction, ) ([]byte, *big.Int, *big.Int, error) { - sdb.SetBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(header.Number.Int64())) + sdb.AddBalanceMultiCoin(common.HexToAddress("0xdeadbeef"), common.HexToHash("0xdeadbeef"), big.NewInt(header.Number.Int64())) return nil, nil, nil, nil }, } diff --git a/core/txindexer.go b/core/txindexer.go index 39c5fe51b0..f7932b762f 100644 --- a/core/txindexer.go +++ b/core/txindexer.go @@ -20,9 +20,9 @@ import ( "fmt" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" ) // TxIndexProgress is the struct describing the progress for transaction indexing. diff --git a/core/txindexer_test.go b/core/txindexer_test.go index 5c212bc953..347bac340a 100644 --- a/core/txindexer_test.go +++ b/core/txindexer_test.go @@ -22,12 +22,12 @@ import ( "testing" "github.com/ava-labs/coreth/consensus/dummy" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb" "github.com/stretchr/testify/require" ) diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 9f9cd09668..b947649ccc 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -43,14 +43,14 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/header" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/rlp" "github.com/holiman/billy" "github.com/holiman/uint256" ) @@ -411,7 +411,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres p.recheck(addr, nil) } baseFee, err := header.EstimateNextBaseFee( - p.chain.Config(), + params.GetExtra(p.chain.Config()), p.head, uint64(time.Now().Unix()), ) @@ -841,7 +841,7 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) { p.limbo.finalize(p.chain.CurrentFinalBlock()) } baseFeeBig, err := header.EstimateNextBaseFee( - p.chain.Config(), + params.GetExtra(p.chain.Config()), p.head, uint64(time.Now().Unix()), ) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 7c86ae2b69..3402cdeb8e 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -41,19 +41,19 @@ import ( "github.com/ava-labs/coreth/consensus/misc/eip4844" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/ethereum/go-ethereum/ethdb/memorydb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/crypto/kzg4844" + "github.com/ava-labs/libevm/ethdb/memorydb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" "github.com/holiman/billy" "github.com/holiman/uint256" ) @@ -72,7 +72,7 @@ var testChainConfig *params.ChainConfig func init() { testChainConfig = new(params.ChainConfig) - *testChainConfig = *params.TestChainConfig + *testChainConfig = params.Copy(params.TestChainConfig) testChainConfig.CancunTime = new(uint64) *testChainConfig.CancunTime = uint64(time.Now().Unix()) @@ -115,8 +115,9 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { BaseFee: mid, Extra: make([]byte, ap3.WindowSize), } + config := params.GetExtra(bc.config) baseFee, err := header.BaseFee( - bc.config, parent, blockTime, + config, parent, blockTime, ) if err != nil { panic(err) diff --git a/core/txpool/blobpool/config.go b/core/txpool/blobpool/config.go index 5df7885fb3..d7b94535a7 100644 --- a/core/txpool/blobpool/config.go +++ b/core/txpool/blobpool/config.go @@ -27,7 +27,7 @@ package blobpool import ( - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) // Config are the configuration parameters of the blob transaction pool. diff --git a/core/txpool/blobpool/evictheap.go b/core/txpool/blobpool/evictheap.go index 0824ddf735..7c7525371c 100644 --- a/core/txpool/blobpool/evictheap.go +++ b/core/txpool/blobpool/evictheap.go @@ -32,7 +32,7 @@ import ( "math" "sort" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/holiman/uint256" ) diff --git a/core/txpool/blobpool/evictheap_test.go b/core/txpool/blobpool/evictheap_test.go index 69b02447bf..70bd772b5d 100644 --- a/core/txpool/blobpool/evictheap_test.go +++ b/core/txpool/blobpool/evictheap_test.go @@ -32,7 +32,7 @@ import ( "testing" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/holiman/uint256" ) diff --git a/core/txpool/blobpool/interface.go b/core/txpool/blobpool/interface.go index c544efa872..42cd916817 100644 --- a/core/txpool/blobpool/interface.go +++ b/core/txpool/blobpool/interface.go @@ -28,9 +28,9 @@ package blobpool import ( "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // BlockChain defines the minimal set of methods needed to back a blob pool with diff --git a/core/txpool/blobpool/limbo.go b/core/txpool/blobpool/limbo.go index 63f31031ab..bf133f7a3b 100644 --- a/core/txpool/blobpool/limbo.go +++ b/core/txpool/blobpool/limbo.go @@ -29,10 +29,10 @@ package blobpool import ( "errors" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" "github.com/holiman/billy" ) diff --git a/core/txpool/blobpool/metrics.go b/core/txpool/blobpool/metrics.go index ccd4dbb574..4763c5f6a2 100644 --- a/core/txpool/blobpool/metrics.go +++ b/core/txpool/blobpool/metrics.go @@ -26,22 +26,33 @@ package blobpool -import "github.com/ava-labs/libevm/metrics" +import ( + "github.com/ava-labs/libevm/metrics" + // Force libevm metrics of the same name to be registered first. + _ "github.com/ava-labs/libevm/core/txpool/blobpool" +) + +// ====== If resolving merge conflicts ====== +// +// All calls to metrics.NewRegistered*() for metrics also defined in libevm/core/txpool/blobpool +// have been replaced with metrics.GetOrRegister*() to get metrics already registered in +// libevm/core/txpool/blobpool or register them here otherwise. These replacements ensure the +// same metrics are shared between the two packages. var ( // datacapGauge tracks the user's configured capacity for the blob pool. It // is mostly a way to expose/debug issues. - datacapGauge = metrics.NewRegisteredGauge("blobpool/datacap", nil) + datacapGauge = metrics.GetOrRegisterGauge("blobpool/datacap", nil) // The below metrics track the per-datastore metrics for the primary blob // store and the temporary limbo store. - datausedGauge = metrics.NewRegisteredGauge("blobpool/dataused", nil) - datarealGauge = metrics.NewRegisteredGauge("blobpool/datareal", nil) - slotusedGauge = metrics.NewRegisteredGauge("blobpool/slotused", nil) + datausedGauge = metrics.GetOrRegisterGauge("blobpool/dataused", nil) + datarealGauge = metrics.GetOrRegisterGauge("blobpool/datareal", nil) + slotusedGauge = metrics.GetOrRegisterGauge("blobpool/slotused", nil) - limboDatausedGauge = metrics.NewRegisteredGauge("blobpool/limbo/dataused", nil) - limboDatarealGauge = metrics.NewRegisteredGauge("blobpool/limbo/datareal", nil) - limboSlotusedGauge = metrics.NewRegisteredGauge("blobpool/limbo/slotused", nil) + limboDatausedGauge = metrics.GetOrRegisterGauge("blobpool/limbo/dataused", nil) + limboDatarealGauge = metrics.GetOrRegisterGauge("blobpool/limbo/datareal", nil) + limboSlotusedGauge = metrics.GetOrRegisterGauge("blobpool/limbo/slotused", nil) // The below metrics track the per-shelf metrics for the primary blob store // and the temporary limbo store. @@ -60,56 +71,56 @@ var ( // // There are no oversized data in the limbo, it only contains blobs and some // constant metadata. - oversizedDatausedGauge = metrics.NewRegisteredGauge("blobpool/oversized/dataused", nil) - oversizedDatagapsGauge = metrics.NewRegisteredGauge("blobpool/oversized/datagaps", nil) - oversizedSlotusedGauge = metrics.NewRegisteredGauge("blobpool/oversized/slotused", nil) - oversizedSlotgapsGauge = metrics.NewRegisteredGauge("blobpool/oversized/slotgaps", nil) + oversizedDatausedGauge = metrics.GetOrRegisterGauge("blobpool/oversized/dataused", nil) + oversizedDatagapsGauge = metrics.GetOrRegisterGauge("blobpool/oversized/datagaps", nil) + oversizedSlotusedGauge = metrics.GetOrRegisterGauge("blobpool/oversized/slotused", nil) + oversizedSlotgapsGauge = metrics.GetOrRegisterGauge("blobpool/oversized/slotgaps", nil) // basefeeGauge and blobfeeGauge track the current network 1559 base fee and // 4844 blob fee respectively. - basefeeGauge = metrics.NewRegisteredGauge("blobpool/basefee", nil) - blobfeeGauge = metrics.NewRegisteredGauge("blobpool/blobfee", nil) + basefeeGauge = metrics.GetOrRegisterGauge("blobpool/basefee", nil) + blobfeeGauge = metrics.GetOrRegisterGauge("blobpool/blobfee", nil) // pooltipGauge is the configurable miner tip to permit a transaction into // the pool. - pooltipGauge = metrics.NewRegisteredGauge("blobpool/pooltip", nil) + pooltipGauge = metrics.GetOrRegisterGauge("blobpool/pooltip", nil) // addwait/time, resetwait/time and getwait/time track the rough health of // the pool and whether it's capable of keeping up with the load from the // network. - addwaitHist = metrics.NewRegisteredHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015)) - addtimeHist = metrics.NewRegisteredHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015)) - getwaitHist = metrics.NewRegisteredHistogram("blobpool/getwait", nil, metrics.NewExpDecaySample(1028, 0.015)) - gettimeHist = metrics.NewRegisteredHistogram("blobpool/gettime", nil, metrics.NewExpDecaySample(1028, 0.015)) - pendwaitHist = metrics.NewRegisteredHistogram("blobpool/pendwait", nil, metrics.NewExpDecaySample(1028, 0.015)) - pendtimeHist = metrics.NewRegisteredHistogram("blobpool/pendtime", nil, metrics.NewExpDecaySample(1028, 0.015)) - resetwaitHist = metrics.NewRegisteredHistogram("blobpool/resetwait", nil, metrics.NewExpDecaySample(1028, 0.015)) - resettimeHist = metrics.NewRegisteredHistogram("blobpool/resettime", nil, metrics.NewExpDecaySample(1028, 0.015)) + addwaitHist = metrics.GetOrRegisterHistogram("blobpool/addwait", nil, metrics.NewExpDecaySample(1028, 0.015)) + addtimeHist = metrics.GetOrRegisterHistogram("blobpool/addtime", nil, metrics.NewExpDecaySample(1028, 0.015)) + getwaitHist = metrics.GetOrRegisterHistogram("blobpool/getwait", nil, metrics.NewExpDecaySample(1028, 0.015)) + gettimeHist = metrics.GetOrRegisterHistogram("blobpool/gettime", nil, metrics.NewExpDecaySample(1028, 0.015)) + pendwaitHist = metrics.GetOrRegisterHistogram("blobpool/pendwait", nil, metrics.NewExpDecaySample(1028, 0.015)) + pendtimeHist = metrics.GetOrRegisterHistogram("blobpool/pendtime", nil, metrics.NewExpDecaySample(1028, 0.015)) + resetwaitHist = metrics.GetOrRegisterHistogram("blobpool/resetwait", nil, metrics.NewExpDecaySample(1028, 0.015)) + resettimeHist = metrics.GetOrRegisterHistogram("blobpool/resettime", nil, metrics.NewExpDecaySample(1028, 0.015)) // The below metrics track various cases where transactions are dropped out // of the pool. Most are exceptional, some are chain progression and some // threshold cappings. - dropInvalidMeter = metrics.NewRegisteredMeter("blobpool/drop/invalid", nil) // Invalid transaction, consensus change or bugfix, neutral-ish - dropDanglingMeter = metrics.NewRegisteredMeter("blobpool/drop/dangling", nil) // First nonce gapped, bad - dropFilledMeter = metrics.NewRegisteredMeter("blobpool/drop/filled", nil) // State full-overlap, chain progress, ok - dropOverlappedMeter = metrics.NewRegisteredMeter("blobpool/drop/overlapped", nil) // State partial-overlap, chain progress, ok - dropRepeatedMeter = metrics.NewRegisteredMeter("blobpool/drop/repeated", nil) // Repeated nonce, bad - dropGappedMeter = metrics.NewRegisteredMeter("blobpool/drop/gapped", nil) // Non-first nonce gapped, bad - dropOverdraftedMeter = metrics.NewRegisteredMeter("blobpool/drop/overdrafted", nil) // Balance exceeded, bad - dropOvercappedMeter = metrics.NewRegisteredMeter("blobpool/drop/overcapped", nil) // Per-account cap exceeded, bad - dropOverflownMeter = metrics.NewRegisteredMeter("blobpool/drop/overflown", nil) // Global disk cap exceeded, neutral-ish - dropUnderpricedMeter = metrics.NewRegisteredMeter("blobpool/drop/underpriced", nil) // Gas tip changed, neutral - dropReplacedMeter = metrics.NewRegisteredMeter("blobpool/drop/replaced", nil) // Transaction replaced, neutral + dropInvalidMeter = metrics.GetOrRegisterMeter("blobpool/drop/invalid", nil) // Invalid transaction, consensus change or bugfix, neutral-ish + dropDanglingMeter = metrics.GetOrRegisterMeter("blobpool/drop/dangling", nil) // First nonce gapped, bad + dropFilledMeter = metrics.GetOrRegisterMeter("blobpool/drop/filled", nil) // State full-overlap, chain progress, ok + dropOverlappedMeter = metrics.GetOrRegisterMeter("blobpool/drop/overlapped", nil) // State partial-overlap, chain progress, ok + dropRepeatedMeter = metrics.GetOrRegisterMeter("blobpool/drop/repeated", nil) // Repeated nonce, bad + dropGappedMeter = metrics.GetOrRegisterMeter("blobpool/drop/gapped", nil) // Non-first nonce gapped, bad + dropOverdraftedMeter = metrics.GetOrRegisterMeter("blobpool/drop/overdrafted", nil) // Balance exceeded, bad + dropOvercappedMeter = metrics.GetOrRegisterMeter("blobpool/drop/overcapped", nil) // Per-account cap exceeded, bad + dropOverflownMeter = metrics.GetOrRegisterMeter("blobpool/drop/overflown", nil) // Global disk cap exceeded, neutral-ish + dropUnderpricedMeter = metrics.GetOrRegisterMeter("blobpool/drop/underpriced", nil) // Gas tip changed, neutral + dropReplacedMeter = metrics.GetOrRegisterMeter("blobpool/drop/replaced", nil) // Transaction replaced, neutral // The below metrics track various outcomes of transactions being added to // the pool. - addInvalidMeter = metrics.NewRegisteredMeter("blobpool/add/invalid", nil) // Invalid transaction, reject, neutral - addUnderpricedMeter = metrics.NewRegisteredMeter("blobpool/add/underpriced", nil) // Gas tip too low, neutral - addStaleMeter = metrics.NewRegisteredMeter("blobpool/add/stale", nil) // Nonce already filled, reject, bad-ish - addGappedMeter = metrics.NewRegisteredMeter("blobpool/add/gapped", nil) // Nonce gapped, reject, bad-ish - addOverdraftedMeter = metrics.NewRegisteredMeter("blobpool/add/overdrafted", nil) // Balance exceeded, reject, neutral - addOvercappedMeter = metrics.NewRegisteredMeter("blobpool/add/overcapped", nil) // Per-account cap exceeded, reject, neutral - addNoreplaceMeter = metrics.NewRegisteredMeter("blobpool/add/noreplace", nil) // Replacement fees or tips too low, neutral - addNonExclusiveMeter = metrics.NewRegisteredMeter("blobpool/add/nonexclusive", nil) // Plain transaction from same account exists, reject, neutral - addValidMeter = metrics.NewRegisteredMeter("blobpool/add/valid", nil) // Valid transaction, add, neutral + addInvalidMeter = metrics.GetOrRegisterMeter("blobpool/add/invalid", nil) // Invalid transaction, reject, neutral + addUnderpricedMeter = metrics.GetOrRegisterMeter("blobpool/add/underpriced", nil) // Gas tip too low, neutral + addStaleMeter = metrics.GetOrRegisterMeter("blobpool/add/stale", nil) // Nonce already filled, reject, bad-ish + addGappedMeter = metrics.GetOrRegisterMeter("blobpool/add/gapped", nil) // Nonce gapped, reject, bad-ish + addOverdraftedMeter = metrics.GetOrRegisterMeter("blobpool/add/overdrafted", nil) // Balance exceeded, reject, neutral + addOvercappedMeter = metrics.GetOrRegisterMeter("blobpool/add/overcapped", nil) // Per-account cap exceeded, reject, neutral + addNoreplaceMeter = metrics.GetOrRegisterMeter("blobpool/add/noreplace", nil) // Replacement fees or tips too low, neutral + addNonExclusiveMeter = metrics.GetOrRegisterMeter("blobpool/add/nonexclusive", nil) // Plain transaction from same account exists, reject, neutral + addValidMeter = metrics.GetOrRegisterMeter("blobpool/add/valid", nil) // Valid transaction, add, neutral ) diff --git a/core/txpool/legacypool/journal.go b/core/txpool/legacypool/journal.go index c586cab543..cc5e900947 100644 --- a/core/txpool/legacypool/journal.go +++ b/core/txpool/legacypool/journal.go @@ -32,10 +32,10 @@ import ( "io/fs" "os" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" ) // errNoActiveJournal is returned if a transaction is attempted to be inserted diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index d3da5c300b..5515d59bc2 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -39,16 +39,19 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/prque" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/prque" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" "github.com/holiman/uint256" + + // Force libevm metrics of the same name to be registered first. + _ "github.com/ava-labs/libevm/core/txpool/legacypool" ) const ( @@ -79,42 +82,48 @@ var ( baseFeeUpdateInterval = 10 * time.Second // Time interval at which to schedule a base fee update for the tx pool after ApricotPhase3 is enabled ) +// ====== If resolving merge conflicts ====== +// +// All calls to metrics.NewRegistered*() for metrics also defined in libevm/core/txpool/legacypool +// have been replaced with metrics.GetOrRegister*() to get metrics already registered in +// libevm/core/txpool/legacypool or register them here otherwise. These replacements ensure the +// same metrics are shared between the two packages. var ( // Metrics for the pending pool - pendingDiscardMeter = metrics.NewRegisteredMeter("txpool/pending/discard", nil) - pendingReplaceMeter = metrics.NewRegisteredMeter("txpool/pending/replace", nil) - pendingRateLimitMeter = metrics.NewRegisteredMeter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting - pendingNofundsMeter = metrics.NewRegisteredMeter("txpool/pending/nofunds", nil) // Dropped due to out-of-funds + pendingDiscardMeter = metrics.GetOrRegisterMeter("txpool/pending/discard", nil) + pendingReplaceMeter = metrics.GetOrRegisterMeter("txpool/pending/replace", nil) + pendingRateLimitMeter = metrics.GetOrRegisterMeter("txpool/pending/ratelimit", nil) // Dropped due to rate limiting + pendingNofundsMeter = metrics.GetOrRegisterMeter("txpool/pending/nofunds", nil) // Dropped due to out-of-funds // Metrics for the queued pool - queuedDiscardMeter = metrics.NewRegisteredMeter("txpool/queued/discard", nil) - queuedReplaceMeter = metrics.NewRegisteredMeter("txpool/queued/replace", nil) - queuedRateLimitMeter = metrics.NewRegisteredMeter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting - queuedNofundsMeter = metrics.NewRegisteredMeter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds - queuedEvictionMeter = metrics.NewRegisteredMeter("txpool/queued/eviction", nil) // Dropped due to lifetime + queuedDiscardMeter = metrics.GetOrRegisterMeter("txpool/queued/discard", nil) + queuedReplaceMeter = metrics.GetOrRegisterMeter("txpool/queued/replace", nil) + queuedRateLimitMeter = metrics.GetOrRegisterMeter("txpool/queued/ratelimit", nil) // Dropped due to rate limiting + queuedNofundsMeter = metrics.GetOrRegisterMeter("txpool/queued/nofunds", nil) // Dropped due to out-of-funds + queuedEvictionMeter = metrics.GetOrRegisterMeter("txpool/queued/eviction", nil) // Dropped due to lifetime // General tx metrics - knownTxMeter = metrics.NewRegisteredMeter("txpool/known", nil) - validTxMeter = metrics.NewRegisteredMeter("txpool/valid", nil) - invalidTxMeter = metrics.NewRegisteredMeter("txpool/invalid", nil) - underpricedTxMeter = metrics.NewRegisteredMeter("txpool/underpriced", nil) - overflowedTxMeter = metrics.NewRegisteredMeter("txpool/overflowed", nil) + knownTxMeter = metrics.GetOrRegisterMeter("txpool/known", nil) + validTxMeter = metrics.GetOrRegisterMeter("txpool/valid", nil) + invalidTxMeter = metrics.GetOrRegisterMeter("txpool/invalid", nil) + underpricedTxMeter = metrics.GetOrRegisterMeter("txpool/underpriced", nil) + overflowedTxMeter = metrics.GetOrRegisterMeter("txpool/overflowed", nil) // throttleTxMeter counts how many transactions are rejected due to too-many-changes between // txpool reorgs. - throttleTxMeter = metrics.NewRegisteredMeter("txpool/throttle", nil) + throttleTxMeter = metrics.GetOrRegisterMeter("txpool/throttle", nil) // reorgDurationTimer measures how long time a txpool reorg takes. - reorgDurationTimer = metrics.NewRegisteredTimer("txpool/reorgtime", nil) + reorgDurationTimer = metrics.GetOrRegisterTimer("txpool/reorgtime", nil) // dropBetweenReorgHistogram counts how many drops we experience between two reorg runs. It is expected // that this number is pretty low, since txpool reorgs happen very frequently. - dropBetweenReorgHistogram = metrics.NewRegisteredHistogram("txpool/dropbetweenreorg", nil, metrics.NewExpDecaySample(1028, 0.015)) + dropBetweenReorgHistogram = metrics.GetOrRegisterHistogram("txpool/dropbetweenreorg", nil, metrics.NewExpDecaySample(1028, 0.015)) - pendingGauge = metrics.NewRegisteredGauge("txpool/pending", nil) - queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil) - localGauge = metrics.NewRegisteredGauge("txpool/local", nil) - slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil) + pendingGauge = metrics.GetOrRegisterGauge("txpool/pending", nil) + queuedGauge = metrics.GetOrRegisterGauge("txpool/queued", nil) + localGauge = metrics.GetOrRegisterGauge("txpool/local", nil) + slotsGauge = metrics.GetOrRegisterGauge("txpool/slots", nil) - reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil) + reheapTimer = metrics.GetOrRegisterTimer("txpool/reheap", nil) ) // BlockChain defines the minimal set of methods needed to back a tx pool with @@ -686,6 +695,7 @@ func (pool *LegacyPool) validateTx(tx *types.Transaction, local bool) error { State: pool.currentState, Rules: pool.chainconfig.Rules( pool.currentHead.Load().Number, + params.IsMergeTODO, pool.currentHead.Load().Time, ), MinimumFee: pool.minimumFee, @@ -1363,7 +1373,7 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest, if reset != nil { pool.demoteUnexecutables() if reset.newHead != nil { - if pool.chainconfig.IsApricotPhase3(reset.newHead.Time) { + if pool.chainconfig.IsLondon(reset.newHead.Number) { if err := pool.updateBaseFeeAt(reset.newHead); err != nil { log.Error("error at updating base fee in tx pool", "error", err) } @@ -1768,13 +1778,14 @@ func (pool *LegacyPool) demoteUnexecutables() { } func (pool *LegacyPool) startPeriodicFeeUpdate() { - if pool.chainconfig.ApricotPhase3BlockTimestamp == nil { + ap3Timestamp := params.GetExtra(pool.chainconfig).ApricotPhase3BlockTimestamp + if ap3Timestamp == nil { return } // Call updateBaseFee here to ensure that there is not a [baseFeeUpdateInterval] delay // when starting up in ApricotPhase3 before the base fee is updated. - if time.Now().After(utils.Uint64ToTime(pool.chainconfig.ApricotPhase3BlockTimestamp)) { + if time.Now().After(utils.Uint64ToTime(ap3Timestamp)) { pool.updateBaseFee() } @@ -1786,8 +1797,9 @@ func (pool *LegacyPool) periodicBaseFeeUpdate() { defer pool.wg.Done() // Sleep until its time to start the periodic base fee update or the tx pool is shutting down + ap3Time := utils.Uint64ToTime(params.GetExtra(pool.chainconfig).ApricotPhase3BlockTimestamp) select { - case <-time.After(time.Until(utils.Uint64ToTime(pool.chainconfig.ApricotPhase3BlockTimestamp))): + case <-time.After(time.Until(ap3Time)): case <-pool.generalShutdownChan: return // Return early if shutting down } @@ -1816,7 +1828,8 @@ func (pool *LegacyPool) updateBaseFee() { // assumes lock is already held func (pool *LegacyPool) updateBaseFeeAt(head *types.Header) error { - baseFeeEstimate, err := header.EstimateNextBaseFee(pool.chainconfig, head, uint64(time.Now().Unix())) + config := params.GetExtra(pool.chainconfig) + baseFeeEstimate, err := header.EstimateNextBaseFee(config, head, uint64(time.Now().Unix())) if err != nil { return err } diff --git a/core/txpool/legacypool/legacypool2_test.go b/core/txpool/legacypool/legacypool2_test.go index 566cfc820e..e478d9f554 100644 --- a/core/txpool/legacypool/legacypool2_test.go +++ b/core/txpool/legacypool/legacypool2_test.go @@ -30,12 +30,12 @@ import ( "math/big" "testing" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/event" "github.com/holiman/uint256" ) diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index a9b8ebb345..2dca13c70b 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -40,16 +40,15 @@ import ( "time" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/trie" "github.com/holiman/uint256" ) @@ -65,8 +64,8 @@ var ( func init() { cpy := *params.TestChainConfig eip1559Config = &cpy - eip1559Config.ApricotPhase2BlockTimestamp = utils.NewUint64(0) - eip1559Config.ApricotPhase3BlockTimestamp = utils.NewUint64(0) + eip1559Config.BerlinBlock = common.Big0 + eip1559Config.LondonBlock = common.Big0 } type testBlockChain struct { diff --git a/core/txpool/legacypool/list.go b/core/txpool/legacypool/list.go index 0b523c3795..89ababa830 100644 --- a/core/txpool/legacypool/list.go +++ b/core/txpool/legacypool/list.go @@ -35,8 +35,8 @@ import ( "sync/atomic" "time" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" "github.com/holiman/uint256" "golang.org/x/exp/slices" ) diff --git a/core/txpool/legacypool/list_test.go b/core/txpool/legacypool/list_test.go index 116e80a707..f0eea8c8ea 100644 --- a/core/txpool/legacypool/list_test.go +++ b/core/txpool/legacypool/list_test.go @@ -31,9 +31,9 @@ import ( "math/rand" "testing" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" "github.com/holiman/uint256" ) diff --git a/core/txpool/legacypool/noncer.go b/core/txpool/legacypool/noncer.go index dd880a6ba3..425748d6f1 100644 --- a/core/txpool/legacypool/noncer.go +++ b/core/txpool/legacypool/noncer.go @@ -30,7 +30,7 @@ import ( "sync" "github.com/ava-labs/coreth/core/state" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // noncer is a tiny virtual state database to manage the executable nonces of diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index 4ebbf97c4f..b1c3ef7556 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -31,9 +31,9 @@ import ( "time" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" "github.com/holiman/uint256" ) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 7cfa58d3ef..d99c08fb15 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -34,11 +34,11 @@ import ( "sync/atomic" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" ) var ( diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 374471e978..fabcda6bb3 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -33,12 +33,12 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto/kzg4844" + "github.com/ava-labs/libevm/log" ) var ( @@ -74,18 +74,18 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types return fmt.Errorf("%w: transaction size %v, limit %v", ErrOversizedData, tx.Size(), opts.MaxSize) } // Ensure only transactions that have been enabled are accepted - if !opts.Config.IsApricotPhase2(head.Time) && tx.Type() != types.LegacyTxType { + if !opts.Config.IsBerlin(head.Number) && tx.Type() != types.LegacyTxType { return fmt.Errorf("%w: type %d rejected, pool not yet in Berlin", core.ErrTxTypeNotSupported, tx.Type()) } - if !opts.Config.IsApricotPhase3(head.Time) && tx.Type() == types.DynamicFeeTxType { + if !opts.Config.IsLondon(head.Number) && tx.Type() == types.DynamicFeeTxType { return fmt.Errorf("%w: type %d rejected, pool not yet in London", core.ErrTxTypeNotSupported, tx.Type()) } if !opts.Config.IsCancun(head.Number, head.Time) && tx.Type() == types.BlobTxType { return fmt.Errorf("%w: type %d rejected, pool not yet in Cancun", core.ErrTxTypeNotSupported, tx.Type()) } // Check whether the init code size has been exceeded - if opts.Config.IsDurango(head.Time) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { - return fmt.Errorf("%w: code size %v, limit %v", vmerrs.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize) + if opts.Config.IsShanghai(head.Number, head.Time) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { + return fmt.Errorf("%w: code size %v, limit %v", vm.ErrMaxInitCodeSizeExceeded, len(tx.Data()), params.MaxInitCodeSize) } // Transactions can't be negative. This may never happen using RLP decoded // transactions but may occur for transactions created using the RPC. @@ -119,7 +119,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types } // Ensure the transaction has more gas than the bare minimum needed to cover // the transaction metadata - intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, opts.Config.Rules(head.Number, head.Time)) + intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, opts.Config.Rules(head.Number, params.IsMergeTODO, head.Time)) if err != nil { return err } diff --git a/core/types.go b/core/types.go index 77e6dd4d2b..dc03e7905f 100644 --- a/core/types.go +++ b/core/types.go @@ -28,8 +28,8 @@ package core import ( "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" ) // Validator is an interface which defines the standard for block validation. It diff --git a/core/types/account.go b/core/types/account.go deleted file mode 100644 index 28a663009e..0000000000 --- a/core/types/account.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2024 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "encoding/hex" - "encoding/json" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" -) - -//go:generate go run github.com/fjl/gencodec -type Account -field-override accountMarshaling -out gen_account.go -//go:generate go run github.com/fjl/gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go - -// Account represents an Ethereum account and its attached data. -// This type is used to specify accounts in the genesis block state, and -// is also useful for JSON encoding/decoding of accounts. -type Account struct { - Code []byte `json:"code,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` - Balance *big.Int `json:"balance" gencodec:"required"` - Nonce uint64 `json:"nonce,omitempty"` - - // used in tests - PrivateKey []byte `json:"secretKey,omitempty"` -} - -type accountMarshaling struct { - Code hexutil.Bytes - Balance *math.HexOrDecimal256 - Nonce math.HexOrDecimal64 - Storage map[storageJSON]storageJSON - PrivateKey hexutil.Bytes -} - -// storageJSON represents a 256 bit byte array, but allows less than 256 bits when -// unmarshaling from hex. -type storageJSON common.Hash - -func (h *storageJSON) UnmarshalText(text []byte) error { - text = bytes.TrimPrefix(text, []byte("0x")) - if len(text) > 64 { - return fmt.Errorf("too many hex characters in storage key/value %q", text) - } - offset := len(h) - len(text)/2 // pad on the left - if _, err := hex.Decode(h[offset:], text); err != nil { - return fmt.Errorf("invalid hex storage key/value %q", text) - } - return nil -} - -func (h storageJSON) MarshalText() ([]byte, error) { - return hexutil.Bytes(h[:]).MarshalText() -} - -// GenesisAlloc specifies the initial state of a genesis block. -type GenesisAlloc map[common.Address]GenesisAccount - -func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { - m := make(map[common.UnprefixedAddress]GenesisAccount) - if err := json.Unmarshal(data, &m); err != nil { - return err - } - *ga = make(GenesisAlloc) - for addr, a := range m { - (*ga)[common.Address(addr)] = a - } - return nil -} - -type GenesisMultiCoinBalance map[common.Hash]*big.Int - -// GenesisAccount is an account in the state of the genesis block. -type GenesisAccount struct { - Code []byte `json:"code,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` - Balance *big.Int `json:"balance" gencodec:"required"` - MCBalance GenesisMultiCoinBalance `json:"mcbalance,omitempty"` - Nonce uint64 `json:"nonce,omitempty"` - PrivateKey []byte `json:"secretKey,omitempty"` // for tests -} - -type genesisAccountMarshaling struct { - Code hexutil.Bytes - Balance *math.HexOrDecimal256 - Nonce math.HexOrDecimal64 - Storage map[storageJSON]storageJSON - PrivateKey hexutil.Bytes -} diff --git a/core/types/block.go b/core/types/block.go deleted file mode 100644 index 6038046e31..0000000000 --- a/core/types/block.go +++ /dev/null @@ -1,458 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package types contains data types related to Ethereum consensus. -package types - -import ( - "encoding/binary" - "io" - "math/big" - "reflect" - "sync/atomic" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rlp" -) - -// A BlockNonce is a 64-bit hash which proves (combined with the -// mix-hash) that a sufficient amount of computation has been carried -// out on a block. -type BlockNonce [8]byte - -// EncodeNonce converts the given integer to a block nonce. -func EncodeNonce(i uint64) BlockNonce { - var n BlockNonce - binary.BigEndian.PutUint64(n[:], i) - return n -} - -// Uint64 returns the integer value of a block nonce. -func (n BlockNonce) Uint64() uint64 { - return binary.BigEndian.Uint64(n[:]) -} - -// MarshalText encodes n as a hex string with 0x prefix. -func (n BlockNonce) MarshalText() ([]byte, error) { - return hexutil.Bytes(n[:]).MarshalText() -} - -// UnmarshalText implements encoding.TextUnmarshaler. -func (n *BlockNonce) UnmarshalText(input []byte) error { - return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) -} - -//go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go -//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -type Header -out gen_header_rlp.go - -// Header represents a block header in the Ethereum blockchain. -type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` - Number *big.Int `json:"number" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - Time uint64 `json:"timestamp" gencodec:"required"` - Extra []byte `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce BlockNonce `json:"nonce"` - ExtDataHash common.Hash `json:"extDataHash" gencodec:"required"` - - // BaseFee was added by EIP-1559 and is ignored in legacy headers. - BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"` - - // ExtDataGasUsed was added by Apricot Phase 4 and is ignored in legacy - // headers. - // - // It is not a uint64 like GasLimit or GasUsed because it is not possible to - // correctly encode this field optionally with uint64. - ExtDataGasUsed *big.Int `json:"extDataGasUsed" rlp:"optional"` - - // BlockGasCost was added by Apricot Phase 4 and is ignored in legacy - // headers. - BlockGasCost *big.Int `json:"blockGasCost" rlp:"optional"` - - // BlobGasUsed was added by EIP-4844 and is ignored in legacy headers. - BlobGasUsed *uint64 `json:"blobGasUsed" rlp:"optional"` - - // ExcessBlobGas was added by EIP-4844 and is ignored in legacy headers. - ExcessBlobGas *uint64 `json:"excessBlobGas" rlp:"optional"` - - // ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers. - ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` -} - -// field type overrides for gencodec -type headerMarshaling struct { - Difficulty *hexutil.Big - Number *hexutil.Big - GasLimit hexutil.Uint64 - GasUsed hexutil.Uint64 - Time hexutil.Uint64 - Extra hexutil.Bytes - BaseFee *hexutil.Big - ExtDataGasUsed *hexutil.Big - BlockGasCost *hexutil.Big - Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON - BlobGasUsed *hexutil.Uint64 - ExcessBlobGas *hexutil.Uint64 -} - -// Hash returns the block hash of the header, which is simply the keccak256 hash of its -// RLP encoding. -func (h *Header) Hash() common.Hash { - return rlpHash(h) -} - -var headerSize = common.StorageSize(reflect.TypeOf(Header{}).Size()) - -// Size returns the approximate memory used by all internal contents. It is used -// to approximate and limit the memory consumption of various caches. -func (h *Header) Size() common.StorageSize { - var baseFeeBits int - if h.BaseFee != nil { - baseFeeBits = h.BaseFee.BitLen() - } - return headerSize + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen()+baseFeeBits)/8) -} - -// EmptyBody returns true if there is no additional 'body' to complete the header -// that is: no transactions and no uncles. -func (h *Header) EmptyBody() bool { - return h.TxHash == EmptyTxsHash && h.UncleHash == EmptyUncleHash -} - -// EmptyReceipts returns true if there are no receipts for this header/block. -func (h *Header) EmptyReceipts() bool { - return h.ReceiptHash == EmptyReceiptsHash -} - -// Body is a simple (mutable, non-safe) data container for storing and moving -// a block's data contents (transactions and uncles) together. -type Body struct { - Transactions []*Transaction - Uncles []*Header - Version uint32 - ExtData *[]byte `rlp:"nil"` -} - -// Block represents an Ethereum block. -// -// Note the Block type tries to be 'immutable', and contains certain caches that rely -// on that. The rules around block immutability are as follows: -// -// - We copy all data when the block is constructed. This makes references held inside -// the block independent of whatever value was passed in. -// -// - We copy all header data on access. This is because any change to the header would mess -// up the cached hash and size values in the block. Calling code is expected to take -// advantage of this to avoid over-allocating! -// -// - When new body data is attached to the block, a shallow copy of the block is returned. -// This ensures block modifications are race-free. -// -// - We do not copy body data on access because it does not affect the caches, and also -// because it would be too expensive. -type Block struct { - header *Header - uncles []*Header - transactions Transactions - - // Coreth specific data structures to support atomic transactions - version uint32 - extdata *[]byte - - // caches - hash atomic.Value - size atomic.Value -} - -// "external" block encoding. used for eth protocol, etc. -type extblock struct { - Header *Header - Txs []*Transaction - Uncles []*Header - Version uint32 - ExtData *[]byte `rlp:"nil"` -} - -// NewBlock creates a new block. The input data is copied, changes to header and to the -// field values will not affect the block. -// -// The values of TxHash, UncleHash, ReceiptHash and Bloom in header -// are ignored and set to values derived from the given txs, uncles -// and receipts. -func NewBlock( - header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, hasher TrieHasher, -) *Block { - b := &Block{header: CopyHeader(header)} - - // TODO: panic if len(txs) != len(receipts) - if len(txs) == 0 { - b.header.TxHash = EmptyTxsHash - } else { - b.header.TxHash = DeriveSha(Transactions(txs), hasher) - b.transactions = make(Transactions, len(txs)) - copy(b.transactions, txs) - } - - if len(receipts) == 0 { - b.header.ReceiptHash = EmptyReceiptsHash - } else { - b.header.ReceiptHash = DeriveSha(Receipts(receipts), hasher) - b.header.Bloom = CreateBloom(receipts) - } - - if len(uncles) == 0 { - b.header.UncleHash = EmptyUncleHash - } else { - b.header.UncleHash = CalcUncleHash(uncles) - b.uncles = make([]*Header, len(uncles)) - for i := range uncles { - b.uncles[i] = CopyHeader(uncles[i]) - } - } - - return b -} - -// CopyHeader creates a deep copy of a block header. -func CopyHeader(h *Header) *Header { - cpy := *h - if cpy.Difficulty = new(big.Int); h.Difficulty != nil { - cpy.Difficulty.Set(h.Difficulty) - } - if cpy.Number = new(big.Int); h.Number != nil { - cpy.Number.Set(h.Number) - } - if h.BaseFee != nil { - cpy.BaseFee = new(big.Int).Set(h.BaseFee) - } - if h.ExtDataGasUsed != nil { - cpy.ExtDataGasUsed = new(big.Int).Set(h.ExtDataGasUsed) - } - if h.BlockGasCost != nil { - cpy.BlockGasCost = new(big.Int).Set(h.BlockGasCost) - } - if len(h.Extra) > 0 { - cpy.Extra = make([]byte, len(h.Extra)) - copy(cpy.Extra, h.Extra) - } - if h.ExcessBlobGas != nil { - cpy.ExcessBlobGas = new(uint64) - *cpy.ExcessBlobGas = *h.ExcessBlobGas - } - if h.BlobGasUsed != nil { - cpy.BlobGasUsed = new(uint64) - *cpy.BlobGasUsed = *h.BlobGasUsed - } - if h.ParentBeaconRoot != nil { - cpy.ParentBeaconRoot = new(common.Hash) - *cpy.ParentBeaconRoot = *h.ParentBeaconRoot - } - return &cpy -} - -// DecodeRLP decodes a block from RLP. -func (b *Block) DecodeRLP(s *rlp.Stream) error { - var eb extblock - _, size, _ := s.Kind() - if err := s.Decode(&eb); err != nil { - return err - } - b.header, b.uncles, b.transactions, b.version, b.extdata = eb.Header, eb.Uncles, eb.Txs, eb.Version, eb.ExtData - b.size.Store(rlp.ListSize(size)) - return nil -} - -// EncodeRLP serializes a block as RLP. -func (b *Block) EncodeRLP(w io.Writer) error { - return rlp.Encode(w, &extblock{ - Header: b.header, - Txs: b.transactions, - Uncles: b.uncles, - Version: b.version, - ExtData: b.extdata, - }) -} - -// Body returns the non-header content of the block. -// Note the returned data is not an independent copy. -func (b *Block) Body() *Body { - return &Body{b.transactions, b.uncles, b.version, b.extdata} -} - -// Accessors for body data. These do not return a copy because the content -// of the body slices does not affect the cached hash/size in block. - -func (b *Block) Uncles() []*Header { return b.uncles } -func (b *Block) Transactions() Transactions { return b.transactions } - -func (b *Block) Transaction(hash common.Hash) *Transaction { - for _, transaction := range b.transactions { - if transaction.Hash() == hash { - return transaction - } - } - return nil -} - -// Header returns the block header (as a copy). -func (b *Block) Header() *Header { - return CopyHeader(b.header) -} - -// Header value accessors. These do copy! - -func (b *Block) Number() *big.Int { return new(big.Int).Set(b.header.Number) } -func (b *Block) GasLimit() uint64 { return b.header.GasLimit } -func (b *Block) GasUsed() uint64 { return b.header.GasUsed } -func (b *Block) Difficulty() *big.Int { return new(big.Int).Set(b.header.Difficulty) } -func (b *Block) Time() uint64 { return b.header.Time } -func (b *Block) Timestamp() uint64 { return b.header.Time } - -func (b *Block) NumberU64() uint64 { return b.header.Number.Uint64() } -func (b *Block) MixDigest() common.Hash { return b.header.MixDigest } -func (b *Block) Nonce() uint64 { return binary.BigEndian.Uint64(b.header.Nonce[:]) } -func (b *Block) Bloom() Bloom { return b.header.Bloom } -func (b *Block) Coinbase() common.Address { return b.header.Coinbase } -func (b *Block) Root() common.Hash { return b.header.Root } -func (b *Block) ParentHash() common.Hash { return b.header.ParentHash } -func (b *Block) TxHash() common.Hash { return b.header.TxHash } -func (b *Block) ReceiptHash() common.Hash { return b.header.ReceiptHash } -func (b *Block) UncleHash() common.Hash { return b.header.UncleHash } -func (b *Block) Extra() []byte { return common.CopyBytes(b.header.Extra) } - -func (b *Block) BaseFee() *big.Int { - if b.header.BaseFee == nil { - return nil - } - return new(big.Int).Set(b.header.BaseFee) -} - -func (b *Block) BeaconRoot() *common.Hash { return b.header.ParentBeaconRoot } - -func (b *Block) ExcessBlobGas() *uint64 { - var excessBlobGas *uint64 - if b.header.ExcessBlobGas != nil { - excessBlobGas = new(uint64) - *excessBlobGas = *b.header.ExcessBlobGas - } - return excessBlobGas -} - -func (b *Block) BlobGasUsed() *uint64 { - var blobGasUsed *uint64 - if b.header.BlobGasUsed != nil { - blobGasUsed = new(uint64) - *blobGasUsed = *b.header.BlobGasUsed - } - return blobGasUsed -} - -func (b *Block) BlockGasCost() *big.Int { - if b.header.BlockGasCost == nil { - return nil - } - return new(big.Int).Set(b.header.BlockGasCost) -} - -// Size returns the true RLP encoded storage size of the block, either by encoding -// and returning it, or returning a previously cached value. -func (b *Block) Size() uint64 { - if size := b.size.Load(); size != nil { - return size.(uint64) - } - c := writeCounter(0) - rlp.Encode(&c, b) - b.size.Store(uint64(c)) - return uint64(c) -} - -type writeCounter uint64 - -func (c *writeCounter) Write(b []byte) (int, error) { - *c += writeCounter(len(b)) - return len(b), nil -} - -func CalcUncleHash(uncles []*Header) common.Hash { - if len(uncles) == 0 { - return EmptyUncleHash - } - return rlpHash(uncles) -} - -// NewBlockWithHeader creates a block with the given header data. The -// header data is copied, changes to header and to the field values -// will not affect the block. -func NewBlockWithHeader(header *Header) *Block { - return &Block{header: CopyHeader(header)} -} - -// WithSeal returns a new block with the data from b but the header replaced with -// the sealed one. -func (b *Block) WithSeal(header *Header) *Block { - return &Block{ - header: CopyHeader(header), - transactions: b.transactions, - uncles: b.uncles, - } -} - -// WithBody returns a copy of the block with the given transaction and uncle contents. -func (b *Block) WithBody(transactions []*Transaction, uncles []*Header) *Block { - block := &Block{ - header: b.header, - transactions: make([]*Transaction, len(transactions)), - uncles: make([]*Header, len(uncles)), - } - copy(block.transactions, transactions) - for i := range uncles { - block.uncles[i] = CopyHeader(uncles[i]) - } - return block -} - -// Hash returns the keccak256 hash of b's header. -// The hash is computed on the first call and cached thereafter. -func (b *Block) Hash() common.Hash { - if hash := b.hash.Load(); hash != nil { - return hash.(common.Hash) - } - v := b.header.Hash() - b.hash.Store(v) - return v -} - -type Blocks []*Block diff --git a/core/types/block_ext.go b/core/types/block_ext.go deleted file mode 100644 index 5ebb7aeb31..0000000000 --- a/core/types/block_ext.go +++ /dev/null @@ -1,67 +0,0 @@ -// (c) 2024, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package types - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -func (b *Block) WithExtData(version uint32, extdata *[]byte) *Block { - b.version = version - b.setExtDataHelper(extdata, false) - return b -} - -func (b *Block) setExtDataHelper(data *[]byte, recalc bool) { - if data == nil { - b.setExtData(nil, recalc) - return - } - b.setExtData(*data, recalc) -} - -func (b *Block) setExtData(data []byte, recalc bool) { - _data := make([]byte, len(data)) - b.extdata = &_data - copy(*b.extdata, data) - if recalc { - b.header.ExtDataHash = CalcExtDataHash(*b.extdata) - } -} - -func (b *Block) ExtData() []byte { - if b.extdata == nil { - return nil - } - return *b.extdata -} - -func (b *Block) Version() uint32 { - return b.version -} - -func (b *Block) ExtDataGasUsed() *big.Int { - if b.header.ExtDataGasUsed == nil { - return nil - } - return new(big.Int).Set(b.header.ExtDataGasUsed) -} - -func CalcExtDataHash(extdata []byte) common.Hash { - if len(extdata) == 0 { - return EmptyExtDataHash - } - return rlpHash(extdata) -} - -func NewBlockWithExtData( - header *Header, txs []*Transaction, uncles []*Header, receipts []*Receipt, - hasher TrieHasher, extdata []byte, recalc bool, -) *Block { - b := NewBlock(header, txs, uncles, receipts, hasher) - b.setExtData(extdata, recalc) - return b -} diff --git a/core/types/bloom9.go b/core/types/bloom9.go deleted file mode 100644 index aa172a0b1b..0000000000 --- a/core/types/bloom9.go +++ /dev/null @@ -1,170 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "encoding/binary" - "fmt" - "math/big" - - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" -) - -type bytesBacked interface { - Bytes() []byte -} - -const ( - // BloomByteLength represents the number of bytes used in a header log bloom. - BloomByteLength = 256 - - // BloomBitLength represents the number of bits used in a header log bloom. - BloomBitLength = 8 * BloomByteLength -) - -// Bloom represents a 2048 bit bloom filter. -type Bloom [BloomByteLength]byte - -// BytesToBloom converts a byte slice to a bloom filter. -// It panics if b is not of suitable size. -func BytesToBloom(b []byte) Bloom { - var bloom Bloom - bloom.SetBytes(b) - return bloom -} - -// SetBytes sets the content of b to the given bytes. -// It panics if d is not of suitable size. -func (b *Bloom) SetBytes(d []byte) { - if len(b) < len(d) { - panic(fmt.Sprintf("bloom bytes too big %d %d", len(b), len(d))) - } - copy(b[BloomByteLength-len(d):], d) -} - -// Add adds d to the filter. Future calls of Test(d) will return true. -func (b *Bloom) Add(d []byte) { - b.add(d, make([]byte, 6)) -} - -// add is internal version of Add, which takes a scratch buffer for reuse (needs to be at least 6 bytes) -func (b *Bloom) add(d []byte, buf []byte) { - i1, v1, i2, v2, i3, v3 := bloomValues(d, buf) - b[i1] |= v1 - b[i2] |= v2 - b[i3] |= v3 -} - -// Big converts b to a big integer. -// Note: Converting a bloom filter to a big.Int and then calling GetBytes -// does not return the same bytes, since big.Int will trim leading zeroes -func (b Bloom) Big() *big.Int { - return new(big.Int).SetBytes(b[:]) -} - -// Bytes returns the backing byte slice of the bloom -func (b Bloom) Bytes() []byte { - return b[:] -} - -// Test checks if the given topic is present in the bloom filter -func (b Bloom) Test(topic []byte) bool { - i1, v1, i2, v2, i3, v3 := bloomValues(topic, make([]byte, 6)) - return v1 == v1&b[i1] && - v2 == v2&b[i2] && - v3 == v3&b[i3] -} - -// MarshalText encodes b as a hex string with 0x prefix. -func (b Bloom) MarshalText() ([]byte, error) { - return hexutil.Bytes(b[:]).MarshalText() -} - -// UnmarshalText b as a hex string with 0x prefix. -func (b *Bloom) UnmarshalText(input []byte) error { - return hexutil.UnmarshalFixedText("Bloom", input, b[:]) -} - -// CreateBloom creates a bloom filter out of the give Receipts (+Logs) -func CreateBloom(receipts Receipts) Bloom { - buf := make([]byte, 6) - var bin Bloom - for _, receipt := range receipts { - for _, log := range receipt.Logs { - bin.add(log.Address.Bytes(), buf) - for _, b := range log.Topics { - bin.add(b[:], buf) - } - } - } - return bin -} - -// LogsBloom returns the bloom bytes for the given logs -func LogsBloom(logs []*Log) []byte { - buf := make([]byte, 6) - var bin Bloom - for _, log := range logs { - bin.add(log.Address.Bytes(), buf) - for _, b := range log.Topics { - bin.add(b[:], buf) - } - } - return bin[:] -} - -// Bloom9 returns the bloom filter for the given data -func Bloom9(data []byte) []byte { - var b Bloom - b.SetBytes(data) - return b.Bytes() -} - -// bloomValues returns the bytes (index-value pairs) to set for the given data -func bloomValues(data []byte, hashbuf []byte) (uint, byte, uint, byte, uint, byte) { - sha := hasherPool.Get().(crypto.KeccakState) - sha.Reset() - sha.Write(data) - sha.Read(hashbuf) - hasherPool.Put(sha) - // The actual bits to flip - v1 := byte(1 << (hashbuf[1] & 0x7)) - v2 := byte(1 << (hashbuf[3] & 0x7)) - v3 := byte(1 << (hashbuf[5] & 0x7)) - // The indices for the bytes to OR in - i1 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf)&0x7ff)>>3) - 1 - i2 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[2:])&0x7ff)>>3) - 1 - i3 := BloomByteLength - uint((binary.BigEndian.Uint16(hashbuf[4:])&0x7ff)>>3) - 1 - - return i1, v1, i2, v2, i3, v3 -} - -// BloomLookup is a convenience-method to check presence in the bloom filter -func BloomLookup(bin Bloom, topic bytesBacked) bool { - return bin.Test(topic.Bytes()) -} diff --git a/core/types/bloom9_test.go b/core/types/bloom9_test.go deleted file mode 100644 index e758b9cd45..0000000000 --- a/core/types/bloom9_test.go +++ /dev/null @@ -1,165 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "fmt" - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -func TestBloom(t *testing.T) { - positive := []string{ - "testtest", - "test", - "hallo", - "other", - } - negative := []string{ - "tes", - "lo", - } - - var bloom Bloom - for _, data := range positive { - bloom.Add([]byte(data)) - } - - for _, data := range positive { - if !bloom.Test([]byte(data)) { - t.Error("expected", data, "to test true") - } - } - for _, data := range negative { - if bloom.Test([]byte(data)) { - t.Error("did not expect", data, "to test true") - } - } -} - -// TestBloomExtensively does some more thorough tests -func TestBloomExtensively(t *testing.T) { - var exp = common.HexToHash("c8d3ca65cdb4874300a9e39475508f23ed6da09fdbc487f89a2dcf50b09eb263") - var b Bloom - // Add 100 "random" things - for i := 0; i < 100; i++ { - data := fmt.Sprintf("xxxxxxxxxx data %d yyyyyyyyyyyyyy", i) - b.Add([]byte(data)) - //b.Add(new(big.Int).SetBytes([]byte(data))) - } - got := crypto.Keccak256Hash(b.Bytes()) - if got != exp { - t.Errorf("Got %x, exp %x", got, exp) - } - var b2 Bloom - b2.SetBytes(b.Bytes()) - got2 := crypto.Keccak256Hash(b2.Bytes()) - if got != got2 { - t.Errorf("Got %x, exp %x", got, got2) - } -} - -func BenchmarkBloom9(b *testing.B) { - test := []byte("testestestest") - for i := 0; i < b.N; i++ { - Bloom9(test) - } -} - -func BenchmarkBloom9Lookup(b *testing.B) { - toTest := []byte("testtest") - bloom := new(Bloom) - for i := 0; i < b.N; i++ { - bloom.Test(toTest) - } -} - -func BenchmarkCreateBloom(b *testing.B) { - var txs = Transactions{ - NewContractCreation(1, big.NewInt(1), 1, big.NewInt(1), nil), - NewTransaction(2, common.HexToAddress("0x2"), big.NewInt(2), 2, big.NewInt(2), nil), - } - var rSmall = Receipts{ - &Receipt{ - Status: ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*Log{ - {Address: common.BytesToAddress([]byte{0x11})}, - {Address: common.BytesToAddress([]byte{0x01, 0x11})}, - }, - TxHash: txs[0].Hash(), - ContractAddress: common.BytesToAddress([]byte{0x01, 0x11, 0x11}), - GasUsed: 1, - }, - &Receipt{ - PostState: common.Hash{2}.Bytes(), - CumulativeGasUsed: 3, - Logs: []*Log{ - {Address: common.BytesToAddress([]byte{0x22})}, - {Address: common.BytesToAddress([]byte{0x02, 0x22})}, - }, - TxHash: txs[1].Hash(), - ContractAddress: common.BytesToAddress([]byte{0x02, 0x22, 0x22}), - GasUsed: 2, - }, - } - - var rLarge = make(Receipts, 200) - // Fill it with 200 receipts x 2 logs - for i := 0; i < 200; i += 2 { - copy(rLarge[i:], rSmall) - } - b.Run("small", func(b *testing.B) { - b.ReportAllocs() - var bl Bloom - for i := 0; i < b.N; i++ { - bl = CreateBloom(rSmall) - } - b.StopTimer() - var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") - got := crypto.Keccak256Hash(bl.Bytes()) - if got != exp { - b.Errorf("Got %x, exp %x", got, exp) - } - }) - b.Run("large", func(b *testing.B) { - b.ReportAllocs() - var bl Bloom - for i := 0; i < b.N; i++ { - bl = CreateBloom(rLarge) - } - b.StopTimer() - var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") - got := crypto.Keccak256Hash(bl.Bytes()) - if got != exp { - b.Errorf("Got %x, exp %x", got, exp) - } - }) -} diff --git a/core/types/gen_access_tuple.go b/core/types/gen_access_tuple.go deleted file mode 100644 index d740b70981..0000000000 --- a/core/types/gen_access_tuple.go +++ /dev/null @@ -1,43 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package types - -import ( - "encoding/json" - "errors" - - "github.com/ethereum/go-ethereum/common" -) - -// MarshalJSON marshals as JSON. -func (a AccessTuple) MarshalJSON() ([]byte, error) { - type AccessTuple struct { - Address common.Address `json:"address" gencodec:"required"` - StorageKeys []common.Hash `json:"storageKeys" gencodec:"required"` - } - var enc AccessTuple - enc.Address = a.Address - enc.StorageKeys = a.StorageKeys - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (a *AccessTuple) UnmarshalJSON(input []byte) error { - type AccessTuple struct { - Address *common.Address `json:"address" gencodec:"required"` - StorageKeys []common.Hash `json:"storageKeys" gencodec:"required"` - } - var dec AccessTuple - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Address == nil { - return errors.New("missing required field 'address' for AccessTuple") - } - a.Address = *dec.Address - if dec.StorageKeys == nil { - return errors.New("missing required field 'storageKeys' for AccessTuple") - } - a.StorageKeys = dec.StorageKeys - return nil -} diff --git a/core/types/gen_account.go b/core/types/gen_account.go deleted file mode 100644 index 4e475896a7..0000000000 --- a/core/types/gen_account.go +++ /dev/null @@ -1,73 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package types - -import ( - "encoding/json" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" -) - -var _ = (*accountMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (a Account) MarshalJSON() ([]byte, error) { - type Account struct { - Code hexutil.Bytes `json:"code,omitempty"` - Storage map[storageJSON]storageJSON `json:"storage,omitempty"` - Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` - Nonce math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey hexutil.Bytes `json:"secretKey,omitempty"` - } - var enc Account - enc.Code = a.Code - if a.Storage != nil { - enc.Storage = make(map[storageJSON]storageJSON, len(a.Storage)) - for k, v := range a.Storage { - enc.Storage[storageJSON(k)] = storageJSON(v) - } - } - enc.Balance = (*math.HexOrDecimal256)(a.Balance) - enc.Nonce = math.HexOrDecimal64(a.Nonce) - enc.PrivateKey = a.PrivateKey - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (a *Account) UnmarshalJSON(input []byte) error { - type Account struct { - Code *hexutil.Bytes `json:"code,omitempty"` - Storage map[storageJSON]storageJSON `json:"storage,omitempty"` - Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` - Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"` - } - var dec Account - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Code != nil { - a.Code = *dec.Code - } - if dec.Storage != nil { - a.Storage = make(map[common.Hash]common.Hash, len(dec.Storage)) - for k, v := range dec.Storage { - a.Storage[common.Hash(k)] = common.Hash(v) - } - } - if dec.Balance == nil { - return errors.New("missing required field 'balance' for Account") - } - a.Balance = (*big.Int)(dec.Balance) - if dec.Nonce != nil { - a.Nonce = uint64(*dec.Nonce) - } - if dec.PrivateKey != nil { - a.PrivateKey = *dec.PrivateKey - } - return nil -} diff --git a/core/types/gen_account_rlp.go b/core/types/gen_account_rlp.go deleted file mode 100644 index 382bedcd38..0000000000 --- a/core/types/gen_account_rlp.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by rlpgen. DO NOT EDIT. - -package types - -import ( - "io" - - "github.com/ethereum/go-ethereum/rlp" -) - -func (obj *StateAccount) EncodeRLP(_w io.Writer) error { - w := rlp.NewEncoderBuffer(_w) - _tmp0 := w.List() - w.WriteUint64(obj.Nonce) - if obj.Balance == nil { - w.Write(rlp.EmptyString) - } else { - w.WriteUint256(obj.Balance) - } - w.WriteBytes(obj.Root[:]) - w.WriteBytes(obj.CodeHash) - w.WriteBool(obj.IsMultiCoin) - w.ListEnd(_tmp0) - return w.Flush() -} diff --git a/core/types/gen_genesis_account.go b/core/types/gen_genesis_account.go deleted file mode 100644 index f4c352ec7e..0000000000 --- a/core/types/gen_genesis_account.go +++ /dev/null @@ -1,79 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package types - -import ( - "encoding/json" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" -) - -var _ = (*genesisAccountMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (g GenesisAccount) MarshalJSON() ([]byte, error) { - type GenesisAccount struct { - Code hexutil.Bytes `json:"code,omitempty"` - Storage map[storageJSON]storageJSON `json:"storage,omitempty"` - Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` - MCBalance GenesisMultiCoinBalance `json:"mcbalance,omitempty"` - Nonce math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey hexutil.Bytes `json:"secretKey,omitempty"` - } - var enc GenesisAccount - enc.Code = g.Code - if g.Storage != nil { - enc.Storage = make(map[storageJSON]storageJSON, len(g.Storage)) - for k, v := range g.Storage { - enc.Storage[storageJSON(k)] = storageJSON(v) - } - } - enc.Balance = (*math.HexOrDecimal256)(g.Balance) - enc.MCBalance = g.MCBalance - enc.Nonce = math.HexOrDecimal64(g.Nonce) - enc.PrivateKey = g.PrivateKey - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (g *GenesisAccount) UnmarshalJSON(input []byte) error { - type GenesisAccount struct { - Code *hexutil.Bytes `json:"code,omitempty"` - Storage map[storageJSON]storageJSON `json:"storage,omitempty"` - Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"` - MCBalance *GenesisMultiCoinBalance `json:"mcbalance,omitempty"` - Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"` - PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"` - } - var dec GenesisAccount - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Code != nil { - g.Code = *dec.Code - } - if dec.Storage != nil { - g.Storage = make(map[common.Hash]common.Hash, len(dec.Storage)) - for k, v := range dec.Storage { - g.Storage[common.Hash(k)] = common.Hash(v) - } - } - if dec.Balance == nil { - return errors.New("missing required field 'balance' for GenesisAccount") - } - g.Balance = (*big.Int)(dec.Balance) - if dec.MCBalance != nil { - g.MCBalance = *dec.MCBalance - } - if dec.Nonce != nil { - g.Nonce = uint64(*dec.Nonce) - } - if dec.PrivateKey != nil { - g.PrivateKey = *dec.PrivateKey - } - return nil -} diff --git a/core/types/gen_header_json.go b/core/types/gen_header_json.go deleted file mode 100644 index 632a6ed48e..0000000000 --- a/core/types/gen_header_json.go +++ /dev/null @@ -1,181 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package types - -import ( - "encoding/json" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*headerMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (h Header) MarshalJSON() ([]byte, error) { - type Header struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase common.Address `json:"miner" gencodec:"required"` - Root common.Hash `json:"stateRoot" gencodec:"required"` - TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest common.Hash `json:"mixHash"` - Nonce BlockNonce `json:"nonce"` - ExtDataHash common.Hash `json:"extDataHash" gencodec:"required"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - ExtDataGasUsed *hexutil.Big `json:"extDataGasUsed" rlp:"optional"` - BlockGasCost *hexutil.Big `json:"blockGasCost" rlp:"optional"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` - ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` - Hash common.Hash `json:"hash"` - } - var enc Header - enc.ParentHash = h.ParentHash - enc.UncleHash = h.UncleHash - enc.Coinbase = h.Coinbase - enc.Root = h.Root - enc.TxHash = h.TxHash - enc.ReceiptHash = h.ReceiptHash - enc.Bloom = h.Bloom - enc.Difficulty = (*hexutil.Big)(h.Difficulty) - enc.Number = (*hexutil.Big)(h.Number) - enc.GasLimit = hexutil.Uint64(h.GasLimit) - enc.GasUsed = hexutil.Uint64(h.GasUsed) - enc.Time = hexutil.Uint64(h.Time) - enc.Extra = h.Extra - enc.MixDigest = h.MixDigest - enc.Nonce = h.Nonce - enc.ExtDataHash = h.ExtDataHash - enc.BaseFee = (*hexutil.Big)(h.BaseFee) - enc.ExtDataGasUsed = (*hexutil.Big)(h.ExtDataGasUsed) - enc.BlockGasCost = (*hexutil.Big)(h.BlockGasCost) - enc.BlobGasUsed = (*hexutil.Uint64)(h.BlobGasUsed) - enc.ExcessBlobGas = (*hexutil.Uint64)(h.ExcessBlobGas) - enc.ParentBeaconRoot = h.ParentBeaconRoot - enc.Hash = h.Hash() - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (h *Header) UnmarshalJSON(input []byte) error { - type Header struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` - Coinbase *common.Address `json:"miner" gencodec:"required"` - Root *common.Hash `json:"stateRoot" gencodec:"required"` - TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` - ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` - Number *hexutil.Big `json:"number" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` - MixDigest *common.Hash `json:"mixHash"` - Nonce *BlockNonce `json:"nonce"` - ExtDataHash *common.Hash `json:"extDataHash" gencodec:"required"` - BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` - ExtDataGasUsed *hexutil.Big `json:"extDataGasUsed" rlp:"optional"` - BlockGasCost *hexutil.Big `json:"blockGasCost" rlp:"optional"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` - ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` - } - var dec Header - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.ParentHash == nil { - return errors.New("missing required field 'parentHash' for Header") - } - h.ParentHash = *dec.ParentHash - if dec.UncleHash == nil { - return errors.New("missing required field 'sha3Uncles' for Header") - } - h.UncleHash = *dec.UncleHash - if dec.Coinbase == nil { - return errors.New("missing required field 'miner' for Header") - } - h.Coinbase = *dec.Coinbase - if dec.Root == nil { - return errors.New("missing required field 'stateRoot' for Header") - } - h.Root = *dec.Root - if dec.TxHash == nil { - return errors.New("missing required field 'transactionsRoot' for Header") - } - h.TxHash = *dec.TxHash - if dec.ReceiptHash == nil { - return errors.New("missing required field 'receiptsRoot' for Header") - } - h.ReceiptHash = *dec.ReceiptHash - if dec.Bloom == nil { - return errors.New("missing required field 'logsBloom' for Header") - } - h.Bloom = *dec.Bloom - if dec.Difficulty == nil { - return errors.New("missing required field 'difficulty' for Header") - } - h.Difficulty = (*big.Int)(dec.Difficulty) - if dec.Number == nil { - return errors.New("missing required field 'number' for Header") - } - h.Number = (*big.Int)(dec.Number) - if dec.GasLimit == nil { - return errors.New("missing required field 'gasLimit' for Header") - } - h.GasLimit = uint64(*dec.GasLimit) - if dec.GasUsed == nil { - return errors.New("missing required field 'gasUsed' for Header") - } - h.GasUsed = uint64(*dec.GasUsed) - if dec.Time == nil { - return errors.New("missing required field 'timestamp' for Header") - } - h.Time = uint64(*dec.Time) - if dec.Extra == nil { - return errors.New("missing required field 'extraData' for Header") - } - h.Extra = *dec.Extra - if dec.MixDigest != nil { - h.MixDigest = *dec.MixDigest - } - if dec.Nonce != nil { - h.Nonce = *dec.Nonce - } - if dec.ExtDataHash == nil { - return errors.New("missing required field 'extDataHash' for Header") - } - h.ExtDataHash = *dec.ExtDataHash - if dec.BaseFee != nil { - h.BaseFee = (*big.Int)(dec.BaseFee) - } - if dec.ExtDataGasUsed != nil { - h.ExtDataGasUsed = (*big.Int)(dec.ExtDataGasUsed) - } - if dec.BlockGasCost != nil { - h.BlockGasCost = (*big.Int)(dec.BlockGasCost) - } - if dec.BlobGasUsed != nil { - h.BlobGasUsed = (*uint64)(dec.BlobGasUsed) - } - if dec.ExcessBlobGas != nil { - h.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) - } - if dec.ParentBeaconRoot != nil { - h.ParentBeaconRoot = dec.ParentBeaconRoot - } - return nil -} diff --git a/core/types/gen_log_json.go b/core/types/gen_log_json.go deleted file mode 100644 index 3ffa9c2feb..0000000000 --- a/core/types/gen_log_json.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package types - -import ( - "encoding/json" - "errors" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*logMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (l Log) MarshalJSON() ([]byte, error) { - type Log struct { - Address common.Address `json:"address" gencodec:"required"` - Topics []common.Hash `json:"topics" gencodec:"required"` - Data hexutil.Bytes `json:"data" gencodec:"required"` - BlockNumber hexutil.Uint64 `json:"blockNumber" rlp:"-"` - TxHash common.Hash `json:"transactionHash" gencodec:"required" rlp:"-"` - TxIndex hexutil.Uint `json:"transactionIndex" rlp:"-"` - BlockHash common.Hash `json:"blockHash" rlp:"-"` - Index hexutil.Uint `json:"logIndex" rlp:"-"` - Removed bool `json:"removed" rlp:"-"` - } - var enc Log - enc.Address = l.Address - enc.Topics = l.Topics - enc.Data = l.Data - enc.BlockNumber = hexutil.Uint64(l.BlockNumber) - enc.TxHash = l.TxHash - enc.TxIndex = hexutil.Uint(l.TxIndex) - enc.BlockHash = l.BlockHash - enc.Index = hexutil.Uint(l.Index) - enc.Removed = l.Removed - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (l *Log) UnmarshalJSON(input []byte) error { - type Log struct { - Address *common.Address `json:"address" gencodec:"required"` - Topics []common.Hash `json:"topics" gencodec:"required"` - Data *hexutil.Bytes `json:"data" gencodec:"required"` - BlockNumber *hexutil.Uint64 `json:"blockNumber" rlp:"-"` - TxHash *common.Hash `json:"transactionHash" gencodec:"required" rlp:"-"` - TxIndex *hexutil.Uint `json:"transactionIndex" rlp:"-"` - BlockHash *common.Hash `json:"blockHash" rlp:"-"` - Index *hexutil.Uint `json:"logIndex" rlp:"-"` - Removed *bool `json:"removed" rlp:"-"` - } - var dec Log - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Address == nil { - return errors.New("missing required field 'address' for Log") - } - l.Address = *dec.Address - if dec.Topics == nil { - return errors.New("missing required field 'topics' for Log") - } - l.Topics = dec.Topics - if dec.Data == nil { - return errors.New("missing required field 'data' for Log") - } - l.Data = *dec.Data - if dec.BlockNumber != nil { - l.BlockNumber = uint64(*dec.BlockNumber) - } - if dec.TxHash == nil { - return errors.New("missing required field 'transactionHash' for Log") - } - l.TxHash = *dec.TxHash - if dec.TxIndex != nil { - l.TxIndex = uint(*dec.TxIndex) - } - if dec.BlockHash != nil { - l.BlockHash = *dec.BlockHash - } - if dec.Index != nil { - l.Index = uint(*dec.Index) - } - if dec.Removed != nil { - l.Removed = *dec.Removed - } - return nil -} diff --git a/core/types/gen_log_rlp.go b/core/types/gen_log_rlp.go deleted file mode 100644 index 89f2083d4b..0000000000 --- a/core/types/gen_log_rlp.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by rlpgen. DO NOT EDIT. - -package types - -import ( - "io" - - "github.com/ethereum/go-ethereum/rlp" -) - -func (obj *Log) EncodeRLP(_w io.Writer) error { - w := rlp.NewEncoderBuffer(_w) - _tmp0 := w.List() - w.WriteBytes(obj.Address[:]) - _tmp1 := w.List() - for _, _tmp2 := range obj.Topics { - w.WriteBytes(_tmp2[:]) - } - w.ListEnd(_tmp1) - w.WriteBytes(obj.Data) - w.ListEnd(_tmp0) - return w.Flush() -} diff --git a/core/types/gen_receipt_json.go b/core/types/gen_receipt_json.go deleted file mode 100644 index 4c641a9727..0000000000 --- a/core/types/gen_receipt_json.go +++ /dev/null @@ -1,128 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package types - -import ( - "encoding/json" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*receiptMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (r Receipt) MarshalJSON() ([]byte, error) { - type Receipt struct { - Type hexutil.Uint64 `json:"type,omitempty"` - PostState hexutil.Bytes `json:"root"` - Status hexutil.Uint64 `json:"status"` - CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` - TxHash common.Hash `json:"transactionHash" gencodec:"required"` - ContractAddress common.Address `json:"contractAddress"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"` - BlobGasUsed hexutil.Uint64 `json:"blobGasUsed,omitempty"` - BlobGasPrice *hexutil.Big `json:"blobGasPrice,omitempty"` - BlockHash common.Hash `json:"blockHash,omitempty"` - BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` - TransactionIndex hexutil.Uint `json:"transactionIndex"` - } - var enc Receipt - enc.Type = hexutil.Uint64(r.Type) - enc.PostState = r.PostState - enc.Status = hexutil.Uint64(r.Status) - enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed) - enc.Bloom = r.Bloom - enc.Logs = r.Logs - enc.TxHash = r.TxHash - enc.ContractAddress = r.ContractAddress - enc.GasUsed = hexutil.Uint64(r.GasUsed) - enc.EffectiveGasPrice = (*hexutil.Big)(r.EffectiveGasPrice) - enc.BlobGasUsed = hexutil.Uint64(r.BlobGasUsed) - enc.BlobGasPrice = (*hexutil.Big)(r.BlobGasPrice) - enc.BlockHash = r.BlockHash - enc.BlockNumber = (*hexutil.Big)(r.BlockNumber) - enc.TransactionIndex = hexutil.Uint(r.TransactionIndex) - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (r *Receipt) UnmarshalJSON(input []byte) error { - type Receipt struct { - Type *hexutil.Uint64 `json:"type,omitempty"` - PostState *hexutil.Bytes `json:"root"` - Status *hexutil.Uint64 `json:"status"` - CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom *Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` - TxHash *common.Hash `json:"transactionHash" gencodec:"required"` - ContractAddress *common.Address `json:"contractAddress"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - EffectiveGasPrice *hexutil.Big `json:"effectiveGasPrice"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed,omitempty"` - BlobGasPrice *hexutil.Big `json:"blobGasPrice,omitempty"` - BlockHash *common.Hash `json:"blockHash,omitempty"` - BlockNumber *hexutil.Big `json:"blockNumber,omitempty"` - TransactionIndex *hexutil.Uint `json:"transactionIndex"` - } - var dec Receipt - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Type != nil { - r.Type = uint8(*dec.Type) - } - if dec.PostState != nil { - r.PostState = *dec.PostState - } - if dec.Status != nil { - r.Status = uint64(*dec.Status) - } - if dec.CumulativeGasUsed == nil { - return errors.New("missing required field 'cumulativeGasUsed' for Receipt") - } - r.CumulativeGasUsed = uint64(*dec.CumulativeGasUsed) - if dec.Bloom == nil { - return errors.New("missing required field 'logsBloom' for Receipt") - } - r.Bloom = *dec.Bloom - if dec.Logs == nil { - return errors.New("missing required field 'logs' for Receipt") - } - r.Logs = dec.Logs - if dec.TxHash == nil { - return errors.New("missing required field 'transactionHash' for Receipt") - } - r.TxHash = *dec.TxHash - if dec.ContractAddress != nil { - r.ContractAddress = *dec.ContractAddress - } - if dec.GasUsed == nil { - return errors.New("missing required field 'gasUsed' for Receipt") - } - r.GasUsed = uint64(*dec.GasUsed) - if dec.EffectiveGasPrice != nil { - r.EffectiveGasPrice = (*big.Int)(dec.EffectiveGasPrice) - } - if dec.BlobGasUsed != nil { - r.BlobGasUsed = uint64(*dec.BlobGasUsed) - } - if dec.BlobGasPrice != nil { - r.BlobGasPrice = (*big.Int)(dec.BlobGasPrice) - } - if dec.BlockHash != nil { - r.BlockHash = *dec.BlockHash - } - if dec.BlockNumber != nil { - r.BlockNumber = (*big.Int)(dec.BlockNumber) - } - if dec.TransactionIndex != nil { - r.TransactionIndex = uint(*dec.TransactionIndex) - } - return nil -} diff --git a/core/types/hashes.go b/core/types/hashes.go deleted file mode 100644 index 3d8a8a013b..0000000000 --- a/core/types/hashes.go +++ /dev/null @@ -1,66 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" -) - -var ( - // EmptyRootHash is the known root hash of an empty merkle trie. - EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - - // EmptyUncleHash is the known hash of the empty uncle set. - EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 - - // EmptyCodeHash is the known hash of the empty EVM bytecode. - EmptyCodeHash = crypto.Keccak256Hash(nil) // c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 - - // EmptyTxsHash is the known hash of the empty transaction set. - EmptyTxsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - - // EmptyReceiptsHash is the known hash of the empty receipt set. - EmptyReceiptsHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - - // EmptyVerkleHash is the known hash of an empty verkle trie. - EmptyVerkleHash = common.Hash{} - - // EmptyExtDataHash is the known hash of empty extdata bytes. - EmptyExtDataHash = rlpHash([]byte(nil)) -) - -// TrieRootHash returns the hash itself if it's non-empty or the predefined -// emptyHash one instead. -func TrieRootHash(hash common.Hash) common.Hash { - if hash == (common.Hash{}) { - log.Error("Zero trie root hash!") - return EmptyRootHash - } - return hash -} diff --git a/core/types/hashing.go b/core/types/hashing.go deleted file mode 100644 index 40291f5406..0000000000 --- a/core/types/hashing.go +++ /dev/null @@ -1,144 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "fmt" - "math" - "sync" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -// hasherPool holds LegacyKeccak256 hashers for rlpHash. -var hasherPool = sync.Pool{ - New: func() interface{} { return sha3.NewLegacyKeccak256() }, -} - -// encodeBufferPool holds temporary encoder buffers for DeriveSha and TX encoding. -var encodeBufferPool = sync.Pool{ - New: func() interface{} { return new(bytes.Buffer) }, -} - -// getPooledBuffer retrieves a buffer from the pool and creates a byte slice of the -// requested size from it. -// -// The caller should return the *bytes.Buffer object back into encodeBufferPool after use! -// The returned byte slice must not be used after returning the buffer. -func getPooledBuffer(size uint64) ([]byte, *bytes.Buffer, error) { - if size > math.MaxInt { - return nil, nil, fmt.Errorf("can't get buffer of size %d", size) - } - buf := encodeBufferPool.Get().(*bytes.Buffer) - buf.Reset() - buf.Grow(int(size)) - b := buf.Bytes()[:int(size)] - return b, buf, nil -} - -// rlpHash encodes x and hashes the encoded bytes. -func rlpHash(x interface{}) (h common.Hash) { - sha := hasherPool.Get().(crypto.KeccakState) - defer hasherPool.Put(sha) - sha.Reset() - rlp.Encode(sha, x) - sha.Read(h[:]) - return h -} - -// prefixedRlpHash writes the prefix into the hasher before rlp-encoding x. -// It's used for typed transactions. -func prefixedRlpHash(prefix byte, x interface{}) (h common.Hash) { - sha := hasherPool.Get().(crypto.KeccakState) - defer hasherPool.Put(sha) - sha.Reset() - sha.Write([]byte{prefix}) - rlp.Encode(sha, x) - sha.Read(h[:]) - return h -} - -// TrieHasher is the tool used to calculate the hash of derivable list. -// This is internal, do not use. -type TrieHasher interface { - Reset() - Update([]byte, []byte) error - Hash() common.Hash -} - -// DerivableList is the input to DeriveSha. -// It is implemented by the 'Transactions' and 'Receipts' types. -// This is internal, do not use these methods. -type DerivableList interface { - Len() int - EncodeIndex(int, *bytes.Buffer) -} - -func encodeForDerive(list DerivableList, i int, buf *bytes.Buffer) []byte { - buf.Reset() - list.EncodeIndex(i, buf) - // It's really unfortunate that we need to perform this copy. - // StackTrie holds onto the values until Hash is called, so the values - // written to it must not alias. - return common.CopyBytes(buf.Bytes()) -} - -// DeriveSha creates the tree hashes of transactions, receipts, and withdrawals in a block header. -func DeriveSha(list DerivableList, hasher TrieHasher) common.Hash { - hasher.Reset() - - valueBuf := encodeBufferPool.Get().(*bytes.Buffer) - defer encodeBufferPool.Put(valueBuf) - - // StackTrie requires values to be inserted in increasing hash order, which is not the - // order that `list` provides hashes in. This insertion sequence ensures that the - // order is correct. - // - // The error returned by hasher is omitted because hasher will produce an incorrect - // hash in case any error occurs. - var indexBuf []byte - for i := 1; i < list.Len() && i <= 0x7f; i++ { - indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) - value := encodeForDerive(list, i, valueBuf) - hasher.Update(indexBuf, value) - } - if list.Len() > 0 { - indexBuf = rlp.AppendUint64(indexBuf[:0], 0) - value := encodeForDerive(list, 0, valueBuf) - hasher.Update(indexBuf, value) - } - for i := 0x80; i < list.Len(); i++ { - indexBuf = rlp.AppendUint64(indexBuf[:0], uint64(i)) - value := encodeForDerive(list, i, valueBuf) - hasher.Update(indexBuf, value) - } - return hasher.Hash() -} diff --git a/core/types/log.go b/core/types/log.go deleted file mode 100644 index fc7e42f295..0000000000 --- a/core/types/log.go +++ /dev/null @@ -1,80 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -type Log -out gen_log_rlp.go -//go:generate go run github.com/fjl/gencodec -type Log -field-override logMarshaling -out gen_log_json.go - -// Log represents a contract log event. These events are generated by the LOG opcode and -// stored/indexed by the node. -type Log struct { - // Consensus fields: - // address of the contract that generated the event - Address common.Address `json:"address" gencodec:"required"` - // list of topics provided by the contract. - Topics []common.Hash `json:"topics" gencodec:"required"` - // supplied by the contract, usually ABI-encoded - Data []byte `json:"data" gencodec:"required"` - - // Derived fields. These fields are filled in by the node - // but not secured by consensus. - // block in which the transaction was included - BlockNumber uint64 `json:"blockNumber" rlp:"-"` - // hash of the transaction - TxHash common.Hash `json:"transactionHash" gencodec:"required" rlp:"-"` - // index of the transaction in the block - TxIndex uint `json:"transactionIndex" rlp:"-"` - // hash of the block in which the transaction was included - BlockHash common.Hash `json:"blockHash" rlp:"-"` - // index of the log in the block - Index uint `json:"logIndex" rlp:"-"` - - // The Removed field is true if this log was reverted due to a chain reorganisation. - // You must pay attention to this field if you receive logs through a filter query. - Removed bool `json:"removed" rlp:"-"` -} - -type logMarshaling struct { - Data hexutil.Bytes - BlockNumber hexutil.Uint64 - TxIndex hexutil.Uint - Index hexutil.Uint -} - -// FlattenLogs converts a nested array of logs to a single array of logs. -func FlattenLogs(list [][]*Log) []*Log { - var flat []*Log - for _, logs := range list { - flat = append(flat, logs...) - } - return flat -} diff --git a/core/types/receipt.go b/core/types/receipt.go deleted file mode 100644 index 1686b8d217..0000000000 --- a/core/types/receipt.go +++ /dev/null @@ -1,387 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "errors" - "fmt" - "io" - "math/big" - "unsafe" - - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -//go:generate go run github.com/fjl/gencodec -type Receipt -field-override receiptMarshaling -out gen_receipt_json.go - -var ( - receiptStatusFailedRLP = []byte{} - receiptStatusSuccessfulRLP = []byte{0x01} -) - -var errShortTypedReceipt = errors.New("typed receipt too short") - -const ( - // ReceiptStatusFailed is the status code of a transaction if execution failed. - ReceiptStatusFailed = uint64(0) - - // ReceiptStatusSuccessful is the status code of a transaction if execution succeeded. - ReceiptStatusSuccessful = uint64(1) -) - -// Receipt represents the results of a transaction. -type Receipt struct { - // Consensus fields: These fields are defined by the Yellow Paper - Type uint8 `json:"type,omitempty"` - PostState []byte `json:"root"` - Status uint64 `json:"status"` - CumulativeGasUsed uint64 `json:"cumulativeGasUsed" gencodec:"required"` - Bloom Bloom `json:"logsBloom" gencodec:"required"` - Logs []*Log `json:"logs" gencodec:"required"` - - // Implementation fields: These fields are added by geth when processing a transaction. - TxHash common.Hash `json:"transactionHash" gencodec:"required"` - ContractAddress common.Address `json:"contractAddress"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - EffectiveGasPrice *big.Int `json:"effectiveGasPrice"` // required, but tag omitted for backwards compatibility - BlobGasUsed uint64 `json:"blobGasUsed,omitempty"` - BlobGasPrice *big.Int `json:"blobGasPrice,omitempty"` - - // Inclusion information: These fields provide information about the inclusion of the - // transaction corresponding to this receipt. - BlockHash common.Hash `json:"blockHash,omitempty"` - BlockNumber *big.Int `json:"blockNumber,omitempty"` - TransactionIndex uint `json:"transactionIndex"` -} - -type receiptMarshaling struct { - Type hexutil.Uint64 - PostState hexutil.Bytes - Status hexutil.Uint64 - CumulativeGasUsed hexutil.Uint64 - GasUsed hexutil.Uint64 - EffectiveGasPrice *hexutil.Big - BlobGasUsed hexutil.Uint64 - BlobGasPrice *hexutil.Big - BlockNumber *hexutil.Big - TransactionIndex hexutil.Uint -} - -// receiptRLP is the consensus encoding of a receipt. -type receiptRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - Bloom Bloom - Logs []*Log -} - -// storedReceiptRLP is the storage encoding of a receipt. -type storedReceiptRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - Logs []*Log -} - -// NewReceipt creates a barebone transaction receipt, copying the init fields. -// Deprecated: create receipts using a struct literal instead. -func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt { - r := &Receipt{ - Type: LegacyTxType, - PostState: common.CopyBytes(root), - CumulativeGasUsed: cumulativeGasUsed, - } - if failed { - r.Status = ReceiptStatusFailed - } else { - r.Status = ReceiptStatusSuccessful - } - return r -} - -// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt -// into an RLP stream. If no post state is present, byzantium fork is assumed. -func (r *Receipt) EncodeRLP(w io.Writer) error { - data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} - if r.Type == LegacyTxType { - return rlp.Encode(w, data) - } - buf := encodeBufferPool.Get().(*bytes.Buffer) - defer encodeBufferPool.Put(buf) - buf.Reset() - if err := r.encodeTyped(data, buf); err != nil { - return err - } - return rlp.Encode(w, buf.Bytes()) -} - -// encodeTyped writes the canonical encoding of a typed receipt to w. -func (r *Receipt) encodeTyped(data *receiptRLP, w *bytes.Buffer) error { - w.WriteByte(r.Type) - return rlp.Encode(w, data) -} - -// MarshalBinary returns the consensus encoding of the receipt. -func (r *Receipt) MarshalBinary() ([]byte, error) { - if r.Type == LegacyTxType { - return rlp.EncodeToBytes(r) - } - data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} - var buf bytes.Buffer - err := r.encodeTyped(data, &buf) - return buf.Bytes(), err -} - -// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a receipt -// from an RLP stream. -func (r *Receipt) DecodeRLP(s *rlp.Stream) error { - kind, size, err := s.Kind() - switch { - case err != nil: - return err - case kind == rlp.List: - // It's a legacy receipt. - var dec receiptRLP - if err := s.Decode(&dec); err != nil { - return err - } - r.Type = LegacyTxType - return r.setFromRLP(dec) - case kind == rlp.Byte: - return errShortTypedReceipt - default: - // It's an EIP-2718 typed tx receipt. - b, buf, err := getPooledBuffer(size) - if err != nil { - return err - } - defer encodeBufferPool.Put(buf) - if err := s.ReadBytes(b); err != nil { - return err - } - return r.decodeTyped(b) - } -} - -// UnmarshalBinary decodes the consensus encoding of receipts. -// It supports legacy RLP receipts and EIP-2718 typed receipts. -func (r *Receipt) UnmarshalBinary(b []byte) error { - if len(b) > 0 && b[0] > 0x7f { - // It's a legacy receipt decode the RLP - var data receiptRLP - err := rlp.DecodeBytes(b, &data) - if err != nil { - return err - } - r.Type = LegacyTxType - return r.setFromRLP(data) - } - // It's an EIP2718 typed transaction envelope. - return r.decodeTyped(b) -} - -// decodeTyped decodes a typed receipt from the canonical format. -func (r *Receipt) decodeTyped(b []byte) error { - if len(b) <= 1 { - return errShortTypedReceipt - } - switch b[0] { - case DynamicFeeTxType, AccessListTxType, BlobTxType: - var data receiptRLP - err := rlp.DecodeBytes(b[1:], &data) - if err != nil { - return err - } - r.Type = b[0] - return r.setFromRLP(data) - default: - return ErrTxTypeNotSupported - } -} - -func (r *Receipt) setFromRLP(data receiptRLP) error { - r.CumulativeGasUsed, r.Bloom, r.Logs = data.CumulativeGasUsed, data.Bloom, data.Logs - return r.setStatus(data.PostStateOrStatus) -} - -func (r *Receipt) setStatus(postStateOrStatus []byte) error { - switch { - case bytes.Equal(postStateOrStatus, receiptStatusSuccessfulRLP): - r.Status = ReceiptStatusSuccessful - case bytes.Equal(postStateOrStatus, receiptStatusFailedRLP): - r.Status = ReceiptStatusFailed - case len(postStateOrStatus) == len(common.Hash{}): - r.PostState = postStateOrStatus - default: - return fmt.Errorf("invalid receipt status %x", postStateOrStatus) - } - return nil -} - -func (r *Receipt) statusEncoding() []byte { - if len(r.PostState) == 0 { - if r.Status == ReceiptStatusFailed { - return receiptStatusFailedRLP - } - return receiptStatusSuccessfulRLP - } - return r.PostState -} - -// Size returns the approximate memory used by all internal contents. It is used -// to approximate and limit the memory consumption of various caches. -func (r *Receipt) Size() common.StorageSize { - size := common.StorageSize(unsafe.Sizeof(*r)) + common.StorageSize(len(r.PostState)) - size += common.StorageSize(len(r.Logs)) * common.StorageSize(unsafe.Sizeof(Log{})) - for _, log := range r.Logs { - size += common.StorageSize(len(log.Topics)*common.HashLength + len(log.Data)) - } - return size -} - -// ReceiptForStorage is a wrapper around a Receipt with RLP serialization -// that omits the Bloom field and deserialization that re-computes it. -type ReceiptForStorage Receipt - -// EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt -// into an RLP stream. -func (r *ReceiptForStorage) EncodeRLP(_w io.Writer) error { - w := rlp.NewEncoderBuffer(_w) - outerList := w.List() - w.WriteBytes((*Receipt)(r).statusEncoding()) - w.WriteUint64(r.CumulativeGasUsed) - logList := w.List() - for _, log := range r.Logs { - if err := log.EncodeRLP(w); err != nil { - return err - } - } - w.ListEnd(logList) - w.ListEnd(outerList) - return w.Flush() -} - -// DecodeRLP implements rlp.Decoder, and loads both consensus and implementation -// fields of a receipt from an RLP stream. -func (r *ReceiptForStorage) DecodeRLP(s *rlp.Stream) error { - var stored storedReceiptRLP - if err := s.Decode(&stored); err != nil { - return err - } - if err := (*Receipt)(r).setStatus(stored.PostStateOrStatus); err != nil { - return err - } - r.CumulativeGasUsed = stored.CumulativeGasUsed - r.Logs = stored.Logs - r.Bloom = CreateBloom(Receipts{(*Receipt)(r)}) - - return nil -} - -// Receipts implements DerivableList for receipts. -type Receipts []*Receipt - -// Len returns the number of receipts in this list. -func (rs Receipts) Len() int { return len(rs) } - -// EncodeIndex encodes the i'th receipt to w. -func (rs Receipts) EncodeIndex(i int, w *bytes.Buffer) { - r := rs[i] - data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} - if r.Type == LegacyTxType { - rlp.Encode(w, data) - return - } - w.WriteByte(r.Type) - switch r.Type { - case AccessListTxType, DynamicFeeTxType, BlobTxType: - rlp.Encode(w, data) - default: - // For unsupported types, write nothing. Since this is for - // DeriveSha, the error will be caught matching the derived hash - // to the block. - } -} - -// DeriveFields fills the receipts with their computed fields based on consensus -// data and contextual infos like containing block and transactions. -func (rs Receipts) DeriveFields(config *params.ChainConfig, hash common.Hash, number uint64, time uint64, baseFee *big.Int, blobGasPrice *big.Int, txs []*Transaction) error { - signer := MakeSigner(config, new(big.Int).SetUint64(number), time) - - logIndex := uint(0) - if len(txs) != len(rs) { - return errors.New("transaction and receipt count mismatch") - } - for i := 0; i < len(rs); i++ { - // The transaction type and hash can be retrieved from the transaction itself - rs[i].Type = txs[i].Type() - rs[i].TxHash = txs[i].Hash() - rs[i].EffectiveGasPrice = txs[i].inner.effectiveGasPrice(new(big.Int), baseFee) - - // EIP-4844 blob transaction fields - if txs[i].Type() == BlobTxType { - rs[i].BlobGasUsed = txs[i].BlobGas() - rs[i].BlobGasPrice = blobGasPrice - } - - // block location fields - rs[i].BlockHash = hash - rs[i].BlockNumber = new(big.Int).SetUint64(number) - rs[i].TransactionIndex = uint(i) - - // The contract address can be derived from the transaction itself - if txs[i].To() == nil { - // Deriving the signer is expensive, only do if it's actually needed - from, _ := Sender(signer, txs[i]) - rs[i].ContractAddress = crypto.CreateAddress(from, txs[i].Nonce()) - } else { - rs[i].ContractAddress = common.Address{} - } - - // The used gas can be calculated based on previous r - if i == 0 { - rs[i].GasUsed = rs[i].CumulativeGasUsed - } else { - rs[i].GasUsed = rs[i].CumulativeGasUsed - rs[i-1].CumulativeGasUsed - } - - // The derived log fields can simply be set from the block and transaction - for j := 0; j < len(rs[i].Logs); j++ { - rs[i].Logs[j].BlockNumber = number - rs[i].Logs[j].BlockHash = hash - rs[i].Logs[j].TxHash = rs[i].TxHash - rs[i].Logs[j].TxIndex = uint(i) - rs[i].Logs[j].Index = logIndex - logIndex++ - } - } - return nil -} diff --git a/core/types/receipt_test.go b/core/types/receipt_test.go deleted file mode 100644 index 32da193c60..0000000000 --- a/core/types/receipt_test.go +++ /dev/null @@ -1,539 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "encoding/json" - "math" - "math/big" - "reflect" - "testing" - - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - "github.com/holiman/uint256" - "github.com/kylelemons/godebug/diff" -) - -var ( - legacyReceipt = &Receipt{ - Status: ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*Log{ - { - Address: common.BytesToAddress([]byte{0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - Data: []byte{0x01, 0x00, 0xff}, - }, - { - Address: common.BytesToAddress([]byte{0x01, 0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - Data: []byte{0x01, 0x00, 0xff}, - }, - }, - } - accessListReceipt = &Receipt{ - Status: ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*Log{ - { - Address: common.BytesToAddress([]byte{0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - Data: []byte{0x01, 0x00, 0xff}, - }, - { - Address: common.BytesToAddress([]byte{0x01, 0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - Data: []byte{0x01, 0x00, 0xff}, - }, - }, - Type: AccessListTxType, - } - eip1559Receipt = &Receipt{ - Status: ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*Log{ - { - Address: common.BytesToAddress([]byte{0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - Data: []byte{0x01, 0x00, 0xff}, - }, - { - Address: common.BytesToAddress([]byte{0x01, 0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - Data: []byte{0x01, 0x00, 0xff}, - }, - }, - Type: DynamicFeeTxType, - } - - // Create a few transactions to have receipts for - to2 = common.HexToAddress("0x2") - to3 = common.HexToAddress("0x3") - to4 = common.HexToAddress("0x4") - to5 = common.HexToAddress("0x5") - to6 = common.HexToAddress("0x6") - to7 = common.HexToAddress("0x7") - txs = Transactions{ - NewTx(&LegacyTx{ - Nonce: 1, - Value: big.NewInt(1), - Gas: 1, - GasPrice: big.NewInt(11), - }), - NewTx(&LegacyTx{ - To: &to2, - Nonce: 2, - Value: big.NewInt(2), - Gas: 2, - GasPrice: big.NewInt(22), - }), - NewTx(&AccessListTx{ - To: &to3, - Nonce: 3, - Value: big.NewInt(3), - Gas: 3, - GasPrice: big.NewInt(33), - }), - // EIP-1559 transactions. - NewTx(&DynamicFeeTx{ - To: &to4, - Nonce: 4, - Value: big.NewInt(4), - Gas: 4, - GasTipCap: big.NewInt(44), - GasFeeCap: big.NewInt(1044), - }), - NewTx(&DynamicFeeTx{ - To: &to5, - Nonce: 5, - Value: big.NewInt(5), - Gas: 5, - GasTipCap: big.NewInt(55), - GasFeeCap: big.NewInt(1055), - }), - // EIP-4844 transactions. - NewTx(&BlobTx{ - To: to6, - Nonce: 6, - Value: uint256.NewInt(6), - Gas: 6, - GasTipCap: uint256.NewInt(66), - GasFeeCap: uint256.NewInt(1066), - BlobFeeCap: uint256.NewInt(100066), - BlobHashes: []common.Hash{{}}, - }), - NewTx(&BlobTx{ - To: to7, - Nonce: 7, - Value: uint256.NewInt(7), - Gas: 7, - GasTipCap: uint256.NewInt(77), - GasFeeCap: uint256.NewInt(1077), - BlobFeeCap: uint256.NewInt(100077), - BlobHashes: []common.Hash{{}, {}, {}}, - }), - } - - blockNumber = big.NewInt(1) - blockTime = uint64(2) - blockHash = common.BytesToHash([]byte{0x03, 0x14}) - - // Create the corresponding receipts - receipts = Receipts{ - &Receipt{ - Status: ReceiptStatusFailed, - CumulativeGasUsed: 1, - Logs: []*Log{ - { - Address: common.BytesToAddress([]byte{0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[0].Hash(), - TxIndex: 0, - BlockHash: blockHash, - Index: 0, - }, - { - Address: common.BytesToAddress([]byte{0x01, 0x11}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[0].Hash(), - TxIndex: 0, - BlockHash: blockHash, - Index: 1, - }, - }, - // derived fields: - TxHash: txs[0].Hash(), - ContractAddress: common.HexToAddress("0x5a443704dd4b594b382c22a083e2bd3090a6fef3"), - GasUsed: 1, - EffectiveGasPrice: big.NewInt(11), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 0, - }, - &Receipt{ - PostState: common.Hash{2}.Bytes(), - CumulativeGasUsed: 3, - Logs: []*Log{ - { - Address: common.BytesToAddress([]byte{0x22}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[1].Hash(), - TxIndex: 1, - BlockHash: blockHash, - Index: 2, - }, - { - Address: common.BytesToAddress([]byte{0x02, 0x22}), - Topics: []common.Hash{common.HexToHash("dead"), common.HexToHash("beef")}, - // derived fields: - BlockNumber: blockNumber.Uint64(), - TxHash: txs[1].Hash(), - TxIndex: 1, - BlockHash: blockHash, - Index: 3, - }, - }, - // derived fields: - TxHash: txs[1].Hash(), - GasUsed: 2, - EffectiveGasPrice: big.NewInt(22), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 1, - }, - &Receipt{ - Type: AccessListTxType, - PostState: common.Hash{3}.Bytes(), - CumulativeGasUsed: 6, - Logs: []*Log{}, - // derived fields: - TxHash: txs[2].Hash(), - GasUsed: 3, - EffectiveGasPrice: big.NewInt(33), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 2, - }, - &Receipt{ - Type: DynamicFeeTxType, - PostState: common.Hash{4}.Bytes(), - CumulativeGasUsed: 10, - Logs: []*Log{}, - // derived fields: - TxHash: txs[3].Hash(), - GasUsed: 4, - EffectiveGasPrice: big.NewInt(1044), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 3, - }, - &Receipt{ - Type: DynamicFeeTxType, - PostState: common.Hash{5}.Bytes(), - CumulativeGasUsed: 15, - Logs: []*Log{}, - // derived fields: - TxHash: txs[4].Hash(), - GasUsed: 5, - EffectiveGasPrice: big.NewInt(1055), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 4, - }, - &Receipt{ - Type: BlobTxType, - PostState: common.Hash{6}.Bytes(), - CumulativeGasUsed: 21, - Logs: []*Log{}, - // derived fields: - TxHash: txs[5].Hash(), - GasUsed: 6, - EffectiveGasPrice: big.NewInt(1066), - BlobGasUsed: params.BlobTxBlobGasPerBlob, - BlobGasPrice: big.NewInt(920), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 5, - }, - &Receipt{ - Type: BlobTxType, - PostState: common.Hash{7}.Bytes(), - CumulativeGasUsed: 28, - Logs: []*Log{}, - // derived fields: - TxHash: txs[6].Hash(), - GasUsed: 7, - EffectiveGasPrice: big.NewInt(1077), - BlobGasUsed: 3 * params.BlobTxBlobGasPerBlob, - BlobGasPrice: big.NewInt(920), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: 6, - }, - } -) - -func TestDecodeEmptyTypedReceipt(t *testing.T) { - input := []byte{0x80} - var r Receipt - err := rlp.DecodeBytes(input, &r) - if err != errShortTypedReceipt { - t.Fatal("wrong error:", err) - } -} - -// Tests that receipt data can be correctly derived from the contextual infos -func TestDeriveFields(t *testing.T) { - // Re-derive receipts. - basefee := big.NewInt(1000) - blobGasPrice := big.NewInt(920) - derivedReceipts := clearComputedFieldsOnReceipts(receipts) - err := Receipts(derivedReceipts).DeriveFields(params.TestChainConfig, blockHash, blockNumber.Uint64(), blockTime, basefee, blobGasPrice, txs) - if err != nil { - t.Fatalf("DeriveFields(...) = %v, want ", err) - } - - // Check diff of receipts against derivedReceipts. - r1, err := json.MarshalIndent(receipts, "", " ") - if err != nil { - t.Fatal("error marshaling input receipts:", err) - } - - r2, err := json.MarshalIndent(derivedReceipts, "", " ") - if err != nil { - t.Fatal("error marshaling derived receipts:", err) - } - d := diff.Diff(string(r1), string(r2)) - if d != "" { - t.Fatal("receipts differ:", d) - } -} - -// Test that we can marshal/unmarshal receipts to/from json without errors. -// This also confirms that our test receipts contain all the required fields. -func TestReceiptJSON(t *testing.T) { - for i := range receipts { - b, err := receipts[i].MarshalJSON() - if err != nil { - t.Fatal("error marshaling receipt to json:", err) - } - r := Receipt{} - err = r.UnmarshalJSON(b) - if err != nil { - t.Fatal("error unmarshaling receipt from json:", err) - } - } -} - -// Test we can still parse receipt without EffectiveGasPrice for backwards compatibility, even -// though it is required per the spec. -func TestEffectiveGasPriceNotRequired(t *testing.T) { - r := *receipts[0] - r.EffectiveGasPrice = nil - b, err := r.MarshalJSON() - if err != nil { - t.Fatal("error marshaling receipt to json:", err) - } - r2 := Receipt{} - err = r2.UnmarshalJSON(b) - if err != nil { - t.Fatal("error unmarshaling receipt from json:", err) - } -} - -// TestTypedReceiptEncodingDecoding reproduces a flaw that existed in the receipt -// rlp decoder, which failed due to a shadowing error. -func TestTypedReceiptEncodingDecoding(t *testing.T) { - var payload = common.FromHex("f9043eb9010c01f90108018262d4b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b9010c01f901080182cd14b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b9010d01f901090183013754b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0b9010d01f90109018301a194b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0") - check := func(bundle []*Receipt) { - t.Helper() - for i, receipt := range bundle { - if got, want := receipt.Type, uint8(1); got != want { - t.Fatalf("bundle %d: got %x, want %x", i, got, want) - } - } - } - { - var bundle []*Receipt - rlp.DecodeBytes(payload, &bundle) - check(bundle) - } - { - var bundle []*Receipt - r := bytes.NewReader(payload) - s := rlp.NewStream(r, uint64(len(payload))) - if err := s.Decode(&bundle); err != nil { - t.Fatal(err) - } - check(bundle) - } -} - -func TestReceiptMarshalBinary(t *testing.T) { - // Legacy Receipt - legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt}) - have, err := legacyReceipt.MarshalBinary() - if err != nil { - t.Fatalf("marshal binary error: %v", err) - } - legacyReceipts := Receipts{legacyReceipt} - buf := new(bytes.Buffer) - legacyReceipts.EncodeIndex(0, buf) - haveEncodeIndex := buf.Bytes() - if !bytes.Equal(have, haveEncodeIndex) { - t.Errorf("BinaryMarshal and EncodeIndex mismatch, got %x want %x", have, haveEncodeIndex) - } - buf.Reset() - if err := legacyReceipt.EncodeRLP(buf); err != nil { - t.Fatalf("encode rlp error: %v", err) - } - haveRLPEncode := buf.Bytes() - if !bytes.Equal(have, haveRLPEncode) { - t.Errorf("BinaryMarshal and EncodeRLP mismatch for legacy tx, got %x want %x", have, haveRLPEncode) - } - legacyWant := common.FromHex("f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff") - if !bytes.Equal(have, legacyWant) { - t.Errorf("encoded RLP mismatch, got %x want %x", have, legacyWant) - } - - // 2930 Receipt - buf.Reset() - accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt}) - have, err = accessListReceipt.MarshalBinary() - if err != nil { - t.Fatalf("marshal binary error: %v", err) - } - accessListReceipts := Receipts{accessListReceipt} - accessListReceipts.EncodeIndex(0, buf) - haveEncodeIndex = buf.Bytes() - if !bytes.Equal(have, haveEncodeIndex) { - t.Errorf("BinaryMarshal and EncodeIndex mismatch, got %x want %x", have, haveEncodeIndex) - } - accessListWant := common.FromHex("01f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff") - if !bytes.Equal(have, accessListWant) { - t.Errorf("encoded RLP mismatch, got %x want %x", have, accessListWant) - } - - // 1559 Receipt - buf.Reset() - eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt}) - have, err = eip1559Receipt.MarshalBinary() - if err != nil { - t.Fatalf("marshal binary error: %v", err) - } - eip1559Receipts := Receipts{eip1559Receipt} - eip1559Receipts.EncodeIndex(0, buf) - haveEncodeIndex = buf.Bytes() - if !bytes.Equal(have, haveEncodeIndex) { - t.Errorf("BinaryMarshal and EncodeIndex mismatch, got %x want %x", have, haveEncodeIndex) - } - eip1559Want := common.FromHex("02f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff") - if !bytes.Equal(have, eip1559Want) { - t.Errorf("encoded RLP mismatch, got %x want %x", have, eip1559Want) - } -} - -func TestReceiptUnmarshalBinary(t *testing.T) { - // Legacy Receipt - legacyBinary := common.FromHex("f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff") - gotLegacyReceipt := new(Receipt) - if err := gotLegacyReceipt.UnmarshalBinary(legacyBinary); err != nil { - t.Fatalf("unmarshal binary error: %v", err) - } - legacyReceipt.Bloom = CreateBloom(Receipts{legacyReceipt}) - if !reflect.DeepEqual(gotLegacyReceipt, legacyReceipt) { - t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotLegacyReceipt, legacyReceipt) - } - - // 2930 Receipt - accessListBinary := common.FromHex("01f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff") - gotAccessListReceipt := new(Receipt) - if err := gotAccessListReceipt.UnmarshalBinary(accessListBinary); err != nil { - t.Fatalf("unmarshal binary error: %v", err) - } - accessListReceipt.Bloom = CreateBloom(Receipts{accessListReceipt}) - if !reflect.DeepEqual(gotAccessListReceipt, accessListReceipt) { - t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", gotAccessListReceipt, accessListReceipt) - } - - // 1559 Receipt - eip1559RctBinary := common.FromHex("02f901c58001b9010000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000000000000000010000080000000000000000000004000000000000000000000000000040000000000000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000f8bef85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100fff85d940000000000000000000000000000000000000111f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff") - got1559Receipt := new(Receipt) - if err := got1559Receipt.UnmarshalBinary(eip1559RctBinary); err != nil { - t.Fatalf("unmarshal binary error: %v", err) - } - eip1559Receipt.Bloom = CreateBloom(Receipts{eip1559Receipt}) - if !reflect.DeepEqual(got1559Receipt, eip1559Receipt) { - t.Errorf("receipt unmarshalled from binary mismatch, got %v want %v", got1559Receipt, eip1559Receipt) - } -} - -func clearComputedFieldsOnReceipts(receipts []*Receipt) []*Receipt { - r := make([]*Receipt, len(receipts)) - for i, receipt := range receipts { - r[i] = clearComputedFieldsOnReceipt(receipt) - } - return r -} - -func clearComputedFieldsOnReceipt(receipt *Receipt) *Receipt { - cpy := *receipt - cpy.TxHash = common.Hash{0xff, 0xff, 0x11} - cpy.BlockHash = common.Hash{0xff, 0xff, 0x22} - cpy.BlockNumber = big.NewInt(math.MaxUint32) - cpy.TransactionIndex = math.MaxUint32 - cpy.ContractAddress = common.Address{0xff, 0xff, 0x33} - cpy.GasUsed = 0xffffffff - cpy.Logs = clearComputedFieldsOnLogs(receipt.Logs) - cpy.EffectiveGasPrice = big.NewInt(0) - cpy.BlobGasUsed = 0 - cpy.BlobGasPrice = nil - return &cpy -} - -func clearComputedFieldsOnLogs(logs []*Log) []*Log { - l := make([]*Log, len(logs)) - for i, log := range logs { - cpy := *log - cpy.BlockNumber = math.MaxUint32 - cpy.BlockHash = common.Hash{} - cpy.TxHash = common.Hash{} - cpy.TxIndex = math.MaxUint32 - cpy.Index = math.MaxUint32 - l[i] = &cpy - } - return l -} diff --git a/core/types/state_account.go b/core/types/state_account.go deleted file mode 100644 index 9f8a6108a3..0000000000 --- a/core/types/state_account.go +++ /dev/null @@ -1,135 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" - "github.com/holiman/uint256" -) - -//go:generate go run github.com/ethereum/go-ethereum/rlp/rlpgen -type StateAccount -out gen_account_rlp.go - -// StateAccount is the Ethereum consensus representation of accounts. -// These objects are stored in the main account trie. -type StateAccount struct { - Nonce uint64 - Balance *uint256.Int - Root common.Hash // merkle root of the storage trie - CodeHash []byte - IsMultiCoin bool -} - -// NewEmptyStateAccount constructs an empty state account. -func NewEmptyStateAccount() *StateAccount { - return &StateAccount{ - Balance: new(uint256.Int), - Root: EmptyRootHash, - CodeHash: EmptyCodeHash.Bytes(), - } -} - -// Copy returns a deep-copied state account object. -func (acct *StateAccount) Copy() *StateAccount { - var balance *uint256.Int - if acct.Balance != nil { - balance = new(uint256.Int).Set(acct.Balance) - } - return &StateAccount{ - Nonce: acct.Nonce, - Balance: balance, - Root: acct.Root, - CodeHash: common.CopyBytes(acct.CodeHash), - IsMultiCoin: acct.IsMultiCoin, - } -} - -// SlimAccount is a modified version of an Account, where the root is replaced -// with a byte slice. This format can be used to represent full-consensus format -// or slim format which replaces the empty root and code hash as nil byte slice. -type SlimAccount struct { - Nonce uint64 - Balance *uint256.Int - Root []byte // Nil if root equals to types.EmptyRootHash - CodeHash []byte // Nil if hash equals to types.EmptyCodeHash - IsMultiCoin bool -} - -// SlimAccountRLP encodes the state account in 'slim RLP' format. -func SlimAccountRLP(account StateAccount) []byte { - slim := SlimAccount{ - Nonce: account.Nonce, - Balance: account.Balance, - IsMultiCoin: account.IsMultiCoin, - } - if account.Root != EmptyRootHash { - slim.Root = account.Root[:] - } - if !bytes.Equal(account.CodeHash, EmptyCodeHash[:]) { - slim.CodeHash = account.CodeHash - } - data, err := rlp.EncodeToBytes(slim) - if err != nil { - panic(err) - } - return data -} - -// FullAccount decodes the data on the 'slim RLP' format and returns -// the consensus format account. -func FullAccount(data []byte) (*StateAccount, error) { - var slim SlimAccount - if err := rlp.DecodeBytes(data, &slim); err != nil { - return nil, err - } - var account StateAccount - account.Nonce, account.Balance, account.IsMultiCoin = slim.Nonce, slim.Balance, slim.IsMultiCoin - - // Interpret the storage root and code hash in slim format. - if len(slim.Root) == 0 { - account.Root = EmptyRootHash - } else { - account.Root = common.BytesToHash(slim.Root) - } - if len(slim.CodeHash) == 0 { - account.CodeHash = EmptyCodeHash[:] - } else { - account.CodeHash = slim.CodeHash - } - return &account, nil -} - -// FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format. -func FullAccountRLP(data []byte) ([]byte, error) { - account, err := FullAccount(data) - if err != nil { - return nil, err - } - return rlp.EncodeToBytes(account) -} diff --git a/core/types/transaction.go b/core/types/transaction.go deleted file mode 100644 index 35602becae..0000000000 --- a/core/types/transaction.go +++ /dev/null @@ -1,601 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "errors" - "fmt" - "io" - "math/big" - "sync/atomic" - "time" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -var ( - ErrInvalidSig = errors.New("invalid transaction v, r, s values") - ErrUnexpectedProtection = errors.New("transaction type does not supported EIP-155 protected signatures") - ErrInvalidTxType = errors.New("transaction type not valid in this context") - ErrTxTypeNotSupported = errors.New("transaction type not supported") - ErrGasFeeCapTooLow = errors.New("fee cap less than base fee") - errShortTypedTx = errors.New("typed transaction too short") - errInvalidYParity = errors.New("'yParity' field must be 0 or 1") - errVYParityMismatch = errors.New("'v' and 'yParity' fields do not match") - errVYParityMissing = errors.New("missing 'yParity' or 'v' field in transaction") -) - -// Transaction types. -const ( - LegacyTxType = 0x00 - AccessListTxType = 0x01 - DynamicFeeTxType = 0x02 - BlobTxType = 0x03 -) - -// Transaction is an Ethereum transaction. -type Transaction struct { - inner TxData // Consensus contents of a transaction - time time.Time // Time first seen locally (spam avoidance) - - // caches - hash atomic.Value - size atomic.Value - from atomic.Value -} - -// NewTx creates a new transaction. -func NewTx(inner TxData) *Transaction { - tx := new(Transaction) - tx.setDecoded(inner.copy(), 0) - return tx -} - -// TxData is the underlying data of a transaction. -// -// This is implemented by DynamicFeeTx, LegacyTx and AccessListTx. -type TxData interface { - txType() byte // returns the type ID - copy() TxData // creates a deep copy and initializes all fields - - chainID() *big.Int - accessList() AccessList - data() []byte - gas() uint64 - gasPrice() *big.Int - gasTipCap() *big.Int - gasFeeCap() *big.Int - value() *big.Int - nonce() uint64 - to() *common.Address - - rawSignatureValues() (v, r, s *big.Int) - setSignatureValues(chainID, v, r, s *big.Int) - - // effectiveGasPrice computes the gas price paid by the transaction, given - // the inclusion block baseFee. - // - // Unlike other TxData methods, the returned *big.Int should be an independent - // copy of the computed value, i.e. callers are allowed to mutate the result. - // Method implementations can use 'dst' to store the result. - effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int - - encode(*bytes.Buffer) error - decode([]byte) error -} - -// EncodeRLP implements rlp.Encoder -func (tx *Transaction) EncodeRLP(w io.Writer) error { - if tx.Type() == LegacyTxType { - return rlp.Encode(w, tx.inner) - } - // It's an EIP-2718 typed TX envelope. - buf := encodeBufferPool.Get().(*bytes.Buffer) - defer encodeBufferPool.Put(buf) - buf.Reset() - if err := tx.encodeTyped(buf); err != nil { - return err - } - return rlp.Encode(w, buf.Bytes()) -} - -// encodeTyped writes the canonical encoding of a typed transaction to w. -func (tx *Transaction) encodeTyped(w *bytes.Buffer) error { - w.WriteByte(tx.Type()) - return tx.inner.encode(w) -} - -// MarshalBinary returns the canonical encoding of the transaction. -// For legacy transactions, it returns the RLP encoding. For EIP-2718 typed -// transactions, it returns the type and payload. -func (tx *Transaction) MarshalBinary() ([]byte, error) { - if tx.Type() == LegacyTxType { - return rlp.EncodeToBytes(tx.inner) - } - var buf bytes.Buffer - err := tx.encodeTyped(&buf) - return buf.Bytes(), err -} - -// DecodeRLP implements rlp.Decoder -func (tx *Transaction) DecodeRLP(s *rlp.Stream) error { - kind, size, err := s.Kind() - switch { - case err != nil: - return err - case kind == rlp.List: - // It's a legacy transaction. - var inner LegacyTx - err := s.Decode(&inner) - if err == nil { - tx.setDecoded(&inner, rlp.ListSize(size)) - } - return err - case kind == rlp.Byte: - return errShortTypedTx - default: - // It's an EIP-2718 typed TX envelope. - // First read the tx payload bytes into a temporary buffer. - b, buf, err := getPooledBuffer(size) - if err != nil { - return err - } - defer encodeBufferPool.Put(buf) - if err := s.ReadBytes(b); err != nil { - return err - } - // Now decode the inner transaction. - inner, err := tx.decodeTyped(b) - if err == nil { - tx.setDecoded(inner, size) - } - return err - } -} - -// UnmarshalBinary decodes the canonical encoding of transactions. -// It supports legacy RLP transactions and EIP-2718 typed transactions. -func (tx *Transaction) UnmarshalBinary(b []byte) error { - if len(b) > 0 && b[0] > 0x7f { - // It's a legacy transaction. - var data LegacyTx - err := rlp.DecodeBytes(b, &data) - if err != nil { - return err - } - tx.setDecoded(&data, uint64(len(b))) - return nil - } - // It's an EIP-2718 typed transaction envelope. - inner, err := tx.decodeTyped(b) - if err != nil { - return err - } - tx.setDecoded(inner, uint64(len(b))) - return nil -} - -// decodeTyped decodes a typed transaction from the canonical format. -func (tx *Transaction) decodeTyped(b []byte) (TxData, error) { - if len(b) <= 1 { - return nil, errShortTypedTx - } - var inner TxData - switch b[0] { - case AccessListTxType: - inner = new(AccessListTx) - case DynamicFeeTxType: - inner = new(DynamicFeeTx) - case BlobTxType: - inner = new(BlobTx) - default: - return nil, ErrTxTypeNotSupported - } - err := inner.decode(b[1:]) - return inner, err -} - -// setDecoded sets the inner transaction and size after decoding. -func (tx *Transaction) setDecoded(inner TxData, size uint64) { - tx.inner = inner - tx.time = time.Now() - if size > 0 { - tx.size.Store(size) - } -} - -func sanityCheckSignature(v *big.Int, r *big.Int, s *big.Int, maybeProtected bool) error { - if isProtectedV(v) && !maybeProtected { - return ErrUnexpectedProtection - } - - var plainV byte - if isProtectedV(v) { - chainID := deriveChainId(v).Uint64() - plainV = byte(v.Uint64() - 35 - 2*chainID) - } else if maybeProtected { - // Only EIP-155 signatures can be optionally protected. Since - // we determined this v value is not protected, it must be a - // raw 27 or 28. - plainV = byte(v.Uint64() - 27) - } else { - // If the signature is not optionally protected, we assume it - // must already be equal to the recovery id. - plainV = byte(v.Uint64()) - } - if !crypto.ValidateSignatureValues(plainV, r, s, false) { - return ErrInvalidSig - } - - return nil -} - -func isProtectedV(V *big.Int) bool { - if V.BitLen() <= 8 { - v := V.Uint64() - return v != 27 && v != 28 && v != 1 && v != 0 - } - // anything not 27 or 28 is considered protected - return true -} - -// Protected says whether the transaction is replay-protected. -func (tx *Transaction) Protected() bool { - switch tx := tx.inner.(type) { - case *LegacyTx: - return tx.V != nil && isProtectedV(tx.V) - default: - return true - } -} - -// Type returns the transaction type. -func (tx *Transaction) Type() uint8 { - return tx.inner.txType() -} - -// ChainId returns the EIP155 chain ID of the transaction. The return value will always be -// non-nil. For legacy transactions which are not replay-protected, the return value is -// zero. -func (tx *Transaction) ChainId() *big.Int { - return tx.inner.chainID() -} - -// Data returns the input data of the transaction. -func (tx *Transaction) Data() []byte { return tx.inner.data() } - -// AccessList returns the access list of the transaction. -func (tx *Transaction) AccessList() AccessList { return tx.inner.accessList() } - -// Gas returns the gas limit of the transaction. -func (tx *Transaction) Gas() uint64 { return tx.inner.gas() } - -// GasPrice returns the gas price of the transaction. -func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.inner.gasPrice()) } - -// GasTipCap returns the gasTipCap per gas of the transaction. -func (tx *Transaction) GasTipCap() *big.Int { return new(big.Int).Set(tx.inner.gasTipCap()) } - -// GasFeeCap returns the fee cap per gas of the transaction. -func (tx *Transaction) GasFeeCap() *big.Int { return new(big.Int).Set(tx.inner.gasFeeCap()) } - -// Value returns the ether amount of the transaction. -func (tx *Transaction) Value() *big.Int { return new(big.Int).Set(tx.inner.value()) } - -// Nonce returns the sender account nonce of the transaction. -func (tx *Transaction) Nonce() uint64 { return tx.inner.nonce() } - -// To returns the recipient address of the transaction. -// For contract-creation transactions, To returns nil. -func (tx *Transaction) To() *common.Address { - return copyAddressPtr(tx.inner.to()) -} - -// Cost returns (gas * gasPrice) + (blobGas * blobGasPrice) + value. -func (tx *Transaction) Cost() *big.Int { - total := new(big.Int).Mul(tx.GasPrice(), new(big.Int).SetUint64(tx.Gas())) - if tx.Type() == BlobTxType { - total.Add(total, new(big.Int).Mul(tx.BlobGasFeeCap(), new(big.Int).SetUint64(tx.BlobGas()))) - } - total.Add(total, tx.Value()) - return total -} - -// RawSignatureValues returns the V, R, S signature values of the transaction. -// The return values should not be modified by the caller. -// The return values may be nil or zero, if the transaction is unsigned. -func (tx *Transaction) RawSignatureValues() (v, r, s *big.Int) { - return tx.inner.rawSignatureValues() -} - -// GasFeeCapCmp compares the fee cap of two transactions. -func (tx *Transaction) GasFeeCapCmp(other *Transaction) int { - return tx.inner.gasFeeCap().Cmp(other.inner.gasFeeCap()) -} - -// GasFeeCapIntCmp compares the fee cap of the transaction against the given fee cap. -func (tx *Transaction) GasFeeCapIntCmp(other *big.Int) int { - return tx.inner.gasFeeCap().Cmp(other) -} - -// GasTipCapCmp compares the gasTipCap of two transactions. -func (tx *Transaction) GasTipCapCmp(other *Transaction) int { - return tx.inner.gasTipCap().Cmp(other.inner.gasTipCap()) -} - -// GasTipCapIntCmp compares the gasTipCap of the transaction against the given gasTipCap. -func (tx *Transaction) GasTipCapIntCmp(other *big.Int) int { - return tx.inner.gasTipCap().Cmp(other) -} - -// EffectiveGasTip returns the effective miner gasTipCap for the given base fee. -// Note: if the effective gasTipCap is negative, this method returns both error -// the actual negative value, _and_ ErrGasFeeCapTooLow -func (tx *Transaction) EffectiveGasTip(baseFee *big.Int) (*big.Int, error) { - if baseFee == nil { - return tx.GasTipCap(), nil - } - var err error - gasFeeCap := tx.GasFeeCap() - if gasFeeCap.Cmp(baseFee) == -1 { - err = ErrGasFeeCapTooLow - } - return math.BigMin(tx.GasTipCap(), gasFeeCap.Sub(gasFeeCap, baseFee)), err -} - -// EffectiveGasTipValue is identical to EffectiveGasTip, but does not return an -// error in case the effective gasTipCap is negative -func (tx *Transaction) EffectiveGasTipValue(baseFee *big.Int) *big.Int { - effectiveTip, _ := tx.EffectiveGasTip(baseFee) - return effectiveTip -} - -// EffectiveGasTipCmp compares the effective gasTipCap of two transactions assuming the given base fee. -func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *big.Int) int { - if baseFee == nil { - return tx.GasTipCapCmp(other) - } - return tx.EffectiveGasTipValue(baseFee).Cmp(other.EffectiveGasTipValue(baseFee)) -} - -// EffectiveGasTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap. -func (tx *Transaction) EffectiveGasTipIntCmp(other *big.Int, baseFee *big.Int) int { - if baseFee == nil { - return tx.GasTipCapIntCmp(other) - } - return tx.EffectiveGasTipValue(baseFee).Cmp(other) -} - -// BlobGas returns the blob gas limit of the transaction for blob transactions, 0 otherwise. -func (tx *Transaction) BlobGas() uint64 { - if blobtx, ok := tx.inner.(*BlobTx); ok { - return blobtx.blobGas() - } - return 0 -} - -// BlobGasFeeCap returns the blob gas fee cap per blob gas of the transaction for blob transactions, nil otherwise. -func (tx *Transaction) BlobGasFeeCap() *big.Int { - if blobtx, ok := tx.inner.(*BlobTx); ok { - return blobtx.BlobFeeCap.ToBig() - } - return nil -} - -// BlobHashes returns the hashes of the blob commitments for blob transactions, nil otherwise. -func (tx *Transaction) BlobHashes() []common.Hash { - if blobtx, ok := tx.inner.(*BlobTx); ok { - return blobtx.BlobHashes - } - return nil -} - -// BlobTxSidecar returns the sidecar of a blob transaction, nil otherwise. -func (tx *Transaction) BlobTxSidecar() *BlobTxSidecar { - if blobtx, ok := tx.inner.(*BlobTx); ok { - return blobtx.Sidecar - } - return nil -} - -// BlobGasFeeCapCmp compares the blob fee cap of two transactions. -func (tx *Transaction) BlobGasFeeCapCmp(other *Transaction) int { - return tx.BlobGasFeeCap().Cmp(other.BlobGasFeeCap()) -} - -// BlobGasFeeCapIntCmp compares the blob fee cap of the transaction against the given blob fee cap. -func (tx *Transaction) BlobGasFeeCapIntCmp(other *big.Int) int { - return tx.BlobGasFeeCap().Cmp(other) -} - -// WithoutBlobTxSidecar returns a copy of tx with the blob sidecar removed. -func (tx *Transaction) WithoutBlobTxSidecar() *Transaction { - blobtx, ok := tx.inner.(*BlobTx) - if !ok { - return tx - } - cpy := &Transaction{ - inner: blobtx.withoutSidecar(), - time: tx.time, - } - // Note: tx.size cache not carried over because the sidecar is included in size! - if h := tx.hash.Load(); h != nil { - cpy.hash.Store(h) - } - if f := tx.from.Load(); f != nil { - cpy.from.Store(f) - } - return cpy -} - -// SetTime sets the decoding time of a transaction. This is used by tests to set -// arbitrary times and by persistent transaction pools when loading old txs from -// disk. -func (tx *Transaction) SetTime(t time.Time) { - tx.time = t -} - -// Time returns the time when the transaction was first seen on the network. It -// is a heuristic to prefer mining older txs vs new all other things equal. -func (tx *Transaction) Time() time.Time { - return tx.time -} - -// Hash returns the transaction hash. -func (tx *Transaction) Hash() common.Hash { - if hash := tx.hash.Load(); hash != nil { - return hash.(common.Hash) - } - - var h common.Hash - if tx.Type() == LegacyTxType { - h = rlpHash(tx.inner) - } else { - h = prefixedRlpHash(tx.Type(), tx.inner) - } - tx.hash.Store(h) - return h -} - -// Size returns the true encoded storage size of the transaction, either by encoding -// and returning it, or returning a previously cached value. -func (tx *Transaction) Size() uint64 { - if size := tx.size.Load(); size != nil { - return size.(uint64) - } - - // Cache miss, encode and cache. - // Note we rely on the assumption that all tx.inner values are RLP-encoded! - c := writeCounter(0) - rlp.Encode(&c, &tx.inner) - size := uint64(c) - - // For blob transactions, add the size of the blob content and the outer list of the - // tx + sidecar encoding. - if sc := tx.BlobTxSidecar(); sc != nil { - size += rlp.ListSize(sc.encodedSize()) - } - - // For typed transactions, the encoding also includes the leading type byte. - if tx.Type() != LegacyTxType { - size += 1 - } - - tx.size.Store(size) - return size -} - -// WithSignature returns a new transaction with the given signature. -// This signature needs to be in the [R || S || V] format where V is 0 or 1. -func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) { - r, s, v, err := signer.SignatureValues(tx, sig) - if err != nil { - return nil, err - } - if r == nil || s == nil || v == nil { - return nil, fmt.Errorf("%w: r: %s, s: %s, v: %s", ErrInvalidSig, r, s, v) - } - cpy := tx.inner.copy() - cpy.setSignatureValues(signer.ChainID(), v, r, s) - return &Transaction{inner: cpy, time: tx.time}, nil -} - -// Transactions implements DerivableList for transactions. -type Transactions []*Transaction - -// Len returns the length of s. -func (s Transactions) Len() int { return len(s) } - -// EncodeIndex encodes the i'th transaction to w. Note that this does not check for errors -// because we assume that *Transaction will only ever contain valid txs that were either -// constructed by decoding or via public API in this package. -func (s Transactions) EncodeIndex(i int, w *bytes.Buffer) { - tx := s[i] - if tx.Type() == LegacyTxType { - rlp.Encode(w, tx.inner) - } else { - tx.encodeTyped(w) - } -} - -// TxDifference returns a new set which is the difference between a and b. -func TxDifference(a, b Transactions) Transactions { - keep := make(Transactions, 0, len(a)) - - remove := make(map[common.Hash]struct{}) - for _, tx := range b { - remove[tx.Hash()] = struct{}{} - } - - for _, tx := range a { - if _, ok := remove[tx.Hash()]; !ok { - keep = append(keep, tx) - } - } - - return keep -} - -// HashDifference returns a new set which is the difference between a and b. -func HashDifference(a, b []common.Hash) []common.Hash { - keep := make([]common.Hash, 0, len(a)) - - remove := make(map[common.Hash]struct{}) - for _, hash := range b { - remove[hash] = struct{}{} - } - - for _, hash := range a { - if _, ok := remove[hash]; !ok { - keep = append(keep, hash) - } - } - - return keep -} - -// TxByNonce implements the sort interface to allow sorting a list of transactions -// by their nonces. This is usually only useful for sorting transactions from a -// single account, otherwise a nonce comparison doesn't make much sense. -type TxByNonce Transactions - -func (s TxByNonce) Len() int { return len(s) } -func (s TxByNonce) Less(i, j int) bool { return s[i].Nonce() < s[j].Nonce() } -func (s TxByNonce) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// copyAddressPtr copies an address. -func copyAddressPtr(a *common.Address) *common.Address { - if a == nil { - return nil - } - cpy := *a - return &cpy -} diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go deleted file mode 100644 index 3839efdc63..0000000000 --- a/core/types/transaction_marshalling.go +++ /dev/null @@ -1,431 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "encoding/json" - "errors" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/holiman/uint256" -) - -// txJSON is the JSON representation of transactions. -type txJSON struct { - Type hexutil.Uint64 `json:"type"` - - ChainID *hexutil.Big `json:"chainId,omitempty"` - Nonce *hexutil.Uint64 `json:"nonce"` - To *common.Address `json:"to"` - Gas *hexutil.Uint64 `json:"gas"` - GasPrice *hexutil.Big `json:"gasPrice"` - MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas"` - MaxFeePerGas *hexutil.Big `json:"maxFeePerGas"` - MaxFeePerBlobGas *hexutil.Big `json:"maxFeePerBlobGas,omitempty"` - Value *hexutil.Big `json:"value"` - Input *hexutil.Bytes `json:"input"` - AccessList *AccessList `json:"accessList,omitempty"` - BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"` - V *hexutil.Big `json:"v"` - R *hexutil.Big `json:"r"` - S *hexutil.Big `json:"s"` - YParity *hexutil.Uint64 `json:"yParity,omitempty"` - - // Blob transaction sidecar encoding: - Blobs []kzg4844.Blob `json:"blobs,omitempty"` - Commitments []kzg4844.Commitment `json:"commitments,omitempty"` - Proofs []kzg4844.Proof `json:"proofs,omitempty"` - - // Only used for encoding: - Hash common.Hash `json:"hash"` -} - -// yParityValue returns the YParity value from JSON. For backwards-compatibility reasons, -// this can be given in the 'v' field or the 'yParity' field. If both exist, they must match. -func (tx *txJSON) yParityValue() (*big.Int, error) { - if tx.YParity != nil { - val := uint64(*tx.YParity) - if val != 0 && val != 1 { - return nil, errInvalidYParity - } - bigval := new(big.Int).SetUint64(val) - if tx.V != nil && tx.V.ToInt().Cmp(bigval) != 0 { - return nil, errVYParityMismatch - } - return bigval, nil - } - if tx.V != nil { - return tx.V.ToInt(), nil - } - return nil, errVYParityMissing -} - -// MarshalJSON marshals as JSON with a hash. -func (tx *Transaction) MarshalJSON() ([]byte, error) { - var enc txJSON - // These are set for all tx types. - enc.Hash = tx.Hash() - enc.Type = hexutil.Uint64(tx.Type()) - - // Other fields are set conditionally depending on tx type. - switch itx := tx.inner.(type) { - case *LegacyTx: - enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) - enc.To = tx.To() - enc.Gas = (*hexutil.Uint64)(&itx.Gas) - enc.GasPrice = (*hexutil.Big)(itx.GasPrice) - enc.Value = (*hexutil.Big)(itx.Value) - enc.Input = (*hexutil.Bytes)(&itx.Data) - enc.V = (*hexutil.Big)(itx.V) - enc.R = (*hexutil.Big)(itx.R) - enc.S = (*hexutil.Big)(itx.S) - if tx.Protected() { - enc.ChainID = (*hexutil.Big)(tx.ChainId()) - } - - case *AccessListTx: - enc.ChainID = (*hexutil.Big)(itx.ChainID) - enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) - enc.To = tx.To() - enc.Gas = (*hexutil.Uint64)(&itx.Gas) - enc.GasPrice = (*hexutil.Big)(itx.GasPrice) - enc.Value = (*hexutil.Big)(itx.Value) - enc.Input = (*hexutil.Bytes)(&itx.Data) - enc.AccessList = &itx.AccessList - enc.V = (*hexutil.Big)(itx.V) - enc.R = (*hexutil.Big)(itx.R) - enc.S = (*hexutil.Big)(itx.S) - yparity := itx.V.Uint64() - enc.YParity = (*hexutil.Uint64)(&yparity) - - case *DynamicFeeTx: - enc.ChainID = (*hexutil.Big)(itx.ChainID) - enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) - enc.To = tx.To() - enc.Gas = (*hexutil.Uint64)(&itx.Gas) - enc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap) - enc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap) - enc.Value = (*hexutil.Big)(itx.Value) - enc.Input = (*hexutil.Bytes)(&itx.Data) - enc.AccessList = &itx.AccessList - enc.V = (*hexutil.Big)(itx.V) - enc.R = (*hexutil.Big)(itx.R) - enc.S = (*hexutil.Big)(itx.S) - yparity := itx.V.Uint64() - enc.YParity = (*hexutil.Uint64)(&yparity) - - case *BlobTx: - enc.ChainID = (*hexutil.Big)(itx.ChainID.ToBig()) - enc.Nonce = (*hexutil.Uint64)(&itx.Nonce) - enc.Gas = (*hexutil.Uint64)(&itx.Gas) - enc.MaxFeePerGas = (*hexutil.Big)(itx.GasFeeCap.ToBig()) - enc.MaxPriorityFeePerGas = (*hexutil.Big)(itx.GasTipCap.ToBig()) - enc.MaxFeePerBlobGas = (*hexutil.Big)(itx.BlobFeeCap.ToBig()) - enc.Value = (*hexutil.Big)(itx.Value.ToBig()) - enc.Input = (*hexutil.Bytes)(&itx.Data) - enc.AccessList = &itx.AccessList - enc.BlobVersionedHashes = itx.BlobHashes - enc.To = tx.To() - enc.V = (*hexutil.Big)(itx.V.ToBig()) - enc.R = (*hexutil.Big)(itx.R.ToBig()) - enc.S = (*hexutil.Big)(itx.S.ToBig()) - yparity := itx.V.Uint64() - enc.YParity = (*hexutil.Uint64)(&yparity) - if sidecar := itx.Sidecar; sidecar != nil { - enc.Blobs = itx.Sidecar.Blobs - enc.Commitments = itx.Sidecar.Commitments - enc.Proofs = itx.Sidecar.Proofs - } - } - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (tx *Transaction) UnmarshalJSON(input []byte) error { - var dec txJSON - err := json.Unmarshal(input, &dec) - if err != nil { - return err - } - - // Decode / verify fields according to transaction type. - var inner TxData - switch dec.Type { - case LegacyTxType: - var itx LegacyTx - inner = &itx - if dec.Nonce == nil { - return errors.New("missing required field 'nonce' in transaction") - } - itx.Nonce = uint64(*dec.Nonce) - if dec.To != nil { - itx.To = dec.To - } - if dec.Gas == nil { - return errors.New("missing required field 'gas' in transaction") - } - itx.Gas = uint64(*dec.Gas) - if dec.GasPrice == nil { - return errors.New("missing required field 'gasPrice' in transaction") - } - itx.GasPrice = (*big.Int)(dec.GasPrice) - if dec.Value == nil { - return errors.New("missing required field 'value' in transaction") - } - itx.Value = (*big.Int)(dec.Value) - if dec.Input == nil { - return errors.New("missing required field 'input' in transaction") - } - itx.Data = *dec.Input - - // signature R - if dec.R == nil { - return errors.New("missing required field 'r' in transaction") - } - itx.R = (*big.Int)(dec.R) - // signature S - if dec.S == nil { - return errors.New("missing required field 's' in transaction") - } - itx.S = (*big.Int)(dec.S) - // signature V - if dec.V == nil { - return errors.New("missing required field 'v' in transaction") - } - itx.V = (*big.Int)(dec.V) - if itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 { - if err := sanityCheckSignature(itx.V, itx.R, itx.S, true); err != nil { - return err - } - } - - case AccessListTxType: - var itx AccessListTx - inner = &itx - if dec.ChainID == nil { - return errors.New("missing required field 'chainId' in transaction") - } - itx.ChainID = (*big.Int)(dec.ChainID) - if dec.Nonce == nil { - return errors.New("missing required field 'nonce' in transaction") - } - itx.Nonce = uint64(*dec.Nonce) - if dec.To != nil { - itx.To = dec.To - } - if dec.Gas == nil { - return errors.New("missing required field 'gas' in transaction") - } - itx.Gas = uint64(*dec.Gas) - if dec.GasPrice == nil { - return errors.New("missing required field 'gasPrice' in transaction") - } - itx.GasPrice = (*big.Int)(dec.GasPrice) - if dec.Value == nil { - return errors.New("missing required field 'value' in transaction") - } - itx.Value = (*big.Int)(dec.Value) - if dec.Input == nil { - return errors.New("missing required field 'input' in transaction") - } - itx.Data = *dec.Input - if dec.AccessList != nil { - itx.AccessList = *dec.AccessList - } - - // signature R - if dec.R == nil { - return errors.New("missing required field 'r' in transaction") - } - itx.R = (*big.Int)(dec.R) - // signature S - if dec.S == nil { - return errors.New("missing required field 's' in transaction") - } - itx.S = (*big.Int)(dec.S) - // signature V - itx.V, err = dec.yParityValue() - if err != nil { - return err - } - if itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 { - if err := sanityCheckSignature(itx.V, itx.R, itx.S, false); err != nil { - return err - } - } - - case DynamicFeeTxType: - var itx DynamicFeeTx - inner = &itx - if dec.ChainID == nil { - return errors.New("missing required field 'chainId' in transaction") - } - itx.ChainID = (*big.Int)(dec.ChainID) - if dec.Nonce == nil { - return errors.New("missing required field 'nonce' in transaction") - } - itx.Nonce = uint64(*dec.Nonce) - if dec.To != nil { - itx.To = dec.To - } - if dec.Gas == nil { - return errors.New("missing required field 'gas' for txdata") - } - itx.Gas = uint64(*dec.Gas) - if dec.MaxPriorityFeePerGas == nil { - return errors.New("missing required field 'maxPriorityFeePerGas' for txdata") - } - itx.GasTipCap = (*big.Int)(dec.MaxPriorityFeePerGas) - if dec.MaxFeePerGas == nil { - return errors.New("missing required field 'maxFeePerGas' for txdata") - } - itx.GasFeeCap = (*big.Int)(dec.MaxFeePerGas) - if dec.Value == nil { - return errors.New("missing required field 'value' in transaction") - } - itx.Value = (*big.Int)(dec.Value) - if dec.Input == nil { - return errors.New("missing required field 'input' in transaction") - } - itx.Data = *dec.Input - if dec.AccessList != nil { - itx.AccessList = *dec.AccessList - } - - // signature R - if dec.R == nil { - return errors.New("missing required field 'r' in transaction") - } - itx.R = (*big.Int)(dec.R) - // signature S - if dec.S == nil { - return errors.New("missing required field 's' in transaction") - } - itx.S = (*big.Int)(dec.S) - // signature V - itx.V, err = dec.yParityValue() - if err != nil { - return err - } - if itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 { - if err := sanityCheckSignature(itx.V, itx.R, itx.S, false); err != nil { - return err - } - } - - case BlobTxType: - var itx BlobTx - inner = &itx - if dec.ChainID == nil { - return errors.New("missing required field 'chainId' in transaction") - } - itx.ChainID = uint256.MustFromBig((*big.Int)(dec.ChainID)) - if dec.Nonce == nil { - return errors.New("missing required field 'nonce' in transaction") - } - itx.Nonce = uint64(*dec.Nonce) - if dec.To == nil { - return errors.New("missing required field 'to' in transaction") - } - itx.To = *dec.To - if dec.Gas == nil { - return errors.New("missing required field 'gas' for txdata") - } - itx.Gas = uint64(*dec.Gas) - if dec.MaxPriorityFeePerGas == nil { - return errors.New("missing required field 'maxPriorityFeePerGas' for txdata") - } - itx.GasTipCap = uint256.MustFromBig((*big.Int)(dec.MaxPriorityFeePerGas)) - if dec.MaxFeePerGas == nil { - return errors.New("missing required field 'maxFeePerGas' for txdata") - } - itx.GasFeeCap = uint256.MustFromBig((*big.Int)(dec.MaxFeePerGas)) - if dec.MaxFeePerBlobGas == nil { - return errors.New("missing required field 'maxFeePerBlobGas' for txdata") - } - itx.BlobFeeCap = uint256.MustFromBig((*big.Int)(dec.MaxFeePerBlobGas)) - if dec.Value == nil { - return errors.New("missing required field 'value' in transaction") - } - itx.Value = uint256.MustFromBig((*big.Int)(dec.Value)) - if dec.Input == nil { - return errors.New("missing required field 'input' in transaction") - } - itx.Data = *dec.Input - if dec.AccessList != nil { - itx.AccessList = *dec.AccessList - } - if dec.BlobVersionedHashes == nil { - return errors.New("missing required field 'blobVersionedHashes' in transaction") - } - itx.BlobHashes = dec.BlobVersionedHashes - - // signature R - var overflow bool - if dec.R == nil { - return errors.New("missing required field 'r' in transaction") - } - itx.R, overflow = uint256.FromBig((*big.Int)(dec.R)) - if overflow { - return errors.New("'r' value overflows uint256") - } - // signature S - if dec.S == nil { - return errors.New("missing required field 's' in transaction") - } - itx.S, overflow = uint256.FromBig((*big.Int)(dec.S)) - if overflow { - return errors.New("'s' value overflows uint256") - } - // signature V - vbig, err := dec.yParityValue() - if err != nil { - return err - } - itx.V, overflow = uint256.FromBig(vbig) - if overflow { - return errors.New("'v' value overflows uint256") - } - if itx.V.Sign() != 0 || itx.R.Sign() != 0 || itx.S.Sign() != 0 { - if err := sanityCheckSignature(vbig, itx.R.ToBig(), itx.S.ToBig(), false); err != nil { - return err - } - } - - default: - return ErrTxTypeNotSupported - } - - // Now set the inner transaction. - tx.setDecoded(inner, 0) - - // TODO: check hash here? - return nil -} diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go deleted file mode 100644 index ac6e432893..0000000000 --- a/core/types/transaction_signing.go +++ /dev/null @@ -1,592 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "crypto/ecdsa" - "errors" - "fmt" - "math/big" - - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -var ErrInvalidChainId = errors.New("invalid chain id for signer") - -// sigCache is used to cache the derived sender and contains -// the signer used to derive it. -type sigCache struct { - signer Signer - from common.Address -} - -// MakeSigner returns a Signer based on the given chain config and block number or time. -func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer { - switch { - case config.IsCancun(blockNumber, blockTime): - return NewCancunSigner(config.ChainID) - case config.IsApricotPhase3(blockTime): - return NewLondonSigner(config.ChainID) - case config.IsApricotPhase2(blockTime): - return NewEIP2930Signer(config.ChainID) - case config.IsEIP155(blockNumber): - return NewEIP155Signer(config.ChainID) - case config.IsHomestead(blockNumber): - return HomesteadSigner{} - default: - return FrontierSigner{} - } -} - -// LatestSigner returns the 'most permissive' Signer available for the given chain -// configuration. Specifically, this enables support of all types of transactions -// when their respective forks are scheduled to occur at any block number (or time) -// in the chain config. -// -// Use this in transaction-handling code where the current block number is unknown. If you -// have the current block number available, use MakeSigner instead. -func LatestSigner(config *params.ChainConfig) Signer { - if config.ChainID != nil { - if config.CancunTime != nil { - return NewCancunSigner(config.ChainID) - } - if config.ApricotPhase3BlockTimestamp != nil { - return NewLondonSigner(config.ChainID) - } - if config.ApricotPhase2BlockTimestamp != nil { - return NewEIP2930Signer(config.ChainID) - } - if config.EIP155Block != nil { - return NewEIP155Signer(config.ChainID) - } - } - return HomesteadSigner{} -} - -// LatestSignerForChainID returns the 'most permissive' Signer available. Specifically, -// this enables support for EIP-155 replay protection and all implemented EIP-2718 -// transaction types if chainID is non-nil. -// -// Use this in transaction-handling code where the current block number and fork -// configuration are unknown. If you have a ChainConfig, use LatestSigner instead. -// If you have a ChainConfig and know the current block number, use MakeSigner instead. -func LatestSignerForChainID(chainID *big.Int) Signer { - if chainID == nil { - return HomesteadSigner{} - } - return NewCancunSigner(chainID) -} - -// SignTx signs the transaction using the given signer and private key. -func SignTx(tx *Transaction, s Signer, prv *ecdsa.PrivateKey) (*Transaction, error) { - h := s.Hash(tx) - sig, err := crypto.Sign(h[:], prv) - if err != nil { - return nil, err - } - return tx.WithSignature(s, sig) -} - -// SignNewTx creates a transaction and signs it. -func SignNewTx(prv *ecdsa.PrivateKey, s Signer, txdata TxData) (*Transaction, error) { - tx := NewTx(txdata) - h := s.Hash(tx) - sig, err := crypto.Sign(h[:], prv) - if err != nil { - return nil, err - } - return tx.WithSignature(s, sig) -} - -// MustSignNewTx creates a transaction and signs it. -// This panics if the transaction cannot be signed. -func MustSignNewTx(prv *ecdsa.PrivateKey, s Signer, txdata TxData) *Transaction { - tx, err := SignNewTx(prv, s, txdata) - if err != nil { - panic(err) - } - return tx -} - -// Sender returns the address derived from the signature (V, R, S) using secp256k1 -// elliptic curve and an error if it failed deriving or upon an incorrect -// signature. -// -// Sender may cache the address, allowing it to be used regardless of -// signing method. The cache is invalidated if the cached signer does -// not match the signer used in the current call. -func Sender(signer Signer, tx *Transaction) (common.Address, error) { - if sc := tx.from.Load(); sc != nil { - sigCache := sc.(sigCache) - // If the signer used to derive from in a previous - // call is not the same as used current, invalidate - // the cache. - if sigCache.signer.Equal(signer) { - return sigCache.from, nil - } - } - - addr, err := signer.Sender(tx) - if err != nil { - return common.Address{}, err - } - tx.from.Store(sigCache{signer: signer, from: addr}) - return addr, nil -} - -// Signer encapsulates transaction signature handling. The name of this type is slightly -// misleading because Signers don't actually sign, they're just for validating and -// processing of signatures. -// -// Note that this interface is not a stable API and may change at any time to accommodate -// new protocol rules. -type Signer interface { - // Sender returns the sender address of the transaction. - Sender(tx *Transaction) (common.Address, error) - - // SignatureValues returns the raw R, S, V values corresponding to the - // given signature. - SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) - ChainID() *big.Int - - // Hash returns 'signature hash', i.e. the transaction hash that is signed by the - // private key. This hash does not uniquely identify the transaction. - Hash(tx *Transaction) common.Hash - - // Equal returns true if the given signer is the same as the receiver. - Equal(Signer) bool -} - -type cancunSigner struct{ londonSigner } - -// NewCancunSigner returns a signer that accepts -// - EIP-4844 blob transactions -// - EIP-1559 dynamic fee transactions -// - EIP-2930 access list transactions, -// - EIP-155 replay protected transactions, and -// - legacy Homestead transactions. -func NewCancunSigner(chainId *big.Int) Signer { - return cancunSigner{londonSigner{eip2930Signer{NewEIP155Signer(chainId)}}} -} - -func (s cancunSigner) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != BlobTxType { - return s.londonSigner.Sender(tx) - } - V, R, S := tx.RawSignatureValues() - // Blob txs are defined to use 0 and 1 as their recovery - // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -func (s cancunSigner) Equal(s2 Signer) bool { - x, ok := s2.(cancunSigner) - return ok && x.chainId.Cmp(s.chainId) == 0 -} - -func (s cancunSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - txdata, ok := tx.inner.(*BlobTx) - if !ok { - return s.londonSigner.SignatureValues(tx, sig) - } - // Check that chain ID of tx matches the signer. We also accept ID zero here, - // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.ToBig().Cmp(s.chainId) != 0 { - return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) - } - R, S, _ = decodeSignature(sig) - V = big.NewInt(int64(sig[64])) - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s cancunSigner) Hash(tx *Transaction) common.Hash { - if tx.Type() != BlobTxType { - return s.londonSigner.Hash(tx) - } - return prefixedRlpHash( - tx.Type(), - []interface{}{ - s.chainId, - tx.Nonce(), - tx.GasTipCap(), - tx.GasFeeCap(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - tx.AccessList(), - tx.BlobGasFeeCap(), - tx.BlobHashes(), - }) -} - -type londonSigner struct{ eip2930Signer } - -// NewLondonSigner returns a signer that accepts -// - EIP-1559 dynamic fee transactions -// - EIP-2930 access list transactions, -// - EIP-155 replay protected transactions, and -// - legacy Homestead transactions. -func NewLondonSigner(chainId *big.Int) Signer { - return londonSigner{eip2930Signer{NewEIP155Signer(chainId)}} -} - -func (s londonSigner) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != DynamicFeeTxType { - return s.eip2930Signer.Sender(tx) - } - V, R, S := tx.RawSignatureValues() - // DynamicFee txs are defined to use 0 and 1 as their recovery - // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -func (s londonSigner) Equal(s2 Signer) bool { - x, ok := s2.(londonSigner) - return ok && x.chainId.Cmp(s.chainId) == 0 -} - -func (s londonSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - txdata, ok := tx.inner.(*DynamicFeeTx) - if !ok { - return s.eip2930Signer.SignatureValues(tx, sig) - } - // Check that chain ID of tx matches the signer. We also accept ID zero here, - // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 { - return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) - } - R, S, _ = decodeSignature(sig) - V = big.NewInt(int64(sig[64])) - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s londonSigner) Hash(tx *Transaction) common.Hash { - if tx.Type() != DynamicFeeTxType { - return s.eip2930Signer.Hash(tx) - } - return prefixedRlpHash( - tx.Type(), - []interface{}{ - s.chainId, - tx.Nonce(), - tx.GasTipCap(), - tx.GasFeeCap(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - tx.AccessList(), - }) -} - -type eip2930Signer struct{ EIP155Signer } - -// NewEIP2930Signer returns a signer that accepts EIP-2930 access list transactions, -// EIP-155 replay protected transactions, and legacy Homestead transactions. -func NewEIP2930Signer(chainId *big.Int) Signer { - return eip2930Signer{NewEIP155Signer(chainId)} -} - -func (s eip2930Signer) ChainID() *big.Int { - return s.chainId -} - -func (s eip2930Signer) Equal(s2 Signer) bool { - x, ok := s2.(eip2930Signer) - return ok && x.chainId.Cmp(s.chainId) == 0 -} - -func (s eip2930Signer) Sender(tx *Transaction) (common.Address, error) { - V, R, S := tx.RawSignatureValues() - switch tx.Type() { - case LegacyTxType: - return s.EIP155Signer.Sender(tx) - case AccessListTxType: - // AL txs are defined to use 0 and 1 as their recovery - // id, add 27 to become equivalent to unprotected Homestead signatures. - V = new(big.Int).Add(V, big.NewInt(27)) - default: - return common.Address{}, ErrTxTypeNotSupported - } - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -func (s eip2930Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - switch txdata := tx.inner.(type) { - case *LegacyTx: - return s.EIP155Signer.SignatureValues(tx, sig) - case *AccessListTx: - // Check that chain ID of tx matches the signer. We also accept ID zero here, - // because it indicates that the chain ID was not specified in the tx. - if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.chainId) != 0 { - return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.chainId) - } - R, S, _ = decodeSignature(sig) - V = big.NewInt(int64(sig[64])) - default: - return nil, nil, nil, ErrTxTypeNotSupported - } - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s eip2930Signer) Hash(tx *Transaction) common.Hash { - switch tx.Type() { - case LegacyTxType: - return s.EIP155Signer.Hash(tx) - case AccessListTxType: - return prefixedRlpHash( - tx.Type(), - []interface{}{ - s.chainId, - tx.Nonce(), - tx.GasPrice(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - tx.AccessList(), - }) - default: - // This _should_ not happen, but in case someone sends in a bad - // json struct via RPC, it's probably more prudent to return an - // empty hash instead of killing the node with a panic - //panic("Unsupported transaction type: %d", tx.typ) - return common.Hash{} - } -} - -// EIP155Signer implements Signer using the EIP-155 rules. This accepts transactions which -// are replay-protected as well as unprotected homestead transactions. -type EIP155Signer struct { - chainId, chainIdMul *big.Int -} - -func NewEIP155Signer(chainId *big.Int) EIP155Signer { - if chainId == nil { - chainId = new(big.Int) - } - return EIP155Signer{ - chainId: chainId, - chainIdMul: new(big.Int).Mul(chainId, big.NewInt(2)), - } -} - -func (s EIP155Signer) ChainID() *big.Int { - return s.chainId -} - -func (s EIP155Signer) Equal(s2 Signer) bool { - eip155, ok := s2.(EIP155Signer) - return ok && eip155.chainId.Cmp(s.chainId) == 0 -} - -var big8 = big.NewInt(8) - -func (s EIP155Signer) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != LegacyTxType { - return common.Address{}, ErrTxTypeNotSupported - } - if !tx.Protected() { - return HomesteadSigner{}.Sender(tx) - } - if tx.ChainId().Cmp(s.chainId) != 0 { - return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.chainId) - } - V, R, S := tx.RawSignatureValues() - V = new(big.Int).Sub(V, s.chainIdMul) - V.Sub(V, big8) - return recoverPlain(s.Hash(tx), R, S, V, true) -} - -// SignatureValues returns signature values. This signature -// needs to be in the [R || S || V] format where V is 0 or 1. -func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { - if tx.Type() != LegacyTxType { - return nil, nil, nil, ErrTxTypeNotSupported - } - R, S, V = decodeSignature(sig) - if s.chainId.Sign() != 0 { - V = big.NewInt(int64(sig[64] + 35)) - V.Add(V, s.chainIdMul) - } - return R, S, V, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (s EIP155Signer) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ - tx.Nonce(), - tx.GasPrice(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - s.chainId, uint(0), uint(0), - }) -} - -// HomesteadSigner implements Signer interface using the -// homestead rules. -type HomesteadSigner struct{ FrontierSigner } - -func (s HomesteadSigner) ChainID() *big.Int { - return nil -} - -func (s HomesteadSigner) Equal(s2 Signer) bool { - _, ok := s2.(HomesteadSigner) - return ok -} - -// SignatureValues returns signature values. This signature -// needs to be in the [R || S || V] format where V is 0 or 1. -func (hs HomesteadSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) { - return hs.FrontierSigner.SignatureValues(tx, sig) -} - -func (hs HomesteadSigner) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != LegacyTxType { - return common.Address{}, ErrTxTypeNotSupported - } - v, r, s := tx.RawSignatureValues() - return recoverPlain(hs.Hash(tx), r, s, v, true) -} - -// FrontierSigner implements Signer interface using the -// frontier rules. -type FrontierSigner struct{} - -func (s FrontierSigner) ChainID() *big.Int { - return nil -} - -func (s FrontierSigner) Equal(s2 Signer) bool { - _, ok := s2.(FrontierSigner) - return ok -} - -func (fs FrontierSigner) Sender(tx *Transaction) (common.Address, error) { - if tx.Type() != LegacyTxType { - return common.Address{}, ErrTxTypeNotSupported - } - v, r, s := tx.RawSignatureValues() - return recoverPlain(fs.Hash(tx), r, s, v, false) -} - -// SignatureValues returns signature values. This signature -// needs to be in the [R || S || V] format where V is 0 or 1. -func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) { - if tx.Type() != LegacyTxType { - return nil, nil, nil, ErrTxTypeNotSupported - } - r, s, v = decodeSignature(sig) - return r, s, v, nil -} - -// Hash returns the hash to be signed by the sender. -// It does not uniquely identify the transaction. -func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { - return rlpHash([]interface{}{ - tx.Nonce(), - tx.GasPrice(), - tx.Gas(), - tx.To(), - tx.Value(), - tx.Data(), - }) -} - -func decodeSignature(sig []byte) (r, s, v *big.Int) { - if len(sig) != crypto.SignatureLength { - panic(fmt.Sprintf("wrong size for signature: got %d, want %d", len(sig), crypto.SignatureLength)) - } - r = new(big.Int).SetBytes(sig[:32]) - s = new(big.Int).SetBytes(sig[32:64]) - v = new(big.Int).SetBytes([]byte{sig[64] + 27}) - return r, s, v -} - -func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (common.Address, error) { - if Vb.BitLen() > 8 { - return common.Address{}, ErrInvalidSig - } - V := byte(Vb.Uint64() - 27) - if !crypto.ValidateSignatureValues(V, R, S, homestead) { - return common.Address{}, ErrInvalidSig - } - // encode the signature in uncompressed format - r, s := R.Bytes(), S.Bytes() - sig := make([]byte, crypto.SignatureLength) - copy(sig[32-len(r):32], r) - copy(sig[64-len(s):64], s) - sig[64] = V - // recover the public key from the signature - pub, err := crypto.Ecrecover(sighash[:], sig) - if err != nil { - return common.Address{}, err - } - if len(pub) == 0 || pub[0] != 4 { - return common.Address{}, errors.New("invalid public key") - } - var addr common.Address - copy(addr[:], crypto.Keccak256(pub[1:])[12:]) - return addr, nil -} - -// deriveChainId derives the chain id from the given v parameter -func deriveChainId(v *big.Int) *big.Int { - if v.BitLen() <= 64 { - v := v.Uint64() - if v == 27 || v == 28 { - return new(big.Int) - } - return new(big.Int).SetUint64((v - 35) / 2) - } - v = new(big.Int).Sub(v, big.NewInt(35)) - return v.Div(v, big.NewInt(2)) -} diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go deleted file mode 100644 index 5735c1539d..0000000000 --- a/core/types/transaction_signing_test.go +++ /dev/null @@ -1,203 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "errors" - "fmt" - "math/big" - "testing" - - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -func TestEIP155Signing(t *testing.T) { - key, _ := crypto.GenerateKey() - addr := crypto.PubkeyToAddress(key.PublicKey) - - signer := NewEIP155Signer(big.NewInt(18)) - tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil), signer, key) - if err != nil { - t.Fatal(err) - } - - from, err := Sender(signer, tx) - if err != nil { - t.Fatal(err) - } - if from != addr { - t.Errorf("expected from and address to be equal. Got %x want %x", from, addr) - } -} - -func TestEIP155ChainId(t *testing.T) { - key, _ := crypto.GenerateKey() - addr := crypto.PubkeyToAddress(key.PublicKey) - - signer := NewEIP155Signer(big.NewInt(18)) - tx, err := SignTx(NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil), signer, key) - if err != nil { - t.Fatal(err) - } - if !tx.Protected() { - t.Fatal("expected tx to be protected") - } - - if tx.ChainId().Cmp(signer.chainId) != 0 { - t.Error("expected chainId to be", signer.chainId, "got", tx.ChainId()) - } - - tx = NewTransaction(0, addr, new(big.Int), 0, new(big.Int), nil) - tx, err = SignTx(tx, HomesteadSigner{}, key) - if err != nil { - t.Fatal(err) - } - - if tx.Protected() { - t.Error("didn't expect tx to be protected") - } - - if tx.ChainId().Sign() != 0 { - t.Error("expected chain id to be 0 got", tx.ChainId()) - } -} - -func TestEIP155SigningVitalik(t *testing.T) { - // Test vectors come from http://vitalik.ca/files/eip155_testvec.txt - for i, test := range []struct { - txRlp, addr string - }{ - {"f864808504a817c800825208943535353535353535353535353535353535353535808025a0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116da0044852b2a670ade5407e78fb2863c51de9fcb96542a07186fe3aeda6bb8a116d", "0xf0f6f18bca1b28cd68e4357452947e021241e9ce"}, - {"f864018504a817c80182a410943535353535353535353535353535353535353535018025a0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bcaa0489efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6", "0x23ef145a395ea3fa3deb533b8a9e1b4c6c25d112"}, - {"f864028504a817c80282f618943535353535353535353535353535353535353535088025a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5a02d7c5bef027816a800da1736444fb58a807ef4c9603b7848673f7e3a68eb14a5", "0x2e485e0c23b4c3c542628a5f672eeab0ad4888be"}, - {"f865038504a817c803830148209435353535353535353535353535353535353535351b8025a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4e0a02a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de", "0x82a88539669a3fd524d669e858935de5e5410cf0"}, - {"f865048504a817c80483019a28943535353535353535353535353535353535353535408025a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c063a013600b294191fc92924bb3ce4b969c1e7e2bab8f4c93c3fc6d0a51733df3c060", "0xf9358f2538fd5ccfeb848b64a96b743fcc930554"}, - {"f865058504a817c8058301ec309435353535353535353535353535353535353535357d8025a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1a04eebf77a833b30520287ddd9478ff51abbdffa30aa90a8d655dba0e8a79ce0c1", "0xa8f7aba377317440bc5b26198a363ad22af1f3a4"}, - {"f866068504a817c80683023e3894353535353535353535353535353535353535353581d88025a06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2fa06455bf8ea6e7463a1046a0b52804526e119b4bf5136279614e0b1e8e296a4e2d", "0xf1f571dc362a0e5b2696b8e775f8491d3e50de35"}, - {"f867078504a817c807830290409435353535353535353535353535353535353535358201578025a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021a052f1a9b320cab38e5da8a8f97989383aab0a49165fc91c737310e4f7e9821021", "0xd37922162ab7cea97c97a87551ed02c9a38b7332"}, - {"f867088504a817c8088302e2489435353535353535353535353535353535353535358202008025a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c12a064b1702d9298fee62dfeccc57d322a463ad55ca201256d01f62b45b2e1c21c10", "0x9bddad43f934d313c2b79ca28a432dd2b7281029"}, - {"f867098504a817c809830334509435353535353535353535353535353535353535358202d98025a052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afba052f8f61201b2b11a78d6e866abc9c3db2ae8631fa656bfe5cb53668255367afb", "0x3c24d7329e92f84f08556ceb6df1cdb0104ca49f"}, - } { - signer := NewEIP155Signer(big.NewInt(1)) - - var tx *Transaction - err := rlp.DecodeBytes(common.Hex2Bytes(test.txRlp), &tx) - if err != nil { - t.Errorf("%d: %v", i, err) - continue - } - - from, err := Sender(signer, tx) - if err != nil { - t.Errorf("%d: %v", i, err) - continue - } - - addr := common.HexToAddress(test.addr) - if from != addr { - t.Errorf("%d: expected %x got %x", i, addr, from) - } - if !tx.Protected() { - t.Errorf("%d: expected to be protected", i) - } - } -} - -func TestChainId(t *testing.T) { - key, _ := defaultTestKey() - - tx := NewTransaction(0, common.Address{}, new(big.Int), 0, new(big.Int), nil) - - var err error - tx, err = SignTx(tx, NewEIP155Signer(big.NewInt(1)), key) - if err != nil { - t.Fatal(err) - } - - _, err = Sender(NewEIP155Signer(big.NewInt(2)), tx) - if !errors.Is(err, ErrInvalidChainId) { - t.Error("expected error:", ErrInvalidChainId, err) - } - - _, err = Sender(NewEIP155Signer(big.NewInt(1)), tx) - if err != nil { - t.Error("expected no error") - } -} - -type nilSigner struct { - v, r, s *big.Int - Signer -} - -func (ns *nilSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v *big.Int, err error) { - return ns.v, ns.r, ns.s, nil -} - -// TestNilSigner ensures a faulty Signer implementation does not result in nil signature values or panics. -func TestNilSigner(t *testing.T) { - key, _ := crypto.GenerateKey() - innerSigner := LatestSignerForChainID(big.NewInt(1)) - for i, signer := range []Signer{ - &nilSigner{v: nil, r: nil, s: nil, Signer: innerSigner}, - &nilSigner{v: big.NewInt(1), r: big.NewInt(1), s: nil, Signer: innerSigner}, - &nilSigner{v: big.NewInt(1), r: nil, s: big.NewInt(1), Signer: innerSigner}, - &nilSigner{v: nil, r: big.NewInt(1), s: big.NewInt(1), Signer: innerSigner}, - } { - t.Run(fmt.Sprintf("signer_%d", i), func(t *testing.T) { - t.Run("legacy", func(t *testing.T) { - legacyTx := createTestLegacyTxInner() - _, err := SignNewTx(key, signer, legacyTx) - if !errors.Is(err, ErrInvalidSig) { - t.Fatal("expected signature values error, no nil result or panic") - } - }) - // test Blob tx specifically, since the signature value types changed - t.Run("blobtx", func(t *testing.T) { - blobtx := createEmptyBlobTxInner(false) - _, err := SignNewTx(key, signer, blobtx) - if !errors.Is(err, ErrInvalidSig) { - t.Fatal("expected signature values error, no nil result or panic") - } - }) - }) - } -} - -func createTestLegacyTxInner() *LegacyTx { - return &LegacyTx{ - Nonce: uint64(0), - To: nil, - Value: big.NewInt(0), - Gas: params.TxGas, - GasPrice: big.NewInt(params.GWei), - Data: nil, - } -} diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go deleted file mode 100644 index 02ea3d16a4..0000000000 --- a/core/types/transaction_test.go +++ /dev/null @@ -1,555 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "crypto/ecdsa" - "encoding/json" - "errors" - "fmt" - "math/big" - "reflect" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -// The values in those tests are from the Transaction Tests -// at github.com/ethereum/tests. -var ( - testAddr = common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b") - - emptyTx = NewTransaction( - 0, - common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), - big.NewInt(0), 0, big.NewInt(0), - nil, - ) - - rightvrsTx, _ = NewTransaction( - 3, - testAddr, - big.NewInt(10), - 2000, - big.NewInt(1), - common.FromHex("5544"), - ).WithSignature( - HomesteadSigner{}, - common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"), - ) - - emptyEip2718Tx = NewTx(&AccessListTx{ - ChainID: big.NewInt(1), - Nonce: 3, - To: &testAddr, - Value: big.NewInt(10), - Gas: 25000, - GasPrice: big.NewInt(1), - Data: common.FromHex("5544"), - }) - - signedEip2718Tx, _ = emptyEip2718Tx.WithSignature( - NewEIP2930Signer(big.NewInt(1)), - common.Hex2Bytes("c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b266032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d3752101"), - ) -) - -func TestDecodeEmptyTypedTx(t *testing.T) { - input := []byte{0x80} - var tx Transaction - err := rlp.DecodeBytes(input, &tx) - if err != errShortTypedTx { - t.Fatal("wrong error:", err) - } -} - -func TestTransactionSigHash(t *testing.T) { - var homestead HomesteadSigner - if homestead.Hash(emptyTx) != common.HexToHash("c775b99e7ad12f50d819fcd602390467e28141316969f4b57f0626f74fe3b386") { - t.Errorf("empty transaction hash mismatch, got %x", emptyTx.Hash()) - } - if homestead.Hash(rightvrsTx) != common.HexToHash("fe7a79529ed5f7c3375d06b26b186a8644e0e16c373d7a12be41c62d6042b77a") { - t.Errorf("RightVRS transaction hash mismatch, got %x", rightvrsTx.Hash()) - } -} - -func TestTransactionEncode(t *testing.T) { - txb, err := rlp.EncodeToBytes(rightvrsTx) - if err != nil { - t.Fatalf("encode error: %v", err) - } - should := common.FromHex("f86103018207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3") - if !bytes.Equal(txb, should) { - t.Errorf("encoded RLP mismatch, got %x", txb) - } -} - -func TestEIP2718TransactionSigHash(t *testing.T) { - s := NewEIP2930Signer(big.NewInt(1)) - if s.Hash(emptyEip2718Tx) != common.HexToHash("49b486f0ec0a60dfbbca2d30cb07c9e8ffb2a2ff41f29a1ab6737475f6ff69f3") { - t.Errorf("empty EIP-2718 transaction hash mismatch, got %x", s.Hash(emptyEip2718Tx)) - } - if s.Hash(signedEip2718Tx) != common.HexToHash("49b486f0ec0a60dfbbca2d30cb07c9e8ffb2a2ff41f29a1ab6737475f6ff69f3") { - t.Errorf("signed EIP-2718 transaction hash mismatch, got %x", s.Hash(signedEip2718Tx)) - } -} - -// This test checks signature operations on access list transactions. -func TestEIP2930Signer(t *testing.T) { - var ( - key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - keyAddr = crypto.PubkeyToAddress(key.PublicKey) - signer1 = NewEIP2930Signer(big.NewInt(1)) - signer2 = NewEIP2930Signer(big.NewInt(2)) - tx0 = NewTx(&AccessListTx{Nonce: 1}) - tx1 = NewTx(&AccessListTx{ChainID: big.NewInt(1), Nonce: 1}) - tx2, _ = SignNewTx(key, signer2, &AccessListTx{ChainID: big.NewInt(2), Nonce: 1}) - ) - - tests := []struct { - tx *Transaction - signer Signer - wantSignerHash common.Hash - wantSenderErr error - wantSignErr error - wantHash common.Hash // after signing - }{ - { - tx: tx0, - signer: signer1, - wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"), - wantSenderErr: ErrInvalidChainId, - wantHash: common.HexToHash("1ccd12d8bbdb96ea391af49a35ab641e219b2dd638dea375f2bc94dd290f2549"), - }, - { - tx: tx1, - signer: signer1, - wantSenderErr: ErrInvalidSig, - wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"), - wantHash: common.HexToHash("1ccd12d8bbdb96ea391af49a35ab641e219b2dd638dea375f2bc94dd290f2549"), - }, - { - // This checks what happens when trying to sign an unsigned tx for the wrong chain. - tx: tx1, - signer: signer2, - wantSenderErr: ErrInvalidChainId, - wantSignerHash: common.HexToHash("367967247499343401261d718ed5aa4c9486583e4d89251afce47f4a33c33362"), - wantSignErr: ErrInvalidChainId, - }, - { - // This checks what happens when trying to re-sign a signed tx for the wrong chain. - tx: tx2, - signer: signer1, - wantSenderErr: ErrInvalidChainId, - wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"), - wantSignErr: ErrInvalidChainId, - }, - } - - for i, test := range tests { - sigHash := test.signer.Hash(test.tx) - if sigHash != test.wantSignerHash { - t.Errorf("test %d: wrong sig hash: got %x, want %x", i, sigHash, test.wantSignerHash) - } - sender, err := Sender(test.signer, test.tx) - if !errors.Is(err, test.wantSenderErr) { - t.Errorf("test %d: wrong Sender error %q", i, err) - } - if err == nil && sender != keyAddr { - t.Errorf("test %d: wrong sender address %x", i, sender) - } - signedTx, err := SignTx(test.tx, test.signer, key) - if !errors.Is(err, test.wantSignErr) { - t.Fatalf("test %d: wrong SignTx error %q", i, err) - } - if signedTx != nil { - if signedTx.Hash() != test.wantHash { - t.Errorf("test %d: wrong tx hash after signing: got %x, want %x", i, signedTx.Hash(), test.wantHash) - } - } - } -} - -func TestEIP2718TransactionEncode(t *testing.T) { - // RLP representation - { - have, err := rlp.EncodeToBytes(signedEip2718Tx) - if err != nil { - t.Fatalf("encode error: %v", err) - } - want := common.FromHex("b86601f8630103018261a894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544c001a0c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b2660a032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d37521") - if !bytes.Equal(have, want) { - t.Errorf("encoded RLP mismatch, got %x", have) - } - } - // Binary representation - { - have, err := signedEip2718Tx.MarshalBinary() - if err != nil { - t.Fatalf("encode error: %v", err) - } - want := common.FromHex("01f8630103018261a894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544c001a0c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b2660a032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d37521") - if !bytes.Equal(have, want) { - t.Errorf("encoded RLP mismatch, got %x", have) - } - } -} - -func decodeTx(data []byte) (*Transaction, error) { - var tx Transaction - t, err := &tx, rlp.DecodeBytes(data, &tx) - return t, err -} - -func defaultTestKey() (*ecdsa.PrivateKey, common.Address) { - key, _ := crypto.HexToECDSA("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") - addr := crypto.PubkeyToAddress(key.PublicKey) - return key, addr -} - -func TestRecipientEmpty(t *testing.T) { - _, addr := defaultTestKey() - tx, err := decodeTx(common.Hex2Bytes("f8498080808080011ca09b16de9d5bdee2cf56c28d16275a4da68cd30273e2525f3959f5d62557489921a0372ebd8fb3345f7db7b5a86d42e24d36e983e259b0664ceb8c227ec9af572f3d")) - if err != nil { - t.Fatal(err) - } - - from, err := Sender(HomesteadSigner{}, tx) - if err != nil { - t.Fatal(err) - } - if addr != from { - t.Fatal("derived address doesn't match") - } -} - -func TestRecipientNormal(t *testing.T) { - _, addr := defaultTestKey() - - tx, err := decodeTx(common.Hex2Bytes("f85d80808094000000000000000000000000000000000000000080011ca0527c0d8f5c63f7b9f41324a7c8a563ee1190bcbf0dac8ab446291bdbf32f5c79a0552c4ef0a09a04395074dab9ed34d3fbfb843c2f2546cc30fe89ec143ca94ca6")) - if err != nil { - t.Fatal(err) - } - - from, err := Sender(HomesteadSigner{}, tx) - if err != nil { - t.Fatal(err) - } - if addr != from { - t.Fatal("derived address doesn't match") - } -} - -// TestTransactionCoding tests serializing/de-serializing to/from rlp and JSON. -func TestTransactionCoding(t *testing.T) { - key, err := crypto.GenerateKey() - if err != nil { - t.Fatalf("could not generate key: %v", err) - } - var ( - signer = NewEIP2930Signer(common.Big1) - addr = common.HexToAddress("0x0000000000000000000000000000000000000001") - recipient = common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") - accesses = AccessList{{Address: addr, StorageKeys: []common.Hash{{0}}}} - ) - for i := uint64(0); i < 500; i++ { - var txdata TxData - switch i % 5 { - case 0: - // Legacy tx. - txdata = &LegacyTx{ - Nonce: i, - To: &recipient, - Gas: 1, - GasPrice: big.NewInt(2), - Data: []byte("abcdef"), - } - case 1: - // Legacy tx contract creation. - txdata = &LegacyTx{ - Nonce: i, - Gas: 1, - GasPrice: big.NewInt(2), - Data: []byte("abcdef"), - } - case 2: - // Tx with non-zero access list. - txdata = &AccessListTx{ - ChainID: big.NewInt(1), - Nonce: i, - To: &recipient, - Gas: 123457, - GasPrice: big.NewInt(10), - AccessList: accesses, - Data: []byte("abcdef"), - } - case 3: - // Tx with empty access list. - txdata = &AccessListTx{ - ChainID: big.NewInt(1), - Nonce: i, - To: &recipient, - Gas: 123457, - GasPrice: big.NewInt(10), - Data: []byte("abcdef"), - } - case 4: - // Contract creation with access list. - txdata = &AccessListTx{ - ChainID: big.NewInt(1), - Nonce: i, - Gas: 123457, - GasPrice: big.NewInt(10), - AccessList: accesses, - } - } - tx, err := SignNewTx(key, signer, txdata) - if err != nil { - t.Fatalf("could not sign transaction: %v", err) - } - // RLP - parsedTx, err := encodeDecodeBinary(tx) - if err != nil { - t.Fatal(err) - } - if err := assertEqual(parsedTx, tx); err != nil { - t.Fatal(err) - } - - // JSON - parsedTx, err = encodeDecodeJSON(tx) - if err != nil { - t.Fatal(err) - } - if err := assertEqual(parsedTx, tx); err != nil { - t.Fatal(err) - } - } -} - -func encodeDecodeJSON(tx *Transaction) (*Transaction, error) { - data, err := json.Marshal(tx) - if err != nil { - return nil, fmt.Errorf("json encoding failed: %v", err) - } - var parsedTx = &Transaction{} - if err := json.Unmarshal(data, &parsedTx); err != nil { - return nil, fmt.Errorf("json decoding failed: %v", err) - } - return parsedTx, nil -} - -func encodeDecodeBinary(tx *Transaction) (*Transaction, error) { - data, err := tx.MarshalBinary() - if err != nil { - return nil, fmt.Errorf("rlp encoding failed: %v", err) - } - var parsedTx = &Transaction{} - if err := parsedTx.UnmarshalBinary(data); err != nil { - return nil, fmt.Errorf("rlp decoding failed: %v", err) - } - return parsedTx, nil -} - -func assertEqual(orig *Transaction, cpy *Transaction) error { - // compare nonce, price, gaslimit, recipient, amount, payload, V, R, S - if want, got := orig.Hash(), cpy.Hash(); want != got { - return fmt.Errorf("parsed tx differs from original tx, want %v, got %v", want, got) - } - if want, got := orig.ChainId(), cpy.ChainId(); want.Cmp(got) != 0 { - return fmt.Errorf("invalid chain id, want %d, got %d", want, got) - } - if orig.AccessList() != nil { - if !reflect.DeepEqual(orig.AccessList(), cpy.AccessList()) { - return errors.New("access list wrong!") - } - } - return nil -} - -func TestTransactionSizes(t *testing.T) { - signer := NewLondonSigner(big.NewInt(123)) - key, _ := crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - to := common.HexToAddress("0x01") - for i, txdata := range []TxData{ - &AccessListTx{ - ChainID: big.NewInt(123), - Nonce: 0, - To: nil, - Value: big.NewInt(1000), - Gas: 21000, - GasPrice: big.NewInt(100000), - }, - &LegacyTx{ - Nonce: 1, - GasPrice: big.NewInt(500), - Gas: 1000000, - To: &to, - Value: big.NewInt(1), - }, - &AccessListTx{ - ChainID: big.NewInt(123), - Nonce: 1, - GasPrice: big.NewInt(500), - Gas: 1000000, - To: &to, - Value: big.NewInt(1), - AccessList: AccessList{ - AccessTuple{ - Address: common.HexToAddress("0x01"), - StorageKeys: []common.Hash{common.HexToHash("0x01")}, - }}, - }, - &DynamicFeeTx{ - ChainID: big.NewInt(123), - Nonce: 1, - Gas: 1000000, - To: &to, - Value: big.NewInt(1), - GasTipCap: big.NewInt(500), - GasFeeCap: big.NewInt(500), - }, - } { - tx, err := SignNewTx(key, signer, txdata) - if err != nil { - t.Fatalf("test %d: %v", i, err) - } - bin, _ := tx.MarshalBinary() - - // Check initial calc - if have, want := int(tx.Size()), len(bin); have != want { - t.Errorf("test %d: size wrong, have %d want %d", i, have, want) - } - // Check cached version too - if have, want := int(tx.Size()), len(bin); have != want { - t.Errorf("test %d: (cached) size wrong, have %d want %d", i, have, want) - } - // Check unmarshalled version too - utx := new(Transaction) - if err := utx.UnmarshalBinary(bin); err != nil { - t.Fatalf("test %d: failed to unmarshal tx: %v", i, err) - } - if have, want := int(utx.Size()), len(bin); have != want { - t.Errorf("test %d: (unmarshalled) size wrong, have %d want %d", i, have, want) - } - } -} - -func TestYParityJSONUnmarshalling(t *testing.T) { - baseJson := map[string]interface{}{ - // type is filled in by the test - "chainId": "0x7", - "nonce": "0x0", - "to": "0x1b442286e32ddcaa6e2570ce9ed85f4b4fc87425", - "gas": "0x124f8", - "gasPrice": "0x693d4ca8", - "maxPriorityFeePerGas": "0x3b9aca00", - "maxFeePerGas": "0x6fc23ac00", - "maxFeePerBlobGas": "0x3b9aca00", - "value": "0x0", - "input": "0x", - "accessList": []interface{}{}, - "blobVersionedHashes": []string{ - "0x010657f37554c781402a22917dee2f75def7ab966d7b770905398eba3c444014", - }, - - // v and yParity are filled in by the test - "r": "0x2a922afc784d07e98012da29f2f37cae1f73eda78aa8805d3df6ee5dbb41ec1", - "s": "0x4f1f75ae6bcdf4970b4f305da1a15d8c5ddb21f555444beab77c9af2baab14", - } - - tests := []struct { - name string - v string - yParity string - wantErr error - }{ - // Valid v and yParity - {"valid v and yParity, 0x0", "0x0", "0x0", nil}, - {"valid v and yParity, 0x1", "0x1", "0x1", nil}, - - // Valid v, missing yParity - {"valid v, missing yParity, 0x0", "0x0", "", nil}, - {"valid v, missing yParity, 0x1", "0x1", "", nil}, - - // Valid yParity, missing v - {"valid yParity, missing v, 0x0", "", "0x0", nil}, - {"valid yParity, missing v, 0x1", "", "0x1", nil}, - - // Invalid yParity - {"invalid yParity, 0x2", "", "0x2", errInvalidYParity}, - - // Conflicting v and yParity - {"conflicting v and yParity", "0x1", "0x0", errVYParityMismatch}, - - // Missing v and yParity - {"missing v and yParity", "", "", errVYParityMissing}, - } - - // Run for all types that accept yParity - t.Parallel() - for _, txType := range []uint64{ - AccessListTxType, - DynamicFeeTxType, - BlobTxType, - } { - for _, test := range tests { - t.Run(fmt.Sprintf("txType=%d: %s", txType, test.name), func(t *testing.T) { - // Copy the base json - testJson := make(map[string]interface{}) - for k, v := range baseJson { - testJson[k] = v - } - - // Set v, yParity and type - if test.v != "" { - testJson["v"] = test.v - } - if test.yParity != "" { - testJson["yParity"] = test.yParity - } - testJson["type"] = fmt.Sprintf("0x%x", txType) - - // Marshal the JSON - jsonBytes, err := json.Marshal(testJson) - if err != nil { - t.Fatal(err) - } - - // Unmarshal the tx - var tx Transaction - err = tx.UnmarshalJSON(jsonBytes) - if err != test.wantErr { - t.Fatalf("wrong error: got %v, want %v", err, test.wantErr) - } - }) - } - } -} diff --git a/core/types/tx_access_list.go b/core/types/tx_access_list.go deleted file mode 100644 index c12232d4eb..0000000000 --- a/core/types/tx_access_list.go +++ /dev/null @@ -1,139 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" -) - -//go:generate go run github.com/fjl/gencodec -type AccessTuple -out gen_access_tuple.go - -// AccessList is an EIP-2930 access list. -type AccessList []AccessTuple - -// AccessTuple is the element type of an access list. -type AccessTuple struct { - Address common.Address `json:"address" gencodec:"required"` - StorageKeys []common.Hash `json:"storageKeys" gencodec:"required"` -} - -// StorageKeys returns the total number of storage keys in the access list. -func (al AccessList) StorageKeys() int { - sum := 0 - for _, tuple := range al { - sum += len(tuple.StorageKeys) - } - return sum -} - -// AccessListTx is the data of EIP-2930 access list transactions. -type AccessListTx struct { - ChainID *big.Int // destination chain ID - Nonce uint64 // nonce of sender account - GasPrice *big.Int // wei per gas - Gas uint64 // gas limit - To *common.Address `rlp:"nil"` // nil means contract creation - Value *big.Int // wei amount - Data []byte // contract invocation input data - AccessList AccessList // EIP-2930 access list - V, R, S *big.Int // signature values -} - -// copy creates a deep copy of the transaction data and initializes all fields. -func (tx *AccessListTx) copy() TxData { - cpy := &AccessListTx{ - Nonce: tx.Nonce, - To: copyAddressPtr(tx.To), - Data: common.CopyBytes(tx.Data), - Gas: tx.Gas, - // These are copied below. - AccessList: make(AccessList, len(tx.AccessList)), - Value: new(big.Int), - ChainID: new(big.Int), - GasPrice: new(big.Int), - V: new(big.Int), - R: new(big.Int), - S: new(big.Int), - } - copy(cpy.AccessList, tx.AccessList) - if tx.Value != nil { - cpy.Value.Set(tx.Value) - } - if tx.ChainID != nil { - cpy.ChainID.Set(tx.ChainID) - } - if tx.GasPrice != nil { - cpy.GasPrice.Set(tx.GasPrice) - } - if tx.V != nil { - cpy.V.Set(tx.V) - } - if tx.R != nil { - cpy.R.Set(tx.R) - } - if tx.S != nil { - cpy.S.Set(tx.S) - } - return cpy -} - -// accessors for innerTx. -func (tx *AccessListTx) txType() byte { return AccessListTxType } -func (tx *AccessListTx) chainID() *big.Int { return tx.ChainID } -func (tx *AccessListTx) accessList() AccessList { return tx.AccessList } -func (tx *AccessListTx) data() []byte { return tx.Data } -func (tx *AccessListTx) gas() uint64 { return tx.Gas } -func (tx *AccessListTx) gasPrice() *big.Int { return tx.GasPrice } -func (tx *AccessListTx) gasTipCap() *big.Int { return tx.GasPrice } -func (tx *AccessListTx) gasFeeCap() *big.Int { return tx.GasPrice } -func (tx *AccessListTx) value() *big.Int { return tx.Value } -func (tx *AccessListTx) nonce() uint64 { return tx.Nonce } -func (tx *AccessListTx) to() *common.Address { return tx.To } - -func (tx *AccessListTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { - return dst.Set(tx.GasPrice) -} - -func (tx *AccessListTx) rawSignatureValues() (v, r, s *big.Int) { - return tx.V, tx.R, tx.S -} - -func (tx *AccessListTx) setSignatureValues(chainID, v, r, s *big.Int) { - tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s -} - -func (tx *AccessListTx) encode(b *bytes.Buffer) error { - return rlp.Encode(b, tx) -} - -func (tx *AccessListTx) decode(input []byte) error { - return rlp.DecodeBytes(input, tx) -} diff --git a/core/types/tx_blob.go b/core/types/tx_blob.go deleted file mode 100644 index 6769f6ebc8..0000000000 --- a/core/types/tx_blob.go +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "crypto/sha256" - "math/big" - - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/ethereum/go-ethereum/rlp" - "github.com/holiman/uint256" -) - -// BlobTx represents an EIP-4844 transaction. -type BlobTx struct { - ChainID *uint256.Int - Nonce uint64 - GasTipCap *uint256.Int // a.k.a. maxPriorityFeePerGas - GasFeeCap *uint256.Int // a.k.a. maxFeePerGas - Gas uint64 - To common.Address - Value *uint256.Int - Data []byte - AccessList AccessList - BlobFeeCap *uint256.Int // a.k.a. maxFeePerBlobGas - BlobHashes []common.Hash - - // A blob transaction can optionally contain blobs. This field must be set when BlobTx - // is used to create a transaction for signing. - Sidecar *BlobTxSidecar `rlp:"-"` - - // Signature values - V *uint256.Int `json:"v" gencodec:"required"` - R *uint256.Int `json:"r" gencodec:"required"` - S *uint256.Int `json:"s" gencodec:"required"` -} - -// BlobTxSidecar contains the blobs of a blob transaction. -type BlobTxSidecar struct { - Blobs []kzg4844.Blob // Blobs needed by the blob pool - Commitments []kzg4844.Commitment // Commitments needed by the blob pool - Proofs []kzg4844.Proof // Proofs needed by the blob pool -} - -// BlobHashes computes the blob hashes of the given blobs. -func (sc *BlobTxSidecar) BlobHashes() []common.Hash { - hasher := sha256.New() - h := make([]common.Hash, len(sc.Commitments)) - for i := range sc.Blobs { - h[i] = kzg4844.CalcBlobHashV1(hasher, &sc.Commitments[i]) - } - return h -} - -// encodedSize computes the RLP size of the sidecar elements. This does NOT return the -// encoded size of the BlobTxSidecar, it's just a helper for tx.Size(). -func (sc *BlobTxSidecar) encodedSize() uint64 { - var blobs, commitments, proofs uint64 - for i := range sc.Blobs { - blobs += rlp.BytesSize(sc.Blobs[i][:]) - } - for i := range sc.Commitments { - commitments += rlp.BytesSize(sc.Commitments[i][:]) - } - for i := range sc.Proofs { - proofs += rlp.BytesSize(sc.Proofs[i][:]) - } - return rlp.ListSize(blobs) + rlp.ListSize(commitments) + rlp.ListSize(proofs) -} - -// blobTxWithBlobs is used for encoding of transactions when blobs are present. -type blobTxWithBlobs struct { - BlobTx *BlobTx - Blobs []kzg4844.Blob - Commitments []kzg4844.Commitment - Proofs []kzg4844.Proof -} - -// copy creates a deep copy of the transaction data and initializes all fields. -func (tx *BlobTx) copy() TxData { - cpy := &BlobTx{ - Nonce: tx.Nonce, - To: tx.To, - Data: common.CopyBytes(tx.Data), - Gas: tx.Gas, - // These are copied below. - AccessList: make(AccessList, len(tx.AccessList)), - BlobHashes: make([]common.Hash, len(tx.BlobHashes)), - Value: new(uint256.Int), - ChainID: new(uint256.Int), - GasTipCap: new(uint256.Int), - GasFeeCap: new(uint256.Int), - BlobFeeCap: new(uint256.Int), - V: new(uint256.Int), - R: new(uint256.Int), - S: new(uint256.Int), - } - copy(cpy.AccessList, tx.AccessList) - copy(cpy.BlobHashes, tx.BlobHashes) - - if tx.Value != nil { - cpy.Value.Set(tx.Value) - } - if tx.ChainID != nil { - cpy.ChainID.Set(tx.ChainID) - } - if tx.GasTipCap != nil { - cpy.GasTipCap.Set(tx.GasTipCap) - } - if tx.GasFeeCap != nil { - cpy.GasFeeCap.Set(tx.GasFeeCap) - } - if tx.BlobFeeCap != nil { - cpy.BlobFeeCap.Set(tx.BlobFeeCap) - } - if tx.V != nil { - cpy.V.Set(tx.V) - } - if tx.R != nil { - cpy.R.Set(tx.R) - } - if tx.S != nil { - cpy.S.Set(tx.S) - } - if tx.Sidecar != nil { - cpy.Sidecar = &BlobTxSidecar{ - Blobs: append([]kzg4844.Blob(nil), tx.Sidecar.Blobs...), - Commitments: append([]kzg4844.Commitment(nil), tx.Sidecar.Commitments...), - Proofs: append([]kzg4844.Proof(nil), tx.Sidecar.Proofs...), - } - } - return cpy -} - -// accessors for innerTx. -func (tx *BlobTx) txType() byte { return BlobTxType } -func (tx *BlobTx) chainID() *big.Int { return tx.ChainID.ToBig() } -func (tx *BlobTx) accessList() AccessList { return tx.AccessList } -func (tx *BlobTx) data() []byte { return tx.Data } -func (tx *BlobTx) gas() uint64 { return tx.Gas } -func (tx *BlobTx) gasFeeCap() *big.Int { return tx.GasFeeCap.ToBig() } -func (tx *BlobTx) gasTipCap() *big.Int { return tx.GasTipCap.ToBig() } -func (tx *BlobTx) gasPrice() *big.Int { return tx.GasFeeCap.ToBig() } -func (tx *BlobTx) value() *big.Int { return tx.Value.ToBig() } -func (tx *BlobTx) nonce() uint64 { return tx.Nonce } -func (tx *BlobTx) to() *common.Address { tmp := tx.To; return &tmp } -func (tx *BlobTx) blobGas() uint64 { return params.BlobTxBlobGasPerBlob * uint64(len(tx.BlobHashes)) } - -func (tx *BlobTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { - if baseFee == nil { - return dst.Set(tx.GasFeeCap.ToBig()) - } - tip := dst.Sub(tx.GasFeeCap.ToBig(), baseFee) - if tip.Cmp(tx.GasTipCap.ToBig()) > 0 { - tip.Set(tx.GasTipCap.ToBig()) - } - return tip.Add(tip, baseFee) -} - -func (tx *BlobTx) rawSignatureValues() (v, r, s *big.Int) { - return tx.V.ToBig(), tx.R.ToBig(), tx.S.ToBig() -} - -func (tx *BlobTx) setSignatureValues(chainID, v, r, s *big.Int) { - tx.ChainID.SetFromBig(chainID) - tx.V.SetFromBig(v) - tx.R.SetFromBig(r) - tx.S.SetFromBig(s) -} - -func (tx *BlobTx) withoutSidecar() *BlobTx { - cpy := *tx - cpy.Sidecar = nil - return &cpy -} - -func (tx *BlobTx) encode(b *bytes.Buffer) error { - if tx.Sidecar == nil { - return rlp.Encode(b, tx) - } - inner := &blobTxWithBlobs{ - BlobTx: tx, - Blobs: tx.Sidecar.Blobs, - Commitments: tx.Sidecar.Commitments, - Proofs: tx.Sidecar.Proofs, - } - return rlp.Encode(b, inner) -} - -func (tx *BlobTx) decode(input []byte) error { - // Here we need to support two formats: the network protocol encoding of the tx (with - // blobs) or the canonical encoding without blobs. - // - // The two encodings can be distinguished by checking whether the first element of the - // input list is itself a list. - - outerList, _, err := rlp.SplitList(input) - if err != nil { - return err - } - firstElemKind, _, _, err := rlp.Split(outerList) - if err != nil { - return err - } - - if firstElemKind != rlp.List { - return rlp.DecodeBytes(input, tx) - } - // It's a tx with blobs. - var inner blobTxWithBlobs - if err := rlp.DecodeBytes(input, &inner); err != nil { - return err - } - *tx = *inner.BlobTx - tx.Sidecar = &BlobTxSidecar{ - Blobs: inner.Blobs, - Commitments: inner.Commitments, - Proofs: inner.Proofs, - } - return nil -} diff --git a/core/types/tx_blob_test.go b/core/types/tx_blob_test.go deleted file mode 100644 index 25d09e31ce..0000000000 --- a/core/types/tx_blob_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package types - -import ( - "crypto/ecdsa" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/holiman/uint256" -) - -// This test verifies that tx.Hash() is not affected by presence of a BlobTxSidecar. -func TestBlobTxHashing(t *testing.T) { - key, _ := crypto.GenerateKey() - withBlobs := createEmptyBlobTx(key, true) - withBlobsStripped := withBlobs.WithoutBlobTxSidecar() - withoutBlobs := createEmptyBlobTx(key, false) - - hash := withBlobs.Hash() - t.Log("tx hash:", hash) - - if h := withBlobsStripped.Hash(); h != hash { - t.Fatal("wrong tx hash after WithoutBlobTxSidecar:", h) - } - if h := withoutBlobs.Hash(); h != hash { - t.Fatal("wrong tx hash on tx created without sidecar:", h) - } -} - -// This test verifies that tx.Size() takes BlobTxSidecar into account. -func TestBlobTxSize(t *testing.T) { - key, _ := crypto.GenerateKey() - withBlobs := createEmptyBlobTx(key, true) - withBlobsStripped := withBlobs.WithoutBlobTxSidecar() - withoutBlobs := createEmptyBlobTx(key, false) - - withBlobsEnc, _ := withBlobs.MarshalBinary() - withoutBlobsEnc, _ := withoutBlobs.MarshalBinary() - - size := withBlobs.Size() - t.Log("size with blobs:", size) - - sizeNoBlobs := withoutBlobs.Size() - t.Log("size without blobs:", sizeNoBlobs) - - if size != uint64(len(withBlobsEnc)) { - t.Error("wrong size with blobs:", size, "encoded length:", len(withBlobsEnc)) - } - if sizeNoBlobs != uint64(len(withoutBlobsEnc)) { - t.Error("wrong size without blobs:", sizeNoBlobs, "encoded length:", len(withoutBlobsEnc)) - } - if sizeNoBlobs >= size { - t.Error("size without blobs >= size with blobs") - } - if sz := withBlobsStripped.Size(); sz != sizeNoBlobs { - t.Fatal("wrong size on tx after WithoutBlobTxSidecar:", sz) - } -} - -var ( - emptyBlob = kzg4844.Blob{} - emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob) - emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) -) - -func createEmptyBlobTx(key *ecdsa.PrivateKey, withSidecar bool) *Transaction { - blobtx := createEmptyBlobTxInner(withSidecar) - signer := NewCancunSigner(blobtx.ChainID.ToBig()) - return MustSignNewTx(key, signer, blobtx) -} - -func createEmptyBlobTxInner(withSidecar bool) *BlobTx { - sidecar := &BlobTxSidecar{ - Blobs: []kzg4844.Blob{emptyBlob}, - Commitments: []kzg4844.Commitment{emptyBlobCommit}, - Proofs: []kzg4844.Proof{emptyBlobProof}, - } - blobtx := &BlobTx{ - ChainID: uint256.NewInt(1), - Nonce: 5, - GasTipCap: uint256.NewInt(22), - GasFeeCap: uint256.NewInt(5), - Gas: 25000, - To: common.Address{0x03, 0x04, 0x05}, - Value: uint256.NewInt(99), - Data: make([]byte, 50), - BlobFeeCap: uint256.NewInt(15), - BlobHashes: sidecar.BlobHashes(), - } - if withSidecar { - blobtx.Sidecar = sidecar - } - return blobtx -} diff --git a/core/types/tx_dynamic_fee.go b/core/types/tx_dynamic_fee.go deleted file mode 100644 index d40f1fbd03..0000000000 --- a/core/types/tx_dynamic_fee.go +++ /dev/null @@ -1,135 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" -) - -// DynamicFeeTx represents an EIP-1559 transaction. -type DynamicFeeTx struct { - ChainID *big.Int - Nonce uint64 - GasTipCap *big.Int // a.k.a. maxPriorityFeePerGas - GasFeeCap *big.Int // a.k.a. maxFeePerGas - Gas uint64 - To *common.Address `rlp:"nil"` // nil means contract creation - Value *big.Int - Data []byte - AccessList AccessList - - // Signature values - V *big.Int `json:"v" gencodec:"required"` - R *big.Int `json:"r" gencodec:"required"` - S *big.Int `json:"s" gencodec:"required"` -} - -// copy creates a deep copy of the transaction data and initializes all fields. -func (tx *DynamicFeeTx) copy() TxData { - cpy := &DynamicFeeTx{ - Nonce: tx.Nonce, - To: copyAddressPtr(tx.To), - Data: common.CopyBytes(tx.Data), - Gas: tx.Gas, - // These are copied below. - AccessList: make(AccessList, len(tx.AccessList)), - Value: new(big.Int), - ChainID: new(big.Int), - GasTipCap: new(big.Int), - GasFeeCap: new(big.Int), - V: new(big.Int), - R: new(big.Int), - S: new(big.Int), - } - copy(cpy.AccessList, tx.AccessList) - if tx.Value != nil { - cpy.Value.Set(tx.Value) - } - if tx.ChainID != nil { - cpy.ChainID.Set(tx.ChainID) - } - if tx.GasTipCap != nil { - cpy.GasTipCap.Set(tx.GasTipCap) - } - if tx.GasFeeCap != nil { - cpy.GasFeeCap.Set(tx.GasFeeCap) - } - if tx.V != nil { - cpy.V.Set(tx.V) - } - if tx.R != nil { - cpy.R.Set(tx.R) - } - if tx.S != nil { - cpy.S.Set(tx.S) - } - return cpy -} - -// accessors for innerTx. -func (tx *DynamicFeeTx) txType() byte { return DynamicFeeTxType } -func (tx *DynamicFeeTx) chainID() *big.Int { return tx.ChainID } -func (tx *DynamicFeeTx) accessList() AccessList { return tx.AccessList } -func (tx *DynamicFeeTx) data() []byte { return tx.Data } -func (tx *DynamicFeeTx) gas() uint64 { return tx.Gas } -func (tx *DynamicFeeTx) gasFeeCap() *big.Int { return tx.GasFeeCap } -func (tx *DynamicFeeTx) gasTipCap() *big.Int { return tx.GasTipCap } -func (tx *DynamicFeeTx) gasPrice() *big.Int { return tx.GasFeeCap } -func (tx *DynamicFeeTx) value() *big.Int { return tx.Value } -func (tx *DynamicFeeTx) nonce() uint64 { return tx.Nonce } -func (tx *DynamicFeeTx) to() *common.Address { return tx.To } - -func (tx *DynamicFeeTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { - if baseFee == nil { - return dst.Set(tx.GasFeeCap) - } - tip := dst.Sub(tx.GasFeeCap, baseFee) - if tip.Cmp(tx.GasTipCap) > 0 { - tip.Set(tx.GasTipCap) - } - return tip.Add(tip, baseFee) -} - -func (tx *DynamicFeeTx) rawSignatureValues() (v, r, s *big.Int) { - return tx.V, tx.R, tx.S -} - -func (tx *DynamicFeeTx) setSignatureValues(chainID, v, r, s *big.Int) { - tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s -} - -func (tx *DynamicFeeTx) encode(b *bytes.Buffer) error { - return rlp.Encode(b, tx) -} - -func (tx *DynamicFeeTx) decode(input []byte) error { - return rlp.DecodeBytes(input, tx) -} diff --git a/core/types/tx_legacy.go b/core/types/tx_legacy.go deleted file mode 100644 index b1f12567db..0000000000 --- a/core/types/tx_legacy.go +++ /dev/null @@ -1,135 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package types - -import ( - "bytes" - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -// LegacyTx is the transaction data of the original Ethereum transactions. -type LegacyTx struct { - Nonce uint64 // nonce of sender account - GasPrice *big.Int // wei per gas - Gas uint64 // gas limit - To *common.Address `rlp:"nil"` // nil means contract creation - Value *big.Int // wei amount - Data []byte // contract invocation input data - V, R, S *big.Int // signature values -} - -// NewTransaction creates an unsigned legacy transaction. -// Deprecated: use NewTx instead. -func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { - return NewTx(&LegacyTx{ - Nonce: nonce, - To: &to, - Value: amount, - Gas: gasLimit, - GasPrice: gasPrice, - Data: data, - }) -} - -// NewContractCreation creates an unsigned legacy transaction. -// Deprecated: use NewTx instead. -func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction { - return NewTx(&LegacyTx{ - Nonce: nonce, - Value: amount, - Gas: gasLimit, - GasPrice: gasPrice, - Data: data, - }) -} - -// copy creates a deep copy of the transaction data and initializes all fields. -func (tx *LegacyTx) copy() TxData { - cpy := &LegacyTx{ - Nonce: tx.Nonce, - To: copyAddressPtr(tx.To), - Data: common.CopyBytes(tx.Data), - Gas: tx.Gas, - // These are initialized below. - Value: new(big.Int), - GasPrice: new(big.Int), - V: new(big.Int), - R: new(big.Int), - S: new(big.Int), - } - if tx.Value != nil { - cpy.Value.Set(tx.Value) - } - if tx.GasPrice != nil { - cpy.GasPrice.Set(tx.GasPrice) - } - if tx.V != nil { - cpy.V.Set(tx.V) - } - if tx.R != nil { - cpy.R.Set(tx.R) - } - if tx.S != nil { - cpy.S.Set(tx.S) - } - return cpy -} - -// accessors for innerTx. -func (tx *LegacyTx) txType() byte { return LegacyTxType } -func (tx *LegacyTx) chainID() *big.Int { return deriveChainId(tx.V) } -func (tx *LegacyTx) accessList() AccessList { return nil } -func (tx *LegacyTx) data() []byte { return tx.Data } -func (tx *LegacyTx) gas() uint64 { return tx.Gas } -func (tx *LegacyTx) gasPrice() *big.Int { return tx.GasPrice } -func (tx *LegacyTx) gasTipCap() *big.Int { return tx.GasPrice } -func (tx *LegacyTx) gasFeeCap() *big.Int { return tx.GasPrice } -func (tx *LegacyTx) value() *big.Int { return tx.Value } -func (tx *LegacyTx) nonce() uint64 { return tx.Nonce } -func (tx *LegacyTx) to() *common.Address { return tx.To } - -func (tx *LegacyTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { - return dst.Set(tx.GasPrice) -} - -func (tx *LegacyTx) rawSignatureValues() (v, r, s *big.Int) { - return tx.V, tx.R, tx.S -} - -func (tx *LegacyTx) setSignatureValues(chainID, v, r, s *big.Int) { - tx.V, tx.R, tx.S = v, r, s -} - -func (tx *LegacyTx) encode(*bytes.Buffer) error { - panic("encode called on LegacyTx") -} - -func (tx *LegacyTx) decode([]byte) error { - panic("decode called on LegacyTx)") -} diff --git a/core/vm/analysis.go b/core/vm/analysis.go deleted file mode 100644 index d35fd628aa..0000000000 --- a/core/vm/analysis.go +++ /dev/null @@ -1,128 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -const ( - set2BitsMask = uint16(0b11) - set3BitsMask = uint16(0b111) - set4BitsMask = uint16(0b1111) - set5BitsMask = uint16(0b1_1111) - set6BitsMask = uint16(0b11_1111) - set7BitsMask = uint16(0b111_1111) -) - -// bitvec is a bit vector which maps bytes in a program. -// An unset bit means the byte is an opcode, a set bit means -// it's data (i.e. argument of PUSHxx). -type bitvec []byte - -func (bits bitvec) set1(pos uint64) { - bits[pos/8] |= 1 << (pos % 8) -} - -func (bits bitvec) setN(flag uint16, pos uint64) { - a := flag << (pos % 8) - bits[pos/8] |= byte(a) - if b := byte(a >> 8); b != 0 { - bits[pos/8+1] = b - } -} - -func (bits bitvec) set8(pos uint64) { - a := byte(0xFF << (pos % 8)) - bits[pos/8] |= a - bits[pos/8+1] = ^a -} - -func (bits bitvec) set16(pos uint64) { - a := byte(0xFF << (pos % 8)) - bits[pos/8] |= a - bits[pos/8+1] = 0xFF - bits[pos/8+2] = ^a -} - -// codeSegment checks if the position is in a code segment. -func (bits *bitvec) codeSegment(pos uint64) bool { - return (((*bits)[pos/8] >> (pos % 8)) & 1) == 0 -} - -// codeBitmap collects data locations in code. -func codeBitmap(code []byte) bitvec { - // The bitmap is 4 bytes longer than necessary, in case the code - // ends with a PUSH32, the algorithm will set bits on the - // bitvector outside the bounds of the actual code. - bits := make(bitvec, len(code)/8+1+4) - return codeBitmapInternal(code, bits) -} - -// codeBitmapInternal is the internal implementation of codeBitmap. -// It exists for the purpose of being able to run benchmark tests -// without dynamic allocations affecting the results. -func codeBitmapInternal(code, bits bitvec) bitvec { - for pc := uint64(0); pc < uint64(len(code)); { - op := OpCode(code[pc]) - pc++ - if int8(op) < int8(PUSH1) { // If not PUSH (the int8(op) > int(PUSH32) is always false). - continue - } - numbits := op - PUSH1 + 1 - if numbits >= 8 { - for ; numbits >= 16; numbits -= 16 { - bits.set16(pc) - pc += 16 - } - for ; numbits >= 8; numbits -= 8 { - bits.set8(pc) - pc += 8 - } - } - switch numbits { - case 1: - bits.set1(pc) - pc += 1 - case 2: - bits.setN(set2BitsMask, pc) - pc += 2 - case 3: - bits.setN(set3BitsMask, pc) - pc += 3 - case 4: - bits.setN(set4BitsMask, pc) - pc += 4 - case 5: - bits.setN(set5BitsMask, pc) - pc += 5 - case 6: - bits.setN(set6BitsMask, pc) - pc += 6 - case 7: - bits.setN(set7BitsMask, pc) - pc += 7 - } - } - return bits -} diff --git a/core/vm/analysis_test.go b/core/vm/analysis_test.go deleted file mode 100644 index ae6bef9b46..0000000000 --- a/core/vm/analysis_test.go +++ /dev/null @@ -1,119 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "math/bits" - "testing" - - "github.com/ethereum/go-ethereum/crypto" -) - -func TestJumpDestAnalysis(t *testing.T) { - tests := []struct { - code []byte - exp byte - which int - }{ - {[]byte{byte(PUSH1), 0x01, 0x01, 0x01}, 0b0000_0010, 0}, - {[]byte{byte(PUSH1), byte(PUSH1), byte(PUSH1), byte(PUSH1)}, 0b0000_1010, 0}, - {[]byte{0x00, byte(PUSH1), 0x00, byte(PUSH1), 0x00, byte(PUSH1), 0x00, byte(PUSH1)}, 0b0101_0100, 0}, - {[]byte{byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), byte(PUSH8), 0x01, 0x01, 0x01}, bits.Reverse8(0x7F), 0}, - {[]byte{byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0001, 1}, - {[]byte{0x01, 0x01, 0x01, 0x01, 0x01, byte(PUSH2), byte(PUSH2), byte(PUSH2), 0x01, 0x01, 0x01}, 0b1100_0000, 0}, - {[]byte{0x01, 0x01, 0x01, 0x01, 0x01, byte(PUSH2), 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0000, 1}, - {[]byte{byte(PUSH3), 0x01, 0x01, 0x01, byte(PUSH1), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0010_1110, 0}, - {[]byte{byte(PUSH3), 0x01, 0x01, 0x01, byte(PUSH1), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0000, 1}, - {[]byte{0x01, byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b1111_1100, 0}, - {[]byte{0x01, byte(PUSH8), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0011, 1}, - {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b1111_1110, 0}, - {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b1111_1111, 1}, - {[]byte{byte(PUSH16), 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, 0b0000_0001, 2}, - {[]byte{byte(PUSH8), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, byte(PUSH1), 0x01}, 0b1111_1110, 0}, - {[]byte{byte(PUSH8), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, byte(PUSH1), 0x01}, 0b0000_0101, 1}, - {[]byte{byte(PUSH32)}, 0b1111_1110, 0}, - {[]byte{byte(PUSH32)}, 0b1111_1111, 1}, - {[]byte{byte(PUSH32)}, 0b1111_1111, 2}, - {[]byte{byte(PUSH32)}, 0b1111_1111, 3}, - {[]byte{byte(PUSH32)}, 0b0000_0001, 4}, - } - for i, test := range tests { - ret := codeBitmap(test.code) - if ret[test.which] != test.exp { - t.Fatalf("test %d: expected %x, got %02x", i, test.exp, ret[test.which]) - } - } -} - -const analysisCodeSize = 1200 * 1024 - -func BenchmarkJumpdestAnalysis_1200k(bench *testing.B) { - // 1.4 ms - code := make([]byte, analysisCodeSize) - bench.SetBytes(analysisCodeSize) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { - codeBitmap(code) - } - bench.StopTimer() -} -func BenchmarkJumpdestHashing_1200k(bench *testing.B) { - // 4 ms - code := make([]byte, analysisCodeSize) - bench.SetBytes(analysisCodeSize) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { - crypto.Keccak256Hash(code) - } - bench.StopTimer() -} - -func BenchmarkJumpdestOpAnalysis(bench *testing.B) { - var op OpCode - bencher := func(b *testing.B) { - code := make([]byte, analysisCodeSize) - b.SetBytes(analysisCodeSize) - for i := range code { - code[i] = byte(op) - } - bits := make(bitvec, len(code)/8+1+4) - b.ResetTimer() - for i := 0; i < b.N; i++ { - for j := range bits { - bits[j] = 0 - } - codeBitmapInternal(code, bits) - } - } - for op = PUSH1; op <= PUSH32; op++ { - bench.Run(op.String(), bencher) - } - op = JUMPDEST - bench.Run(op.String(), bencher) - op = STOP - bench.Run(op.String(), bencher) -} diff --git a/core/vm/common.go b/core/vm/common.go deleted file mode 100644 index 0e3ed04376..0000000000 --- a/core/vm/common.go +++ /dev/null @@ -1,92 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/holiman/uint256" -) - -// calcMemSize64 calculates the required memory size, and returns -// the size and whether the result overflowed uint64 -func calcMemSize64(off, l *uint256.Int) (uint64, bool) { - if !l.IsUint64() { - return 0, true - } - return calcMemSize64WithUint(off, l.Uint64()) -} - -// calcMemSize64WithUint calculates the required memory size, and returns -// the size and whether the result overflowed uint64 -// Identical to calcMemSize64, but length is a uint64 -func calcMemSize64WithUint(off *uint256.Int, length64 uint64) (uint64, bool) { - // if length is zero, memsize is always zero, regardless of offset - if length64 == 0 { - return 0, false - } - // Check that offset doesn't overflow - offset64, overflow := off.Uint64WithOverflow() - if overflow { - return 0, true - } - val := offset64 + length64 - // if value < either of it's parts, then it overflowed - return val, val < offset64 -} - -// getData returns a slice from the data based on the start and size and pads -// up to size with zero's. This function is overflow safe. -func getData(data []byte, start uint64, size uint64) []byte { - length := uint64(len(data)) - if start > length { - start = length - } - end := start + size - if end > length { - end = length - } - return common.RightPadBytes(data[start:end], int(size)) -} - -// toWordSize returns the ceiled word size required for memory expansion. -func toWordSize(size uint64) uint64 { - if size > math.MaxUint64-31 { - return math.MaxUint64/32 + 1 - } - - return (size + 31) / 32 -} - -func allZero(b []byte) bool { - for _, byte := range b { - if byte != 0 { - return false - } - } - return true -} diff --git a/core/vm/contract.go b/core/vm/contract.go deleted file mode 100644 index 129b208eb7..0000000000 --- a/core/vm/contract.go +++ /dev/null @@ -1,202 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -// ContractRef is a reference to the contract's backing object -type ContractRef interface { - Address() common.Address -} - -// AccountRef implements ContractRef. -// -// Account references are used during EVM initialisation and -// its primary use is to fetch addresses. Removing this object -// proves difficult because of the cached jump destinations which -// are fetched from the parent contract (i.e. the caller), which -// is a ContractRef. -type AccountRef common.Address - -// Address casts AccountRef to an Address -func (ar AccountRef) Address() common.Address { return (common.Address)(ar) } - -// Contract represents an ethereum contract in the state database. It contains -// the contract code, calling arguments. Contract implements ContractRef -type Contract struct { - // CallerAddress is the result of the caller which initialised this - // contract. However when the "call method" is delegated this value - // needs to be initialised to that of the caller's caller. - CallerAddress common.Address - caller ContractRef - self ContractRef - - jumpdests map[common.Hash]bitvec // Aggregated result of JUMPDEST analysis. - analysis bitvec // Locally cached result of JUMPDEST analysis - - Code []byte - CodeHash common.Hash - CodeAddr *common.Address - Input []byte - - Gas uint64 - value *uint256.Int -} - -// NewContract returns a new contract environment for the execution of EVM. -func NewContract(caller ContractRef, object ContractRef, value *uint256.Int, gas uint64) *Contract { - c := &Contract{CallerAddress: caller.Address(), caller: caller, self: object} - - if parent, ok := caller.(*Contract); ok { - // Reuse JUMPDEST analysis from parent context if available. - c.jumpdests = parent.jumpdests - } else { - c.jumpdests = make(map[common.Hash]bitvec) - } - - // Gas should be a pointer so it can safely be reduced through the run - // This pointer will be off the state transition - c.Gas = gas - // ensures a value is set - c.value = value - - return c -} - -func (c *Contract) validJumpdest(dest *uint256.Int) bool { - udest, overflow := dest.Uint64WithOverflow() - // PC cannot go beyond len(code) and certainly can't be bigger than 63bits. - // Don't bother checking for JUMPDEST in that case. - if overflow || udest >= uint64(len(c.Code)) { - return false - } - // Only JUMPDESTs allowed for destinations - if OpCode(c.Code[udest]) != JUMPDEST { - return false - } - return c.isCode(udest) -} - -// isCode returns true if the provided PC location is an actual opcode, as -// opposed to a data-segment following a PUSHN operation. -func (c *Contract) isCode(udest uint64) bool { - // Do we already have an analysis laying around? - if c.analysis != nil { - return c.analysis.codeSegment(udest) - } - // Do we have a contract hash already? - // If we do have a hash, that means it's a 'regular' contract. For regular - // contracts ( not temporary initcode), we store the analysis in a map - if c.CodeHash != (common.Hash{}) { - // Does parent context have the analysis? - analysis, exist := c.jumpdests[c.CodeHash] - if !exist { - // Do the analysis and save in parent context - // We do not need to store it in c.analysis - analysis = codeBitmap(c.Code) - c.jumpdests[c.CodeHash] = analysis - } - // Also stash it in current contract for faster access - c.analysis = analysis - return analysis.codeSegment(udest) - } - // We don't have the code hash, most likely a piece of initcode not already - // in state trie. In that case, we do an analysis, and save it locally, so - // we don't have to recalculate it for every JUMP instruction in the execution - // However, we don't save it within the parent context - if c.analysis == nil { - c.analysis = codeBitmap(c.Code) - } - return c.analysis.codeSegment(udest) -} - -// AsDelegate sets the contract to be a delegate call and returns the current -// contract (for chaining calls) -func (c *Contract) AsDelegate() *Contract { - // NOTE: caller must, at all times be a contract. It should never happen - // that caller is something other than a Contract. - parent := c.caller.(*Contract) - c.CallerAddress = parent.CallerAddress - c.value = parent.value - - return c -} - -// GetOp returns the n'th element in the contract's byte array -func (c *Contract) GetOp(n uint64) OpCode { - if n < uint64(len(c.Code)) { - return OpCode(c.Code[n]) - } - - return STOP -} - -// Caller returns the caller of the contract. -// -// Caller will recursively call caller when the contract is a delegate -// call, including that of caller's caller. -func (c *Contract) Caller() common.Address { - return c.CallerAddress -} - -// UseGas attempts the use gas and subtracts it and returns true on success -func (c *Contract) UseGas(gas uint64) (ok bool) { - if c.Gas < gas { - return false - } - c.Gas -= gas - return true -} - -// Address returns the contracts address -func (c *Contract) Address() common.Address { - return c.self.Address() -} - -// Value returns the contract's value (sent to it from it's caller) -func (c *Contract) Value() *uint256.Int { - return c.value -} - -// SetCallCode sets the code of the contract and address of the backing data -// object -func (c *Contract) SetCallCode(addr *common.Address, hash common.Hash, code []byte) { - c.Code = code - c.CodeHash = hash - c.CodeAddr = addr -} - -// SetCodeOptionalHash can be used to provide code, but it's optional to provide hash. -// In case hash is not provided, the jumpdest analysis will not be saved to the parent context -func (c *Contract) SetCodeOptionalHash(addr *common.Address, codeAndHash *codeAndHash) { - c.Code = codeAndHash.code - c.CodeHash = codeAndHash.hash - c.CodeAddr = addr -} diff --git a/core/vm/contracts.go b/core/vm/contracts.go deleted file mode 100644 index b14dea6b2a..0000000000 --- a/core/vm/contracts.go +++ /dev/null @@ -1,1250 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "crypto/sha256" - "encoding/binary" - "errors" - "fmt" - "math/big" - - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/precompile/contract" - "github.com/ava-labs/coreth/precompile/modules" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/blake2b" - "github.com/ethereum/go-ethereum/crypto/bls12381" - "github.com/ethereum/go-ethereum/crypto/bn256" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "golang.org/x/crypto/ripemd160" -) - -// PrecompiledContract is the basic interface for native Go contracts. The implementation -// requires a deterministic gas count based on the input size of the Run method of the -// contract. -type PrecompiledContract interface { - RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use - Run(input []byte) ([]byte, error) // Run runs the precompiled contract -} - -// PrecompiledContractsHomestead contains the default set of pre-compiled Ethereum -// contracts used in the Frontier and Homestead releases. -var PrecompiledContractsHomestead = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), -} - -// PrecompiledContractsByzantium contains the default set of pre-compiled Ethereum -// contracts used in the Byzantium release. -var PrecompiledContractsByzantium = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), - common.BytesToAddress([]byte{5}): newWrappedPrecompiledContract(&bigModExp{eip2565: false}), - common.BytesToAddress([]byte{6}): newWrappedPrecompiledContract(&bn256AddByzantium{}), - common.BytesToAddress([]byte{7}): newWrappedPrecompiledContract(&bn256ScalarMulByzantium{}), - common.BytesToAddress([]byte{8}): newWrappedPrecompiledContract(&bn256PairingByzantium{}), -} - -// PrecompiledContractsIstanbul contains the default set of pre-compiled Ethereum -// contracts used in the Istanbul release. -var PrecompiledContractsIstanbul = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), - common.BytesToAddress([]byte{5}): newWrappedPrecompiledContract(&bigModExp{eip2565: false}), - common.BytesToAddress([]byte{6}): newWrappedPrecompiledContract(&bn256AddIstanbul{}), - common.BytesToAddress([]byte{7}): newWrappedPrecompiledContract(&bn256ScalarMulIstanbul{}), - common.BytesToAddress([]byte{8}): newWrappedPrecompiledContract(&bn256PairingIstanbul{}), - common.BytesToAddress([]byte{9}): newWrappedPrecompiledContract(&blake2F{}), -} - -// PrecompiledContractsApricotPhase2 contains the default set of pre-compiled Ethereum -// contracts used in the Apricot Phase 2 release. -var PrecompiledContractsApricotPhase2 = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), - common.BytesToAddress([]byte{5}): newWrappedPrecompiledContract(&bigModExp{eip2565: true}), - common.BytesToAddress([]byte{6}): newWrappedPrecompiledContract(&bn256AddIstanbul{}), - common.BytesToAddress([]byte{7}): newWrappedPrecompiledContract(&bn256ScalarMulIstanbul{}), - common.BytesToAddress([]byte{8}): newWrappedPrecompiledContract(&bn256PairingIstanbul{}), - common.BytesToAddress([]byte{9}): newWrappedPrecompiledContract(&blake2F{}), - genesisContractAddr: &deprecatedContract{}, - NativeAssetBalanceAddr: &nativeAssetBalance{gasCost: params.AssetBalanceApricot}, - NativeAssetCallAddr: &nativeAssetCall{gasCost: params.AssetCallApricot}, -} - -// PrecompiledContractsApricotPhasePre6 contains the default set of pre-compiled Ethereum -// contracts used in the PrecompiledContractsApricotPhasePre6 release. -var PrecompiledContractsApricotPhasePre6 = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), - common.BytesToAddress([]byte{5}): newWrappedPrecompiledContract(&bigModExp{eip2565: true}), - common.BytesToAddress([]byte{6}): newWrappedPrecompiledContract(&bn256AddIstanbul{}), - common.BytesToAddress([]byte{7}): newWrappedPrecompiledContract(&bn256ScalarMulIstanbul{}), - common.BytesToAddress([]byte{8}): newWrappedPrecompiledContract(&bn256PairingIstanbul{}), - common.BytesToAddress([]byte{9}): newWrappedPrecompiledContract(&blake2F{}), - genesisContractAddr: &deprecatedContract{}, - NativeAssetBalanceAddr: &deprecatedContract{}, - NativeAssetCallAddr: &deprecatedContract{}, -} - -// PrecompiledContractsApricotPhase6 contains the default set of pre-compiled Ethereum -// contracts used in the Apricot Phase 6 release. -var PrecompiledContractsApricotPhase6 = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), - common.BytesToAddress([]byte{5}): newWrappedPrecompiledContract(&bigModExp{eip2565: true}), - common.BytesToAddress([]byte{6}): newWrappedPrecompiledContract(&bn256AddIstanbul{}), - common.BytesToAddress([]byte{7}): newWrappedPrecompiledContract(&bn256ScalarMulIstanbul{}), - common.BytesToAddress([]byte{8}): newWrappedPrecompiledContract(&bn256PairingIstanbul{}), - common.BytesToAddress([]byte{9}): newWrappedPrecompiledContract(&blake2F{}), - genesisContractAddr: &deprecatedContract{}, - NativeAssetBalanceAddr: &nativeAssetBalance{gasCost: params.AssetBalanceApricot}, - NativeAssetCallAddr: &nativeAssetCall{gasCost: params.AssetCallApricot}, -} - -// PrecompiledContractsBanff contains the default set of pre-compiled Ethereum -// contracts used in the Banff release. -var PrecompiledContractsBanff = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), - common.BytesToAddress([]byte{5}): newWrappedPrecompiledContract(&bigModExp{eip2565: true}), - common.BytesToAddress([]byte{6}): newWrappedPrecompiledContract(&bn256AddIstanbul{}), - common.BytesToAddress([]byte{7}): newWrappedPrecompiledContract(&bn256ScalarMulIstanbul{}), - common.BytesToAddress([]byte{8}): newWrappedPrecompiledContract(&bn256PairingIstanbul{}), - common.BytesToAddress([]byte{9}): newWrappedPrecompiledContract(&blake2F{}), - genesisContractAddr: &deprecatedContract{}, - NativeAssetBalanceAddr: &deprecatedContract{}, - NativeAssetCallAddr: &deprecatedContract{}, -} - -// PrecompiledContractsCancun contains the default set of pre-compiled Ethereum -// contracts used in the Cancun release. -var PrecompiledContractsCancun = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{1}): newWrappedPrecompiledContract(&ecrecover{}), - common.BytesToAddress([]byte{2}): newWrappedPrecompiledContract(&sha256hash{}), - common.BytesToAddress([]byte{3}): newWrappedPrecompiledContract(&ripemd160hash{}), - common.BytesToAddress([]byte{4}): newWrappedPrecompiledContract(&dataCopy{}), - common.BytesToAddress([]byte{5}): newWrappedPrecompiledContract(&bigModExp{eip2565: true}), - common.BytesToAddress([]byte{6}): newWrappedPrecompiledContract(&bn256AddIstanbul{}), - common.BytesToAddress([]byte{7}): newWrappedPrecompiledContract(&bn256ScalarMulIstanbul{}), - common.BytesToAddress([]byte{8}): newWrappedPrecompiledContract(&bn256PairingIstanbul{}), - common.BytesToAddress([]byte{9}): newWrappedPrecompiledContract(&blake2F{}), - common.BytesToAddress([]byte{0x0a}): newWrappedPrecompiledContract(&kzgPointEvaluation{}), - genesisContractAddr: &deprecatedContract{}, - NativeAssetBalanceAddr: &deprecatedContract{}, - NativeAssetCallAddr: &deprecatedContract{}, -} - -// PrecompiledContractsBLS contains the set of pre-compiled Ethereum -// contracts specified in EIP-2537. These are exported for testing purposes. -var PrecompiledContractsBLS = map[common.Address]contract.StatefulPrecompiledContract{ - common.BytesToAddress([]byte{10}): newWrappedPrecompiledContract(&bls12381G1Add{}), - common.BytesToAddress([]byte{11}): newWrappedPrecompiledContract(&bls12381G1Mul{}), - common.BytesToAddress([]byte{12}): newWrappedPrecompiledContract(&bls12381G1MultiExp{}), - common.BytesToAddress([]byte{13}): newWrappedPrecompiledContract(&bls12381G2Add{}), - common.BytesToAddress([]byte{14}): newWrappedPrecompiledContract(&bls12381G2Mul{}), - common.BytesToAddress([]byte{15}): newWrappedPrecompiledContract(&bls12381G2MultiExp{}), - common.BytesToAddress([]byte{16}): newWrappedPrecompiledContract(&bls12381Pairing{}), - common.BytesToAddress([]byte{17}): newWrappedPrecompiledContract(&bls12381MapG1{}), - common.BytesToAddress([]byte{18}): newWrappedPrecompiledContract(&bls12381MapG2{}), -} - -var ( - PrecompiledAddressesCancun []common.Address - PrecompiledAddressesBanff []common.Address - PrecompiledAddressesApricotPhase6 []common.Address - PrecompiledAddressesApricotPhasePre6 []common.Address - PrecompiledAddressesApricotPhase2 []common.Address - PrecompiledAddressesIstanbul []common.Address - PrecompiledAddressesByzantium []common.Address - PrecompiledAddressesHomestead []common.Address - PrecompiledAddressesBLS []common.Address - PrecompileAllNativeAddresses map[common.Address]struct{} -) - -func init() { - for k := range PrecompiledContractsHomestead { - PrecompiledAddressesHomestead = append(PrecompiledAddressesHomestead, k) - } - for k := range PrecompiledContractsByzantium { - PrecompiledAddressesByzantium = append(PrecompiledAddressesByzantium, k) - } - for k := range PrecompiledContractsIstanbul { - PrecompiledAddressesIstanbul = append(PrecompiledAddressesIstanbul, k) - } - for k := range PrecompiledContractsApricotPhase2 { - PrecompiledAddressesApricotPhase2 = append(PrecompiledAddressesApricotPhase2, k) - } - for k := range PrecompiledContractsApricotPhasePre6 { - PrecompiledAddressesApricotPhasePre6 = append(PrecompiledAddressesApricotPhasePre6, k) - } - for k := range PrecompiledContractsApricotPhase6 { - PrecompiledAddressesApricotPhase6 = append(PrecompiledAddressesApricotPhase6, k) - } - for k := range PrecompiledContractsBanff { - PrecompiledAddressesBanff = append(PrecompiledAddressesBanff, k) - } - for k := range PrecompiledContractsCancun { - PrecompiledAddressesCancun = append(PrecompiledAddressesCancun, k) - } - for k := range PrecompiledContractsBLS { - PrecompiledAddressesBLS = append(PrecompiledAddressesBLS, k) - } - - // Set of all native precompile addresses that are in use - // Note: this will repeat some addresses, but this is cheap and makes the code clearer. - PrecompileAllNativeAddresses = make(map[common.Address]struct{}) - addrsList := append(PrecompiledAddressesHomestead, PrecompiledAddressesByzantium...) - addrsList = append(addrsList, PrecompiledAddressesIstanbul...) - addrsList = append(addrsList, PrecompiledAddressesApricotPhase2...) - addrsList = append(addrsList, PrecompiledAddressesApricotPhasePre6...) - addrsList = append(addrsList, PrecompiledAddressesApricotPhase6...) - addrsList = append(addrsList, PrecompiledAddressesBanff...) - addrsList = append(addrsList, PrecompiledAddressesCancun...) - addrsList = append(addrsList, PrecompiledAddressesBLS...) - for _, k := range addrsList { - PrecompileAllNativeAddresses[k] = struct{}{} - } - - // Ensure that this package will panic during init if there is a conflict present with the declared - // precompile addresses. - for _, module := range modules.RegisteredModules() { - address := module.Address - if _, ok := PrecompileAllNativeAddresses[address]; ok { - panic(fmt.Errorf("precompile address collides with existing native address: %s", address)) - } - } -} - -// ActivePrecompiles returns the precompiles enabled with the current configuration. -func ActivePrecompiles(rules params.Rules) []common.Address { - switch { - case rules.IsCancun: - return PrecompiledAddressesCancun - case rules.IsBanff: - return PrecompiledAddressesBanff - case rules.IsApricotPhase2: - return PrecompiledAddressesApricotPhase2 - case rules.IsIstanbul: - return PrecompiledAddressesIstanbul - case rules.IsByzantium: - return PrecompiledAddressesByzantium - default: - return PrecompiledAddressesHomestead - } -} - -// RunPrecompiledContract runs and evaluates the output of a precompiled contract. -// It returns -// - the returned bytes, -// - the _remaining_ gas, -// - any error that occurred -func RunPrecompiledContract(p PrecompiledContract, input []byte, suppliedGas uint64) (ret []byte, remainingGas uint64, err error) { - gasCost := p.RequiredGas(input) - if suppliedGas < gasCost { - return nil, 0, vmerrs.ErrOutOfGas - } - suppliedGas -= gasCost - output, err := p.Run(input) - return output, suppliedGas, err -} - -// ECRECOVER implemented as a native contract. -type ecrecover struct{} - -func (c *ecrecover) RequiredGas(input []byte) uint64 { - return params.EcrecoverGas -} - -func (c *ecrecover) Run(input []byte) ([]byte, error) { - const ecRecoverInputLength = 128 - - input = common.RightPadBytes(input, ecRecoverInputLength) - // "input" is (hash, v, r, s), each 32 bytes - // but for ecrecover we want (r, s, v) - - r := new(big.Int).SetBytes(input[64:96]) - s := new(big.Int).SetBytes(input[96:128]) - v := input[63] - 27 - - // tighter sig s values input homestead only apply to tx sigs - if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) { - return nil, nil - } - // We must make sure not to modify the 'input', so placing the 'v' along with - // the signature needs to be done on a new allocation - sig := make([]byte, 65) - copy(sig, input[64:128]) - sig[64] = v - // v needs to be at the end for libsecp256k1 - pubKey, err := crypto.Ecrecover(input[:32], sig) - // make sure the public key is a valid one - if err != nil { - return nil, nil - } - - // the first byte of pubkey is bitcoin heritage - return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil -} - -// SHA256 implemented as a native contract. -type sha256hash struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -// -// This method does not require any overflow checking as the input size gas costs -// required for anything significant is so high it's impossible to pay for. -func (c *sha256hash) RequiredGas(input []byte) uint64 { - return uint64(len(input)+31)/32*params.Sha256PerWordGas + params.Sha256BaseGas -} -func (c *sha256hash) Run(input []byte) ([]byte, error) { - h := sha256.Sum256(input) - return h[:], nil -} - -// RIPEMD160 implemented as a native contract. -type ripemd160hash struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -// -// This method does not require any overflow checking as the input size gas costs -// required for anything significant is so high it's impossible to pay for. -func (c *ripemd160hash) RequiredGas(input []byte) uint64 { - return uint64(len(input)+31)/32*params.Ripemd160PerWordGas + params.Ripemd160BaseGas -} -func (c *ripemd160hash) Run(input []byte) ([]byte, error) { - ripemd := ripemd160.New() - ripemd.Write(input) - return common.LeftPadBytes(ripemd.Sum(nil), 32), nil -} - -// data copy implemented as a native contract. -type dataCopy struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -// -// This method does not require any overflow checking as the input size gas costs -// required for anything significant is so high it's impossible to pay for. -func (c *dataCopy) RequiredGas(input []byte) uint64 { - return uint64(len(input)+31)/32*params.IdentityPerWordGas + params.IdentityBaseGas -} -func (c *dataCopy) Run(in []byte) ([]byte, error) { - return common.CopyBytes(in), nil -} - -// bigModExp implements a native big integer exponential modular operation. -type bigModExp struct { - eip2565 bool -} - -var ( - big0 = big.NewInt(0) - big1 = big.NewInt(1) - big3 = big.NewInt(3) - big4 = big.NewInt(4) - big7 = big.NewInt(7) - big8 = big.NewInt(8) - big16 = big.NewInt(16) - big20 = big.NewInt(20) - big32 = big.NewInt(32) - big64 = big.NewInt(64) - big96 = big.NewInt(96) - big480 = big.NewInt(480) - big1024 = big.NewInt(1024) - big3072 = big.NewInt(3072) - big199680 = big.NewInt(199680) -) - -// modexpMultComplexity implements bigModexp multComplexity formula, as defined in EIP-198 -// -// def mult_complexity(x): -// if x <= 64: return x ** 2 -// elif x <= 1024: return x ** 2 // 4 + 96 * x - 3072 -// else: return x ** 2 // 16 + 480 * x - 199680 -// -// where is x is max(length_of_MODULUS, length_of_BASE) -func modexpMultComplexity(x *big.Int) *big.Int { - switch { - case x.Cmp(big64) <= 0: - x.Mul(x, x) // x ** 2 - case x.Cmp(big1024) <= 0: - // (x ** 2 // 4 ) + ( 96 * x - 3072) - x = new(big.Int).Add( - new(big.Int).Div(new(big.Int).Mul(x, x), big4), - new(big.Int).Sub(new(big.Int).Mul(big96, x), big3072), - ) - default: - // (x ** 2 // 16) + (480 * x - 199680) - x = new(big.Int).Add( - new(big.Int).Div(new(big.Int).Mul(x, x), big16), - new(big.Int).Sub(new(big.Int).Mul(big480, x), big199680), - ) - } - return x -} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bigModExp) RequiredGas(input []byte) uint64 { - var ( - baseLen = new(big.Int).SetBytes(getData(input, 0, 32)) - expLen = new(big.Int).SetBytes(getData(input, 32, 32)) - modLen = new(big.Int).SetBytes(getData(input, 64, 32)) - ) - if len(input) > 96 { - input = input[96:] - } else { - input = input[:0] - } - // Retrieve the head 32 bytes of exp for the adjusted exponent length - var expHead *big.Int - if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 { - expHead = new(big.Int) - } else { - if expLen.Cmp(big32) > 0 { - expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32)) - } else { - expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64())) - } - } - // Calculate the adjusted exponent length - var msb int - if bitlen := expHead.BitLen(); bitlen > 0 { - msb = bitlen - 1 - } - adjExpLen := new(big.Int) - if expLen.Cmp(big32) > 0 { - adjExpLen.Sub(expLen, big32) - adjExpLen.Mul(big8, adjExpLen) - } - adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) - // Calculate the gas cost of the operation - gas := new(big.Int).Set(math.BigMax(modLen, baseLen)) - if c.eip2565 { - // EIP-2565 has three changes - // 1. Different multComplexity (inlined here) - // in EIP-2565 (https://eips.ethereum.org/EIPS/eip-2565): - // - // def mult_complexity(x): - // ceiling(x/8)^2 - // - //where is x is max(length_of_MODULUS, length_of_BASE) - gas = gas.Add(gas, big7) - gas = gas.Div(gas, big8) - gas.Mul(gas, gas) - - gas.Mul(gas, math.BigMax(adjExpLen, big1)) - // 2. Different divisor (`GQUADDIVISOR`) (3) - gas.Div(gas, big3) - if gas.BitLen() > 64 { - return math.MaxUint64 - } - // 3. Minimum price of 200 gas - if gas.Uint64() < 200 { - return 200 - } - return gas.Uint64() - } - gas = modexpMultComplexity(gas) - gas.Mul(gas, math.BigMax(adjExpLen, big1)) - gas.Div(gas, big20) - - if gas.BitLen() > 64 { - return math.MaxUint64 - } - return gas.Uint64() -} - -func (c *bigModExp) Run(input []byte) ([]byte, error) { - var ( - baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() - expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() - modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() - ) - if len(input) > 96 { - input = input[96:] - } else { - input = input[:0] - } - // Handle a special case when both the base and mod length is zero - if baseLen == 0 && modLen == 0 { - return []byte{}, nil - } - // Retrieve the operands and execute the exponentiation - var ( - base = new(big.Int).SetBytes(getData(input, 0, baseLen)) - exp = new(big.Int).SetBytes(getData(input, baseLen, expLen)) - mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen)) - v []byte - ) - switch { - case mod.BitLen() == 0: - // Modulo 0 is undefined, return zero - return common.LeftPadBytes([]byte{}, int(modLen)), nil - case base.BitLen() == 1: // a bit length of 1 means it's 1 (or -1). - //If base == 1, then we can just return base % mod (if mod >= 1, which it is) - v = base.Mod(base, mod).Bytes() - default: - v = base.Exp(base, exp, mod).Bytes() - } - return common.LeftPadBytes(v, int(modLen)), nil -} - -// newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point, -// returning it, or an error if the point is invalid. -func newCurvePoint(blob []byte) (*bn256.G1, error) { - p := new(bn256.G1) - if _, err := p.Unmarshal(blob); err != nil { - return nil, err - } - return p, nil -} - -// newTwistPoint unmarshals a binary blob into a bn256 elliptic curve point, -// returning it, or an error if the point is invalid. -func newTwistPoint(blob []byte) (*bn256.G2, error) { - p := new(bn256.G2) - if _, err := p.Unmarshal(blob); err != nil { - return nil, err - } - return p, nil -} - -// runBn256Add implements the Bn256Add precompile, referenced by both -// Byzantium and Istanbul operations. -func runBn256Add(input []byte) ([]byte, error) { - x, err := newCurvePoint(getData(input, 0, 64)) - if err != nil { - return nil, err - } - y, err := newCurvePoint(getData(input, 64, 64)) - if err != nil { - return nil, err - } - res := new(bn256.G1) - res.Add(x, y) - return res.Marshal(), nil -} - -// bn256Add implements a native elliptic curve point addition conforming to -// Istanbul consensus rules. -type bn256AddIstanbul struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256AddIstanbul) RequiredGas(input []byte) uint64 { - return params.Bn256AddGasIstanbul -} - -func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) { - return runBn256Add(input) -} - -// bn256AddByzantium implements a native elliptic curve point addition -// conforming to Byzantium consensus rules. -type bn256AddByzantium struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256AddByzantium) RequiredGas(input []byte) uint64 { - return params.Bn256AddGasByzantium -} - -func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) { - return runBn256Add(input) -} - -// runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by -// both Byzantium and Istanbul operations. -func runBn256ScalarMul(input []byte) ([]byte, error) { - p, err := newCurvePoint(getData(input, 0, 64)) - if err != nil { - return nil, err - } - res := new(bn256.G1) - res.ScalarMult(p, new(big.Int).SetBytes(getData(input, 64, 32))) - return res.Marshal(), nil -} - -// bn256ScalarMulIstanbul implements a native elliptic curve scalar -// multiplication conforming to Istanbul consensus rules. -type bn256ScalarMulIstanbul struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256ScalarMulIstanbul) RequiredGas(input []byte) uint64 { - return params.Bn256ScalarMulGasIstanbul -} - -func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) { - return runBn256ScalarMul(input) -} - -// bn256ScalarMulByzantium implements a native elliptic curve scalar -// multiplication conforming to Byzantium consensus rules. -type bn256ScalarMulByzantium struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256ScalarMulByzantium) RequiredGas(input []byte) uint64 { - return params.Bn256ScalarMulGasByzantium -} - -func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) { - return runBn256ScalarMul(input) -} - -var ( - // true32Byte is returned if the bn256 pairing check succeeds. - true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} - - // false32Byte is returned if the bn256 pairing check fails. - false32Byte = make([]byte, 32) - - // errBadPairingInput is returned if the bn256 pairing input is invalid. - errBadPairingInput = errors.New("bad elliptic curve pairing size") -) - -// runBn256Pairing implements the Bn256Pairing precompile, referenced by both -// Byzantium and Istanbul operations. -func runBn256Pairing(input []byte) ([]byte, error) { - // Handle some corner cases cheaply - if len(input)%192 > 0 { - return nil, errBadPairingInput - } - // Convert the input into a set of coordinates - var ( - cs []*bn256.G1 - ts []*bn256.G2 - ) - for i := 0; i < len(input); i += 192 { - c, err := newCurvePoint(input[i : i+64]) - if err != nil { - return nil, err - } - t, err := newTwistPoint(input[i+64 : i+192]) - if err != nil { - return nil, err - } - cs = append(cs, c) - ts = append(ts, t) - } - // Execute the pairing checks and return the results - if bn256.PairingCheck(cs, ts) { - return true32Byte, nil - } - return false32Byte, nil -} - -// bn256PairingIstanbul implements a pairing pre-compile for the bn256 curve -// conforming to Istanbul consensus rules. -type bn256PairingIstanbul struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256PairingIstanbul) RequiredGas(input []byte) uint64 { - return params.Bn256PairingBaseGasIstanbul + uint64(len(input)/192)*params.Bn256PairingPerPointGasIstanbul -} - -func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) { - return runBn256Pairing(input) -} - -// bn256PairingByzantium implements a pairing pre-compile for the bn256 curve -// conforming to Byzantium consensus rules. -type bn256PairingByzantium struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bn256PairingByzantium) RequiredGas(input []byte) uint64 { - return params.Bn256PairingBaseGasByzantium + uint64(len(input)/192)*params.Bn256PairingPerPointGasByzantium -} - -func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) { - return runBn256Pairing(input) -} - -type blake2F struct{} - -func (c *blake2F) RequiredGas(input []byte) uint64 { - // If the input is malformed, we can't calculate the gas, return 0 and let the - // actual call choke and fault. - if len(input) != blake2FInputLength { - return 0 - } - return uint64(binary.BigEndian.Uint32(input[0:4])) -} - -const ( - blake2FInputLength = 213 - blake2FFinalBlockBytes = byte(1) - blake2FNonFinalBlockBytes = byte(0) -) - -var ( - errBlake2FInvalidInputLength = errors.New("invalid input length") - errBlake2FInvalidFinalFlag = errors.New("invalid final flag") -) - -func (c *blake2F) Run(input []byte) ([]byte, error) { - // Make sure the input is valid (correct length and final flag) - if len(input) != blake2FInputLength { - return nil, errBlake2FInvalidInputLength - } - if input[212] != blake2FNonFinalBlockBytes && input[212] != blake2FFinalBlockBytes { - return nil, errBlake2FInvalidFinalFlag - } - // Parse the input into the Blake2b call parameters - var ( - rounds = binary.BigEndian.Uint32(input[0:4]) - final = input[212] == blake2FFinalBlockBytes - - h [8]uint64 - m [16]uint64 - t [2]uint64 - ) - for i := 0; i < 8; i++ { - offset := 4 + i*8 - h[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) - } - for i := 0; i < 16; i++ { - offset := 68 + i*8 - m[i] = binary.LittleEndian.Uint64(input[offset : offset+8]) - } - t[0] = binary.LittleEndian.Uint64(input[196:204]) - t[1] = binary.LittleEndian.Uint64(input[204:212]) - - // Execute the compression function, extract and return the result - blake2b.F(&h, m, t, final, rounds) - - output := make([]byte, 64) - for i := 0; i < 8; i++ { - offset := i * 8 - binary.LittleEndian.PutUint64(output[offset:offset+8], h[i]) - } - return output, nil -} - -var ( - errBLS12381InvalidInputLength = errors.New("invalid input length") - errBLS12381InvalidFieldElementTopBytes = errors.New("invalid field element top bytes") - errBLS12381G1PointSubgroup = errors.New("g1 point is not on correct subgroup") - errBLS12381G2PointSubgroup = errors.New("g2 point is not on correct subgroup") -) - -// bls12381G1Add implements EIP-2537 G1Add precompile. -type bls12381G1Add struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G1Add) RequiredGas(input []byte) uint64 { - return params.Bls12381G1AddGas -} - -func (c *bls12381G1Add) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G1Add precompile. - // > G1 addition call expects `256` bytes as an input that is interpreted as byte concatenation of two G1 points (`128` bytes each). - // > Output is an encoding of addition operation result - single G1 point (`128` bytes). - if len(input) != 256 { - return nil, errBLS12381InvalidInputLength - } - var err error - var p0, p1 *bls12381.PointG1 - - // Initialize G1 - g := bls12381.NewG1() - - // Decode G1 point p_0 - if p0, err = g.DecodePoint(input[:128]); err != nil { - return nil, err - } - // Decode G1 point p_1 - if p1, err = g.DecodePoint(input[128:]); err != nil { - return nil, err - } - - // Compute r = p_0 + p_1 - r := g.New() - g.Add(r, p0, p1) - - // Encode the G1 point result into 128 bytes - return g.EncodePoint(r), nil -} - -// bls12381G1Mul implements EIP-2537 G1Mul precompile. -type bls12381G1Mul struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G1Mul) RequiredGas(input []byte) uint64 { - return params.Bls12381G1MulGas -} - -func (c *bls12381G1Mul) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G1Mul precompile. - // > G1 multiplication call expects `160` bytes as an input that is interpreted as byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). - // > Output is an encoding of multiplication operation result - single G1 point (`128` bytes). - if len(input) != 160 { - return nil, errBLS12381InvalidInputLength - } - var err error - var p0 *bls12381.PointG1 - - // Initialize G1 - g := bls12381.NewG1() - - // Decode G1 point - if p0, err = g.DecodePoint(input[:128]); err != nil { - return nil, err - } - // Decode scalar value - e := new(big.Int).SetBytes(input[128:]) - - // Compute r = e * p_0 - r := g.New() - g.MulScalar(r, p0, e) - - // Encode the G1 point into 128 bytes - return g.EncodePoint(r), nil -} - -// bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile. -type bls12381G1MultiExp struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G1MultiExp) RequiredGas(input []byte) uint64 { - // Calculate G1 point, scalar value pair length - k := len(input) / 160 - if k == 0 { - // Return 0 gas for small input length - return 0 - } - // Lookup discount value for G1 point, scalar value pair length - var discount uint64 - if dLen := len(params.Bls12381MultiExpDiscountTable); k < dLen { - discount = params.Bls12381MultiExpDiscountTable[k-1] - } else { - discount = params.Bls12381MultiExpDiscountTable[dLen-1] - } - // Calculate gas and return the result - return (uint64(k) * params.Bls12381G1MulGas * discount) / 1000 -} - -func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G1MultiExp precompile. - // G1 multiplication call expects `160*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G1 point (`128` bytes) and encoding of a scalar value (`32` bytes). - // Output is an encoding of multiexponentiation operation result - single G1 point (`128` bytes). - k := len(input) / 160 - if len(input) == 0 || len(input)%160 != 0 { - return nil, errBLS12381InvalidInputLength - } - var err error - points := make([]*bls12381.PointG1, k) - scalars := make([]*big.Int, k) - - // Initialize G1 - g := bls12381.NewG1() - - // Decode point scalar pairs - for i := 0; i < k; i++ { - off := 160 * i - t0, t1, t2 := off, off+128, off+160 - // Decode G1 point - if points[i], err = g.DecodePoint(input[t0:t1]); err != nil { - return nil, err - } - // Decode scalar value - scalars[i] = new(big.Int).SetBytes(input[t1:t2]) - } - - // Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1) - r := g.New() - g.MultiExp(r, points, scalars) - - // Encode the G1 point to 128 bytes - return g.EncodePoint(r), nil -} - -// bls12381G2Add implements EIP-2537 G2Add precompile. -type bls12381G2Add struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G2Add) RequiredGas(input []byte) uint64 { - return params.Bls12381G2AddGas -} - -func (c *bls12381G2Add) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G2Add precompile. - // > G2 addition call expects `512` bytes as an input that is interpreted as byte concatenation of two G2 points (`256` bytes each). - // > Output is an encoding of addition operation result - single G2 point (`256` bytes). - if len(input) != 512 { - return nil, errBLS12381InvalidInputLength - } - var err error - var p0, p1 *bls12381.PointG2 - - // Initialize G2 - g := bls12381.NewG2() - r := g.New() - - // Decode G2 point p_0 - if p0, err = g.DecodePoint(input[:256]); err != nil { - return nil, err - } - // Decode G2 point p_1 - if p1, err = g.DecodePoint(input[256:]); err != nil { - return nil, err - } - - // Compute r = p_0 + p_1 - g.Add(r, p0, p1) - - // Encode the G2 point into 256 bytes - return g.EncodePoint(r), nil -} - -// bls12381G2Mul implements EIP-2537 G2Mul precompile. -type bls12381G2Mul struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G2Mul) RequiredGas(input []byte) uint64 { - return params.Bls12381G2MulGas -} - -func (c *bls12381G2Mul) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G2MUL precompile logic. - // > G2 multiplication call expects `288` bytes as an input that is interpreted as byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). - // > Output is an encoding of multiplication operation result - single G2 point (`256` bytes). - if len(input) != 288 { - return nil, errBLS12381InvalidInputLength - } - var err error - var p0 *bls12381.PointG2 - - // Initialize G2 - g := bls12381.NewG2() - - // Decode G2 point - if p0, err = g.DecodePoint(input[:256]); err != nil { - return nil, err - } - // Decode scalar value - e := new(big.Int).SetBytes(input[256:]) - - // Compute r = e * p_0 - r := g.New() - g.MulScalar(r, p0, e) - - // Encode the G2 point into 256 bytes - return g.EncodePoint(r), nil -} - -// bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile. -type bls12381G2MultiExp struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381G2MultiExp) RequiredGas(input []byte) uint64 { - // Calculate G2 point, scalar value pair length - k := len(input) / 288 - if k == 0 { - // Return 0 gas for small input length - return 0 - } - // Lookup discount value for G2 point, scalar value pair length - var discount uint64 - if dLen := len(params.Bls12381MultiExpDiscountTable); k < dLen { - discount = params.Bls12381MultiExpDiscountTable[k-1] - } else { - discount = params.Bls12381MultiExpDiscountTable[dLen-1] - } - // Calculate gas and return the result - return (uint64(k) * params.Bls12381G2MulGas * discount) / 1000 -} - -func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 G2MultiExp precompile logic - // > G2 multiplication call expects `288*k` bytes as an input that is interpreted as byte concatenation of `k` slices each of them being a byte concatenation of encoding of G2 point (`256` bytes) and encoding of a scalar value (`32` bytes). - // > Output is an encoding of multiexponentiation operation result - single G2 point (`256` bytes). - k := len(input) / 288 - if len(input) == 0 || len(input)%288 != 0 { - return nil, errBLS12381InvalidInputLength - } - var err error - points := make([]*bls12381.PointG2, k) - scalars := make([]*big.Int, k) - - // Initialize G2 - g := bls12381.NewG2() - - // Decode point scalar pairs - for i := 0; i < k; i++ { - off := 288 * i - t0, t1, t2 := off, off+256, off+288 - // Decode G1 point - if points[i], err = g.DecodePoint(input[t0:t1]); err != nil { - return nil, err - } - // Decode scalar value - scalars[i] = new(big.Int).SetBytes(input[t1:t2]) - } - - // Compute r = e_0 * p_0 + e_1 * p_1 + ... + e_(k-1) * p_(k-1) - r := g.New() - g.MultiExp(r, points, scalars) - - // Encode the G2 point to 256 bytes. - return g.EncodePoint(r), nil -} - -// bls12381Pairing implements EIP-2537 Pairing precompile. -type bls12381Pairing struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381Pairing) RequiredGas(input []byte) uint64 { - return params.Bls12381PairingBaseGas + uint64(len(input)/384)*params.Bls12381PairingPerPairGas -} - -func (c *bls12381Pairing) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 Pairing precompile logic. - // > Pairing call expects `384*k` bytes as an inputs that is interpreted as byte concatenation of `k` slices. Each slice has the following structure: - // > - `128` bytes of G1 point encoding - // > - `256` bytes of G2 point encoding - // > Output is a `32` bytes where last single byte is `0x01` if pairing result is equal to multiplicative identity in a pairing target field and `0x00` otherwise - // > (which is equivalent of Big Endian encoding of Solidity values `uint256(1)` and `uin256(0)` respectively). - k := len(input) / 384 - if len(input) == 0 || len(input)%384 != 0 { - return nil, errBLS12381InvalidInputLength - } - - // Initialize BLS12-381 pairing engine - e := bls12381.NewPairingEngine() - g1, g2 := e.G1, e.G2 - - // Decode pairs - for i := 0; i < k; i++ { - off := 384 * i - t0, t1, t2 := off, off+128, off+384 - - // Decode G1 point - p1, err := g1.DecodePoint(input[t0:t1]) - if err != nil { - return nil, err - } - // Decode G2 point - p2, err := g2.DecodePoint(input[t1:t2]) - if err != nil { - return nil, err - } - - // 'point is on curve' check already done, - // Here we need to apply subgroup checks. - if !g1.InCorrectSubgroup(p1) { - return nil, errBLS12381G1PointSubgroup - } - if !g2.InCorrectSubgroup(p2) { - return nil, errBLS12381G2PointSubgroup - } - - // Update pairing engine with G1 and G2 points - e.AddPair(p1, p2) - } - // Prepare 32 byte output - out := make([]byte, 32) - - // Compute pairing and set the result - if e.Check() { - out[31] = 1 - } - return out, nil -} - -// decodeBLS12381FieldElement decodes BLS12-381 elliptic curve field element. -// Removes top 16 bytes of 64 byte input. -func decodeBLS12381FieldElement(in []byte) ([]byte, error) { - if len(in) != 64 { - return nil, errors.New("invalid field element length") - } - // check top bytes - for i := 0; i < 16; i++ { - if in[i] != byte(0x00) { - return nil, errBLS12381InvalidFieldElementTopBytes - } - } - out := make([]byte, 48) - copy(out[:], in[16:]) - return out, nil -} - -// bls12381MapG1 implements EIP-2537 MapG1 precompile. -type bls12381MapG1 struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381MapG1) RequiredGas(input []byte) uint64 { - return params.Bls12381MapG1Gas -} - -func (c *bls12381MapG1) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 Map_To_G1 precompile. - // > Field-to-curve call expects `64` bytes as an input that is interpreted as a an element of the base field. - // > Output of this call is `128` bytes and is G1 point following respective encoding rules. - if len(input) != 64 { - return nil, errBLS12381InvalidInputLength - } - - // Decode input field element - fe, err := decodeBLS12381FieldElement(input) - if err != nil { - return nil, err - } - - // Initialize G1 - g := bls12381.NewG1() - - // Compute mapping - r, err := g.MapToCurve(fe) - if err != nil { - return nil, err - } - - // Encode the G1 point to 128 bytes - return g.EncodePoint(r), nil -} - -// bls12381MapG2 implements EIP-2537 MapG2 precompile. -type bls12381MapG2 struct{} - -// RequiredGas returns the gas required to execute the pre-compiled contract. -func (c *bls12381MapG2) RequiredGas(input []byte) uint64 { - return params.Bls12381MapG2Gas -} - -func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { - // Implements EIP-2537 Map_FP2_TO_G2 precompile logic. - // > Field-to-curve call expects `128` bytes as an input that is interpreted as a an element of the quadratic extension field. - // > Output of this call is `256` bytes and is G2 point following respective encoding rules. - if len(input) != 128 { - return nil, errBLS12381InvalidInputLength - } - - // Decode input field element - fe := make([]byte, 96) - c0, err := decodeBLS12381FieldElement(input[:64]) - if err != nil { - return nil, err - } - copy(fe[48:], c0) - c1, err := decodeBLS12381FieldElement(input[64:]) - if err != nil { - return nil, err - } - copy(fe[:48], c1) - - // Initialize G2 - g := bls12381.NewG2() - - // Compute mapping - r, err := g.MapToCurve(fe) - if err != nil { - return nil, err - } - - // Encode the G2 point to 256 bytes - return g.EncodePoint(r), nil -} - -// kzgPointEvaluation implements the EIP-4844 point evaluation precompile. -type kzgPointEvaluation struct{} - -// RequiredGas estimates the gas required for running the point evaluation precompile. -func (b *kzgPointEvaluation) RequiredGas(input []byte) uint64 { - return params.BlobTxPointEvaluationPrecompileGas -} - -const ( - blobVerifyInputLength = 192 // Max input length for the point evaluation precompile. - blobCommitmentVersionKZG uint8 = 0x01 // Version byte for the point evaluation precompile. - blobPrecompileReturnValue = "000000000000000000000000000000000000000000000000000000000000100073eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" -) - -var ( - errBlobVerifyInvalidInputLength = errors.New("invalid input length") - errBlobVerifyMismatchedVersion = errors.New("mismatched versioned hash") - errBlobVerifyKZGProof = errors.New("error verifying kzg proof") -) - -// Run executes the point evaluation precompile. -func (b *kzgPointEvaluation) Run(input []byte) ([]byte, error) { - if len(input) != blobVerifyInputLength { - return nil, errBlobVerifyInvalidInputLength - } - // versioned hash: first 32 bytes - var versionedHash common.Hash - copy(versionedHash[:], input[:]) - - var ( - point kzg4844.Point - claim kzg4844.Claim - ) - // Evaluation point: next 32 bytes - copy(point[:], input[32:]) - // Expected output: next 32 bytes - copy(claim[:], input[64:]) - - // input kzg point: next 48 bytes - var commitment kzg4844.Commitment - copy(commitment[:], input[96:]) - if kZGToVersionedHash(commitment) != versionedHash { - return nil, errBlobVerifyMismatchedVersion - } - - // Proof: next 48 bytes - var proof kzg4844.Proof - copy(proof[:], input[144:]) - - if err := kzg4844.VerifyProof(commitment, point, claim, proof); err != nil { - return nil, fmt.Errorf("%w: %v", errBlobVerifyKZGProof, err) - } - - return common.Hex2Bytes(blobPrecompileReturnValue), nil -} - -// kZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844 -func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash { - h := sha256.Sum256(kzg[:]) - h[0] = blobCommitmentVersionKZG - - return h -} diff --git a/core/vm/contracts_fuzz_test.go b/core/vm/contracts_fuzz_test.go deleted file mode 100644 index e955287ba3..0000000000 --- a/core/vm/contracts_fuzz_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// (c) 2019-2024, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func FuzzPrecompiledContracts(f *testing.F) { - // Create list of addresses - var addrs []common.Address - for k := range allPrecompiles { - addrs = append(addrs, k) - } - f.Fuzz(func(t *testing.T, addr uint8, input []byte) { - a := addrs[int(addr)%len(addrs)] - p := allPrecompiles[a] - gas := p.RequiredGas(input) - if gas > 10_000_000 { - return - } - inWant := string(input) - RunPrecompiledContract(p, input, gas) - if inHave := string(input); inWant != inHave { - t.Errorf("Precompiled %v modified input data", a) - } - }) -} diff --git a/core/vm/contracts_stateful.go b/core/vm/contracts_stateful.go deleted file mode 100644 index 64a34ffcf5..0000000000 --- a/core/vm/contracts_stateful.go +++ /dev/null @@ -1,31 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package vm - -import ( - "github.com/ava-labs/coreth/precompile/contract" - "github.com/ethereum/go-ethereum/common" -) - -// wrappedPrecompiledContract implements StatefulPrecompiledContract by wrapping stateless native precompiled contracts -// in Ethereum. -type wrappedPrecompiledContract struct { - p PrecompiledContract -} - -// newWrappedPrecompiledContract returns a wrapped version of [PrecompiledContract] to be executed according to the StatefulPrecompiledContract -// interface. -func newWrappedPrecompiledContract(p PrecompiledContract) contract.StatefulPrecompiledContract { - return &wrappedPrecompiledContract{p: p} -} - -// Run implements the StatefulPrecompiledContract interface -func (w *wrappedPrecompiledContract) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { - return RunPrecompiledContract(w.p, input, suppliedGas) -} - -// RunStatefulPrecompiledContract confirms runs [precompile] with the specified parameters. -func RunStatefulPrecompiledContract(precompile contract.StatefulPrecompiledContract, accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { - return precompile.Run(accessibleState, caller, addr, input, suppliedGas, readOnly) -} diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go deleted file mode 100644 index 80a2c33d18..0000000000 --- a/core/vm/contracts_test.go +++ /dev/null @@ -1,407 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "testing" - "time" - - "github.com/ethereum/go-ethereum/common" -) - -// precompiledTest defines the input/output pairs for precompiled contract tests. -type precompiledTest struct { - Input, Expected string - Gas uint64 - Name string - NoBenchmark bool // Benchmark primarily the worst-cases -} - -// precompiledFailureTest defines the input/error pairs for precompiled -// contract failure tests. -type precompiledFailureTest struct { - Input string - ExpectedError string - Name string -} - -// allPrecompiles does not map to the actual set of precompiles, as it also contains -// repriced versions of precompiles at certain slots -var allPrecompiles = map[common.Address]PrecompiledContract{ - common.BytesToAddress([]byte{1}): &ecrecover{}, - common.BytesToAddress([]byte{2}): &sha256hash{}, - common.BytesToAddress([]byte{3}): &ripemd160hash{}, - common.BytesToAddress([]byte{4}): &dataCopy{}, - common.BytesToAddress([]byte{5}): &bigModExp{eip2565: false}, - common.BytesToAddress([]byte{0xf5}): &bigModExp{eip2565: true}, - common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, - common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, - common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, - common.BytesToAddress([]byte{9}): &blake2F{}, - common.BytesToAddress([]byte{0x0a}): &kzgPointEvaluation{}, - - common.BytesToAddress([]byte{0x0f, 0x0a}): &bls12381G1Add{}, - common.BytesToAddress([]byte{0x0f, 0x0b}): &bls12381G1Mul{}, - common.BytesToAddress([]byte{0x0f, 0x0c}): &bls12381G1MultiExp{}, - common.BytesToAddress([]byte{0x0f, 0x0d}): &bls12381G2Add{}, - common.BytesToAddress([]byte{0x0f, 0x0e}): &bls12381G2Mul{}, - common.BytesToAddress([]byte{0x0f, 0x0f}): &bls12381G2MultiExp{}, - common.BytesToAddress([]byte{0x0f, 0x10}): &bls12381Pairing{}, - common.BytesToAddress([]byte{0x0f, 0x11}): &bls12381MapG1{}, - common.BytesToAddress([]byte{0x0f, 0x12}): &bls12381MapG2{}, -} - -// EIP-152 test vectors -var blake2FMalformedInputTests = []precompiledFailureTest{ - { - Input: "", - ExpectedError: errBlake2FInvalidInputLength.Error(), - Name: "vector 0: empty input", - }, - { - Input: "00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", - ExpectedError: errBlake2FInvalidInputLength.Error(), - Name: "vector 1: less than 213 bytes input", - }, - { - Input: "000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001", - ExpectedError: errBlake2FInvalidInputLength.Error(), - Name: "vector 2: more than 213 bytes input", - }, - { - Input: "0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002", - ExpectedError: errBlake2FInvalidFinalFlag.Error(), - Name: "vector 3: malformed final block indicator flag", - }, -} - -func testPrecompiled(addr string, test precompiledTest, t *testing.T) { - p := allPrecompiles[common.HexToAddress(addr)] - in := common.Hex2Bytes(test.Input) - gas := p.RequiredGas(in) - t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) { - if res, _, err := RunPrecompiledContract(p, in, gas); err != nil { - t.Error(err) - } else if common.Bytes2Hex(res) != test.Expected { - t.Errorf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res)) - } - if expGas := test.Gas; expGas != gas { - t.Errorf("%v: gas wrong, expected %d, got %d", test.Name, expGas, gas) - } - // Verify that the precompile did not touch the input buffer - exp := common.Hex2Bytes(test.Input) - if !bytes.Equal(in, exp) { - t.Errorf("Precompiled %v modified input data", addr) - } - }) -} - -func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) { - p := allPrecompiles[common.HexToAddress(addr)] - in := common.Hex2Bytes(test.Input) - gas := p.RequiredGas(in) - 1 - - t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) { - _, _, err := RunPrecompiledContract(p, in, gas) - if err.Error() != "out of gas" { - t.Errorf("Expected error [out of gas], got [%v]", err) - } - // Verify that the precompile did not touch the input buffer - exp := common.Hex2Bytes(test.Input) - if !bytes.Equal(in, exp) { - t.Errorf("Precompiled %v modified input data", addr) - } - }) -} - -func testPrecompiledFailure(addr string, test precompiledFailureTest, t *testing.T) { - p := allPrecompiles[common.HexToAddress(addr)] - in := common.Hex2Bytes(test.Input) - gas := p.RequiredGas(in) - t.Run(test.Name, func(t *testing.T) { - _, _, err := RunPrecompiledContract(p, in, gas) - if err.Error() != test.ExpectedError { - t.Errorf("Expected error [%v], got [%v]", test.ExpectedError, err) - } - // Verify that the precompile did not touch the input buffer - exp := common.Hex2Bytes(test.Input) - if !bytes.Equal(in, exp) { - t.Errorf("Precompiled %v modified input data", addr) - } - }) -} - -func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { - if test.NoBenchmark { - return - } - p := allPrecompiles[common.HexToAddress(addr)] - in := common.Hex2Bytes(test.Input) - reqGas := p.RequiredGas(in) - - var ( - res []byte - err error - data = make([]byte, len(in)) - ) - - bench.Run(fmt.Sprintf("%s-Gas=%d", test.Name, reqGas), func(bench *testing.B) { - bench.ReportAllocs() - start := time.Now() - bench.ResetTimer() - for i := 0; i < bench.N; i++ { - copy(data, in) - res, _, err = RunPrecompiledContract(p, data, reqGas) - } - bench.StopTimer() - elapsed := uint64(time.Since(start)) - if elapsed < 1 { - elapsed = 1 - } - gasUsed := reqGas * uint64(bench.N) - bench.ReportMetric(float64(reqGas), "gas/op") - // Keep it as uint64, multiply 100 to get two digit float later - mgasps := (100 * 1000 * gasUsed) / elapsed - bench.ReportMetric(float64(mgasps)/100, "mgas/s") - //Check if it is correct - if err != nil { - bench.Error(err) - return - } - if common.Bytes2Hex(res) != test.Expected { - bench.Errorf("Expected %v, got %v", test.Expected, common.Bytes2Hex(res)) - return - } - }) -} - -// Benchmarks the sample inputs from the ECRECOVER precompile. -func BenchmarkPrecompiledEcrecover(bench *testing.B) { - t := precompiledTest{ - Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02", - Expected: "000000000000000000000000ceaccac640adf55b2028469bd36ba501f28b699d", - Name: "", - } - benchmarkPrecompiled("01", t, bench) -} - -// Benchmarks the sample inputs from the SHA256 precompile. -func BenchmarkPrecompiledSha256(bench *testing.B) { - t := precompiledTest{ - Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02", - Expected: "811c7003375852fabd0d362e40e68607a12bdabae61a7d068fe5fdd1dbbf2a5d", - Name: "128", - } - benchmarkPrecompiled("02", t, bench) -} - -// Benchmarks the sample inputs from the RIPEMD precompile. -func BenchmarkPrecompiledRipeMD(bench *testing.B) { - t := precompiledTest{ - Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02", - Expected: "0000000000000000000000009215b8d9882ff46f0dfde6684d78e831467f65e6", - Name: "128", - } - benchmarkPrecompiled("03", t, bench) -} - -// Benchmarks the sample inputs from the identity precompile. -func BenchmarkPrecompiledIdentity(bench *testing.B) { - t := precompiledTest{ - Input: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02", - Expected: "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02", - Name: "128", - } - benchmarkPrecompiled("04", t, bench) -} - -// Tests the sample inputs from the ModExp EIP 198. -func TestPrecompiledModExp(t *testing.T) { testJson("modexp", "05", t) } -func BenchmarkPrecompiledModExp(b *testing.B) { benchJson("modexp", "05", b) } - -func TestPrecompiledModExpEip2565(t *testing.T) { testJson("modexp_eip2565", "f5", t) } -func BenchmarkPrecompiledModExpEip2565(b *testing.B) { benchJson("modexp_eip2565", "f5", b) } - -// Tests the sample inputs from the elliptic curve addition EIP 213. -func TestPrecompiledBn256Add(t *testing.T) { testJson("bn256Add", "06", t) } -func BenchmarkPrecompiledBn256Add(b *testing.B) { benchJson("bn256Add", "06", b) } - -// Tests OOG -func TestPrecompiledModExpOOG(t *testing.T) { - modexpTests, err := loadJson("modexp") - if err != nil { - t.Fatal(err) - } - for _, test := range modexpTests { - testPrecompiledOOG("05", test, t) - } -} - -// Tests the sample inputs from the elliptic curve scalar multiplication EIP 213. -func TestPrecompiledBn256ScalarMul(t *testing.T) { testJson("bn256ScalarMul", "07", t) } -func BenchmarkPrecompiledBn256ScalarMul(b *testing.B) { benchJson("bn256ScalarMul", "07", b) } - -// Tests the sample inputs from the elliptic curve pairing check EIP 197. -func TestPrecompiledBn256Pairing(t *testing.T) { testJson("bn256Pairing", "08", t) } -func BenchmarkPrecompiledBn256Pairing(b *testing.B) { benchJson("bn256Pairing", "08", b) } - -func TestPrecompiledBlake2F(t *testing.T) { testJson("blake2F", "09", t) } -func BenchmarkPrecompiledBlake2F(b *testing.B) { benchJson("blake2F", "09", b) } - -func TestPrecompileBlake2FMalformedInput(t *testing.T) { - for _, test := range blake2FMalformedInputTests { - testPrecompiledFailure("09", test, t) - } -} - -func TestPrecompiledEcrecover(t *testing.T) { testJson("ecRecover", "01", t) } - -func testJson(name, addr string, t *testing.T) { - tests, err := loadJson(name) - if err != nil { - t.Fatal(err) - } - for _, test := range tests { - testPrecompiled(addr, test, t) - } -} - -func testJsonFail(name, addr string, t *testing.T) { - tests, err := loadJsonFail(name) - if err != nil { - t.Fatal(err) - } - for _, test := range tests { - testPrecompiledFailure(addr, test, t) - } -} - -func benchJson(name, addr string, b *testing.B) { - tests, err := loadJson(name) - if err != nil { - b.Fatal(err) - } - for _, test := range tests { - benchmarkPrecompiled(addr, test, b) - } -} - -func TestPrecompiledBLS12381G1Add(t *testing.T) { testJson("blsG1Add", "f0a", t) } -func TestPrecompiledBLS12381G1Mul(t *testing.T) { testJson("blsG1Mul", "f0b", t) } -func TestPrecompiledBLS12381G1MultiExp(t *testing.T) { testJson("blsG1MultiExp", "f0c", t) } -func TestPrecompiledBLS12381G2Add(t *testing.T) { testJson("blsG2Add", "f0d", t) } -func TestPrecompiledBLS12381G2Mul(t *testing.T) { testJson("blsG2Mul", "f0e", t) } -func TestPrecompiledBLS12381G2MultiExp(t *testing.T) { testJson("blsG2MultiExp", "f0f", t) } -func TestPrecompiledBLS12381Pairing(t *testing.T) { testJson("blsPairing", "f10", t) } -func TestPrecompiledBLS12381MapG1(t *testing.T) { testJson("blsMapG1", "f11", t) } -func TestPrecompiledBLS12381MapG2(t *testing.T) { testJson("blsMapG2", "f12", t) } - -func TestPrecompiledPointEvaluation(t *testing.T) { testJson("pointEvaluation", "0a", t) } - -func BenchmarkPrecompiledBLS12381G1Add(b *testing.B) { benchJson("blsG1Add", "f0a", b) } -func BenchmarkPrecompiledBLS12381G1Mul(b *testing.B) { benchJson("blsG1Mul", "f0b", b) } -func BenchmarkPrecompiledBLS12381G1MultiExp(b *testing.B) { benchJson("blsG1MultiExp", "f0c", b) } -func BenchmarkPrecompiledBLS12381G2Add(b *testing.B) { benchJson("blsG2Add", "f0d", b) } -func BenchmarkPrecompiledBLS12381G2Mul(b *testing.B) { benchJson("blsG2Mul", "f0e", b) } -func BenchmarkPrecompiledBLS12381G2MultiExp(b *testing.B) { benchJson("blsG2MultiExp", "f0f", b) } -func BenchmarkPrecompiledBLS12381Pairing(b *testing.B) { benchJson("blsPairing", "f10", b) } -func BenchmarkPrecompiledBLS12381MapG1(b *testing.B) { benchJson("blsMapG1", "f11", b) } -func BenchmarkPrecompiledBLS12381MapG2(b *testing.B) { benchJson("blsMapG2", "f12", b) } - -// Failure tests -func TestPrecompiledBLS12381G1AddFail(t *testing.T) { testJsonFail("blsG1Add", "f0a", t) } -func TestPrecompiledBLS12381G1MulFail(t *testing.T) { testJsonFail("blsG1Mul", "f0b", t) } -func TestPrecompiledBLS12381G1MultiExpFail(t *testing.T) { testJsonFail("blsG1MultiExp", "f0c", t) } -func TestPrecompiledBLS12381G2AddFail(t *testing.T) { testJsonFail("blsG2Add", "f0d", t) } -func TestPrecompiledBLS12381G2MulFail(t *testing.T) { testJsonFail("blsG2Mul", "f0e", t) } -func TestPrecompiledBLS12381G2MultiExpFail(t *testing.T) { testJsonFail("blsG2MultiExp", "f0f", t) } -func TestPrecompiledBLS12381PairingFail(t *testing.T) { testJsonFail("blsPairing", "f10", t) } -func TestPrecompiledBLS12381MapG1Fail(t *testing.T) { testJsonFail("blsMapG1", "f11", t) } -func TestPrecompiledBLS12381MapG2Fail(t *testing.T) { testJsonFail("blsMapG2", "f12", t) } - -func loadJson(name string) ([]precompiledTest, error) { - data, err := os.ReadFile(fmt.Sprintf("testdata/precompiles/%v.json", name)) - if err != nil { - return nil, err - } - var testcases []precompiledTest - err = json.Unmarshal(data, &testcases) - return testcases, err -} - -func loadJsonFail(name string) ([]precompiledFailureTest, error) { - data, err := os.ReadFile(fmt.Sprintf("testdata/precompiles/fail-%v.json", name)) - if err != nil { - return nil, err - } - var testcases []precompiledFailureTest - err = json.Unmarshal(data, &testcases) - return testcases, err -} - -// BenchmarkPrecompiledBLS12381G1MultiExpWorstCase benchmarks the worst case we could find that still fits a gaslimit of 10MGas. -func BenchmarkPrecompiledBLS12381G1MultiExpWorstCase(b *testing.B) { - task := "0000000000000000000000000000000008d8c4a16fb9d8800cce987c0eadbb6b3b005c213d44ecb5adeed713bae79d606041406df26169c35df63cf972c94be1" + - "0000000000000000000000000000000011bc8afe71676e6730702a46ef817060249cd06cd82e6981085012ff6d013aa4470ba3a2c71e13ef653e1e223d1ccfe9" + - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - input := task - for i := 0; i < 4787; i++ { - input = input + task - } - testcase := precompiledTest{ - Input: input, - Expected: "0000000000000000000000000000000005a6310ea6f2a598023ae48819afc292b4dfcb40aabad24a0c2cb6c19769465691859eeb2a764342a810c5038d700f18000000000000000000000000000000001268ac944437d15923dc0aec00daa9250252e43e4b35ec7a19d01f0d6cd27f6e139d80dae16ba1c79cc7f57055a93ff5", - Name: "WorstCaseG1", - NoBenchmark: false, - } - benchmarkPrecompiled("0c", testcase, b) -} - -// BenchmarkPrecompiledBLS12381G2MultiExpWorstCase benchmarks the worst case we could find that still fits a gaslimit of 10MGas. -func BenchmarkPrecompiledBLS12381G2MultiExpWorstCase(b *testing.B) { - task := "000000000000000000000000000000000d4f09acd5f362e0a516d4c13c5e2f504d9bd49fdfb6d8b7a7ab35a02c391c8112b03270d5d9eefe9b659dd27601d18f" + - "000000000000000000000000000000000fd489cb75945f3b5ebb1c0e326d59602934c8f78fe9294a8877e7aeb95de5addde0cb7ab53674df8b2cfbb036b30b99" + - "00000000000000000000000000000000055dbc4eca768714e098bbe9c71cf54b40f51c26e95808ee79225a87fb6fa1415178db47f02d856fea56a752d185f86b" + - "000000000000000000000000000000001239b7640f416eb6e921fe47f7501d504fadc190d9cf4e89ae2b717276739a2f4ee9f637c35e23c480df029fd8d247c7" + - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - input := task - for i := 0; i < 1040; i++ { - input = input + task - } - - testcase := precompiledTest{ - Input: input, - Expected: "0000000000000000000000000000000018f5ea0c8b086095cfe23f6bb1d90d45de929292006dba8cdedd6d3203af3c6bbfd592e93ecb2b2c81004961fdcbb46c00000000000000000000000000000000076873199175664f1b6493a43c02234f49dc66f077d3007823e0343ad92e30bd7dc209013435ca9f197aca44d88e9dac000000000000000000000000000000000e6f07f4b23b511eac1e2682a0fc224c15d80e122a3e222d00a41fab15eba645a700b9ae84f331ae4ed873678e2e6c9b000000000000000000000000000000000bcb4849e460612aaed79617255fd30c03f51cf03d2ed4163ca810c13e1954b1e8663157b957a601829bb272a4e6c7b8", - Name: "WorstCaseG2", - NoBenchmark: false, - } - benchmarkPrecompiled("0f", testcase, b) -} diff --git a/core/vm/doc.go b/core/vm/doc.go deleted file mode 100644 index 85165df9b0..0000000000 --- a/core/vm/doc.go +++ /dev/null @@ -1,34 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -/* -Package vm implements the Ethereum Virtual Machine. - -The vm package implements one EVM, a byte code VM. The BC (Byte Code) VM loops -over a set of bytes and executes them according to the set of rules defined -in the Ethereum yellow paper. -*/ -package vm diff --git a/core/vm/eips.go b/core/vm/eips.go deleted file mode 100644 index b573705dc2..0000000000 --- a/core/vm/eips.go +++ /dev/null @@ -1,330 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "fmt" - "sort" - - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -var activators = map[int]func(*JumpTable){ - 5656: enable5656, - 6780: enable6780, - 3855: enable3855, - 3860: enable3860, - 3198: enable3198, - 2929: enable2929, - 2200: enable2200, - 1884: enable1884, - 1344: enable1344, - 1153: enable1153, -} - -// EnableEIP enables the given EIP on the config. -// This operation writes in-place, and callers need to ensure that the globally -// defined jump tables are not polluted. -func EnableEIP(eipNum int, jt *JumpTable) error { - enablerFn, ok := activators[eipNum] - if !ok { - return fmt.Errorf("undefined eip %d", eipNum) - } - enablerFn(jt) - return nil -} - -func ValidEip(eipNum int) bool { - _, ok := activators[eipNum] - return ok -} -func ActivateableEips() []string { - var nums []string - for k := range activators { - nums = append(nums, fmt.Sprintf("%d", k)) - } - sort.Strings(nums) - return nums -} - -// enable1884 applies EIP-1884 to the given jump table: -// - Increase cost of BALANCE to 700 -// - Increase cost of EXTCODEHASH to 700 -// - Increase cost of SLOAD to 800 -// - Define SELFBALANCE, with cost GasFastStep (5) -func enable1884(jt *JumpTable) { - // Gas cost changes - jt[SLOAD].constantGas = params.SloadGasEIP1884 - jt[BALANCE].constantGas = params.BalanceGasEIP1884 - jt[EXTCODEHASH].constantGas = params.ExtcodeHashGasEIP1884 - - // New opcode - jt[SELFBALANCE] = &operation{ - execute: opSelfBalance, - constantGas: GasFastStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - } -} - -func opSelfBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) - scope.Stack.push(balance) - return nil, nil -} - -// enable1344 applies EIP-1344 (ChainID Opcode) -// - Adds an opcode that returns the current chain’s EIP-155 unique identifier -func enable1344(jt *JumpTable) { - // New opcode - jt[CHAINID] = &operation{ - execute: opChainID, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - } -} - -// opChainID implements CHAINID opcode -func opChainID(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - chainId, _ := uint256.FromBig(interpreter.evm.chainConfig.ChainID) - scope.Stack.push(chainId) - return nil, nil -} - -// enable2200 applies EIP-2200 (Rebalance net-metered SSTORE) -func enable2200(jt *JumpTable) { - jt[SLOAD].constantGas = params.SloadGasEIP2200 - jt[SSTORE].dynamicGas = gasSStoreEIP2200 -} - -// enable2929 enables "EIP-2929: Gas cost increases for state access opcodes" -// https://eips.ethereum.org/EIPS/eip-2929 -func enable2929(jt *JumpTable) { - jt[SSTORE].dynamicGas = gasSStoreEIP2929 - - jt[SLOAD].constantGas = 0 - jt[SLOAD].dynamicGas = gasSLoadEIP2929 - - jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929 - jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP2929 - - jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929 - jt[EXTCODESIZE].dynamicGas = gasEip2929AccountCheck - - jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929 - jt[EXTCODEHASH].dynamicGas = gasEip2929AccountCheck - - jt[BALANCE].constantGas = params.WarmStorageReadCostEIP2929 - jt[BALANCE].dynamicGas = gasEip2929AccountCheck - - jt[CALL].constantGas = params.WarmStorageReadCostEIP2929 - jt[CALL].dynamicGas = gasCallEIP2929 - - jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929 - jt[CALLCODE].dynamicGas = gasCallCodeEIP2929 - - jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929 - jt[STATICCALL].dynamicGas = gasStaticCallEIP2929 - - jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929 - jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP2929 - - // This was previously part of the dynamic cost, but we're using it as a constantGas - // factor here - jt[SELFDESTRUCT].constantGas = params.SelfdestructGasEIP150 - jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929 -} - -// enableAP1 disables gas refunds for SSTORE and SELFDESTRUCT. It is very -// similar to EIP-3298: Removal of Refunds [DRAFT] -// (https://eips.ethereum.org/EIPS/eip-3298). -func enableAP1(jt *JumpTable) { - jt[SSTORE].dynamicGas = gasSStoreAP1 - jt[SELFDESTRUCT].dynamicGas = gasSelfdestructAP1 -} - -// enable3198 applies EIP-3198 (BASEFEE Opcode) -// - Adds an opcode that returns the current block's base fee. -func enable3198(jt *JumpTable) { - // New opcode - jt[BASEFEE] = &operation{ - execute: opBaseFee, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - } -} - -// enable1153 applies EIP-1153 "Transient Storage" -// - Adds TLOAD that reads from transient storage -// - Adds TSTORE that writes to transient storage -func enable1153(jt *JumpTable) { - jt[TLOAD] = &operation{ - execute: opTload, - constantGas: params.WarmStorageReadCostEIP2929, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - } - - jt[TSTORE] = &operation{ - execute: opTstore, - constantGas: params.WarmStorageReadCostEIP2929, - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - } -} - -// opTload implements TLOAD opcode -func opTload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - loc := scope.Stack.peek() - hash := common.Hash(loc.Bytes32()) - val := interpreter.evm.StateDB.GetTransientState(scope.Contract.Address(), hash) - loc.SetBytes(val.Bytes()) - return nil, nil -} - -// opTstore implements TSTORE opcode -func opTstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.readOnly { - return nil, vmerrs.ErrWriteProtection - } - loc := scope.Stack.pop() - val := scope.Stack.pop() - interpreter.evm.StateDB.SetTransientState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32()) - return nil, nil -} - -// opBaseFee implements BASEFEE opcode -func opBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - baseFee, _ := uint256.FromBig(interpreter.evm.Context.BaseFee) - scope.Stack.push(baseFee) - return nil, nil -} - -// enable3855 applies EIP-3855 (PUSH0 opcode) -func enable3855(jt *JumpTable) { - // New opcode - jt[PUSH0] = &operation{ - execute: opPush0, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - } -} - -// opPush0 implements the PUSH0 opcode -func opPush0(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int)) - return nil, nil -} - -// enable3860 enables "EIP-3860: Limit and meter initcode" -// https://eips.ethereum.org/EIPS/eip-3860 -func enable3860(jt *JumpTable) { - jt[CREATE].dynamicGas = gasCreateEip3860 - jt[CREATE2].dynamicGas = gasCreate2Eip3860 -} - -// enable5656 enables EIP-5656 (MCOPY opcode) -// https://eips.ethereum.org/EIPS/eip-5656 -func enable5656(jt *JumpTable) { - jt[MCOPY] = &operation{ - execute: opMcopy, - constantGas: GasFastestStep, - dynamicGas: gasMcopy, - minStack: minStack(3, 0), - maxStack: maxStack(3, 0), - memorySize: memoryMcopy, - } -} - -// opMcopy implements the MCOPY opcode (https://eips.ethereum.org/EIPS/eip-5656) -func opMcopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - var ( - dst = scope.Stack.pop() - src = scope.Stack.pop() - length = scope.Stack.pop() - ) - // These values are checked for overflow during memory expansion calculation - // (the memorySize function on the opcode). - scope.Memory.Copy(dst.Uint64(), src.Uint64(), length.Uint64()) - return nil, nil -} - -// opBlobHash implements the BLOBHASH opcode -func opBlobHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - index := scope.Stack.peek() - if index.LtUint64(uint64(len(interpreter.evm.TxContext.BlobHashes))) { - blobHash := interpreter.evm.TxContext.BlobHashes[index.Uint64()] - index.SetBytes32(blobHash[:]) - } else { - index.Clear() - } - return nil, nil -} - -// opBlobBaseFee implements BLOBBASEFEE opcode -func opBlobBaseFee(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - blobBaseFee, _ := uint256.FromBig(interpreter.evm.Context.BlobBaseFee) - scope.Stack.push(blobBaseFee) - return nil, nil -} - -// enable4844 applies EIP-4844 (BLOBHASH opcode) -func enable4844(jt *JumpTable) { - jt[BLOBHASH] = &operation{ - execute: opBlobHash, - constantGas: GasFastestStep, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - } -} - -// enable7516 applies EIP-7516 (BLOBBASEFEE opcode) -func enable7516(jt *JumpTable) { - jt[BLOBBASEFEE] = &operation{ - execute: opBlobBaseFee, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - } -} - -// enable6780 applies EIP-6780 (deactivate SELFDESTRUCT) -func enable6780(jt *JumpTable) { - jt[SELFDESTRUCT] = &operation{ - execute: opSelfdestruct6780, - dynamicGas: gasSelfdestructEIP3529, - constantGas: params.SelfdestructGasEIP150, - minStack: minStack(1, 0), - maxStack: maxStack(1, 0), - } -} diff --git a/core/vm/errors.go b/core/vm/errors.go deleted file mode 100644 index 683a5651c4..0000000000 --- a/core/vm/errors.go +++ /dev/null @@ -1,68 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "errors" - "fmt" -) - -// List evm execution errors -var ( - // errStopToken is an internal token indicating interpreter loop termination, - // never returned to outside callers. - errStopToken = errors.New("stop token") -) - -// ErrStackUnderflow wraps an evm error when the items on the stack less -// than the minimal requirement. -type ErrStackUnderflow struct { - stackLen int - required int -} - -func (e *ErrStackUnderflow) Error() string { - return fmt.Sprintf("stack underflow (%d <=> %d)", e.stackLen, e.required) -} - -// ErrStackOverflow wraps an evm error when the items on the stack exceeds -// the maximum allowance. -type ErrStackOverflow struct { - stackLen int - limit int -} - -func (e *ErrStackOverflow) Error() string { - return fmt.Sprintf("stack limit reached %d (%d)", e.stackLen, e.limit) -} - -// ErrInvalidOpCode wraps an evm error when an invalid opcode is encountered. -type ErrInvalidOpCode struct { - opcode OpCode -} - -func (e *ErrInvalidOpCode) Error() string { return fmt.Sprintf("invalid opcode: %s", e.opcode) } diff --git a/core/vm/evm.go b/core/vm/evm.go deleted file mode 100644 index 2d26282b03..0000000000 --- a/core/vm/evm.go +++ /dev/null @@ -1,719 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "math/big" - "sync/atomic" - - "github.com/ava-labs/avalanchego/snow" - "github.com/ava-labs/coreth/constants" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/plugin/evm/header" - "github.com/ava-labs/coreth/precompile/contract" - "github.com/ava-labs/coreth/precompile/modules" - "github.com/ava-labs/coreth/precompile/precompileconfig" - "github.com/ava-labs/coreth/predicate" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/holiman/uint256" -) - -var ( - _ contract.AccessibleState = &EVM{} - _ contract.BlockContext = &BlockContext{} -) - -// IsProhibited returns true if [addr] is in the prohibited list of addresses which should -// not be allowed as an EOA or newly created contract address. -func IsProhibited(addr common.Address) bool { - if addr == constants.BlackholeAddr { - return true - } - - return modules.ReservedAddress(addr) -} - -type ( - // CanTransferFunc is the signature of a transfer guard function - CanTransferFunc func(StateDB, common.Address, *uint256.Int) bool - CanTransferMCFunc func(StateDB, common.Address, common.Address, common.Hash, *big.Int) bool - // TransferFunc is the signature of a transfer function - TransferFunc func(StateDB, common.Address, common.Address, *uint256.Int) - TransferMCFunc func(StateDB, common.Address, common.Address, common.Hash, *big.Int) - // GetHashFunc returns the n'th block hash in the blockchain - // and is used by the BLOCKHASH EVM op code. - GetHashFunc func(uint64) common.Hash -) - -func (evm *EVM) precompile(addr common.Address) (contract.StatefulPrecompiledContract, bool) { - var precompiles map[common.Address]contract.StatefulPrecompiledContract - switch { - case evm.chainRules.IsCancun: - precompiles = PrecompiledContractsCancun - case evm.chainRules.IsBanff: - precompiles = PrecompiledContractsBanff - case evm.chainRules.IsApricotPhase6: - precompiles = PrecompiledContractsApricotPhase6 - case evm.chainRules.IsApricotPhasePre6: - precompiles = PrecompiledContractsApricotPhasePre6 - case evm.chainRules.IsApricotPhase2: - precompiles = PrecompiledContractsApricotPhase2 - case evm.chainRules.IsIstanbul: - precompiles = PrecompiledContractsIstanbul - case evm.chainRules.IsByzantium: - precompiles = PrecompiledContractsByzantium - default: - precompiles = PrecompiledContractsHomestead - } - - // Check the existing precompiles first - p, ok := precompiles[addr] - if ok { - return p, true - } - - // Otherwise, check the chain rules for the additionally configured precompiles. - if _, ok = evm.chainRules.ActivePrecompiles[addr]; ok { - module, ok := modules.GetPrecompileModuleByAddress(addr) - return module.Contract, ok - } - - return nil, false -} - -// BlockContext provides the EVM with auxiliary information. Once provided -// it shouldn't be modified. -type BlockContext struct { - // CanTransfer returns whether the account contains - // sufficient ether to transfer the value - CanTransfer CanTransferFunc - // CanTransferMC returns whether the account contains - // sufficient multicoin balance to transfer the value - CanTransferMC CanTransferMCFunc - // Transfer transfers ether from one account to the other - Transfer TransferFunc - // TransferMultiCoin transfers multicoin from one account to the other - TransferMultiCoin TransferMCFunc - // GetHash returns the hash corresponding to n - GetHash GetHashFunc - // PredicateResults are the results of predicate verification available - // throughout the EVM's execution. - // - // PredicateResults may be nil if it is not encoded in the extra field of - // the block's header or if the extra field has not been parsed yet. - PredicateResults *predicate.Results - // Extra is the extra field from the block header. - Extra []byte - - // Block information - Coinbase common.Address // Provides information for COINBASE - GasLimit uint64 // Provides information for GASLIMIT - BlockNumber *big.Int // Provides information for NUMBER - Time uint64 // Provides information for TIME - Difficulty *big.Int // Provides information for DIFFICULTY - BaseFee *big.Int // Provides information for BASEFEE - BlobBaseFee *big.Int // Provides information for BLOBBASEFEE (0 if vm runs with NoBaseFee flag and 0 blob gas price) -} - -func (b *BlockContext) Number() *big.Int { - return b.BlockNumber -} - -func (b *BlockContext) Timestamp() uint64 { - return b.Time -} - -func (b *BlockContext) GetPredicateResults(txHash common.Hash, address common.Address) []byte { - if b.PredicateResults == nil { - return nil - } - return b.PredicateResults.GetResults(txHash, address) -} - -// TxContext provides the EVM with information about a transaction. -// All fields can change between transactions. -type TxContext struct { - // Message information - Origin common.Address // Provides information for ORIGIN - GasPrice *big.Int // Provides information for GASPRICE (and is used to zero the basefee if NoBaseFee is set) - BlobHashes []common.Hash // Provides information for BLOBHASH - BlobFeeCap *big.Int // Is used to zero the blobbasefee if NoBaseFee is set -} - -// EVM is the Ethereum Virtual Machine base object and provides -// the necessary tools to run a contract on the given state with -// the provided context. It should be noted that any error -// generated through any of the calls should be considered a -// revert-state-and-consume-all-gas operation, no checks on -// specific errors should ever be performed. The interpreter makes -// sure that any errors generated are to be considered faulty code. -// -// The EVM should never be reused and is not thread safe. -type EVM struct { - // Context provides auxiliary blockchain related information - Context BlockContext - TxContext - // StateDB gives access to the underlying state - StateDB StateDB - // Depth is the current call stack - depth int - - // chainConfig contains information about the current chain - chainConfig *params.ChainConfig - // chain rules contains the chain rules for the current epoch - chainRules params.Rules - // virtual machine configuration options used to initialise the - // evm. - Config Config - // global (to this context) ethereum virtual machine - // used throughout the execution of the tx. - interpreter *EVMInterpreter - // abort is used to abort the EVM calling operations - abort atomic.Bool - // callGasTemp holds the gas available for the current call. This is needed because the - // available gas is calculated in gasCall* according to the 63/64 rule and later - // applied in opCall*. - callGasTemp uint64 -} - -// NewEVM returns a new EVM. The returned EVM is not thread safe and should -// only ever be used *once*. -func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig *params.ChainConfig, config Config) *EVM { - // If basefee tracking is disabled (eth_call, eth_estimateGas, etc), and no - // gas prices were specified, lower the basefee to 0 to avoid breaking EVM - // invariants (basefee < feecap) - if config.NoBaseFee { - if txCtx.GasPrice.BitLen() == 0 { - blockCtx.BaseFee = new(big.Int) - } - if txCtx.BlobFeeCap != nil && txCtx.BlobFeeCap.BitLen() == 0 { - blockCtx.BlobBaseFee = new(big.Int) - } - } - evm := &EVM{ - Context: blockCtx, - TxContext: txCtx, - StateDB: statedb, - Config: config, - chainConfig: chainConfig, - chainRules: chainConfig.Rules(blockCtx.BlockNumber, blockCtx.Time), - } - evm.interpreter = NewEVMInterpreter(evm) - - // If the predicate results were set by the miner, use them. - if blockCtx.PredicateResults != nil { - return evm - } - - // Parse the predicate results from the extra field and store them in the - // block context. - predicateBytes := header.PredicateBytesFromExtra(evm.chainRules.AvalancheRules, blockCtx.Extra) - if len(predicateBytes) == 0 { - return evm - } - - // The VM has already verified the correctness of the results during header - // validation. - results, err := predicate.ParseResults(predicateBytes) - if err != nil { - log.Error("Unexpected error parsing predicate results", - "err", err, - ) - return evm - } - - // Because the BlockContext is pass-by-value, this does not cache the - // results for future calls to NewEVM. - evm.Context.PredicateResults = results - return evm -} - -// Reset resets the EVM with a new transaction context.Reset -// This is not threadsafe and should only be done very cautiously. -func (evm *EVM) Reset(txCtx TxContext, statedb StateDB) { - evm.TxContext = txCtx - evm.StateDB = statedb -} - -// Cancel cancels any running EVM operation. This may be called concurrently and -// it's safe to be called multiple times. -func (evm *EVM) Cancel() { - evm.abort.Store(true) -} - -// Cancelled returns true if Cancel has been called -func (evm *EVM) Cancelled() bool { - return evm.abort.Load() -} - -// GetSnowContext returns the evm's snow.Context. -func (evm *EVM) GetSnowContext() *snow.Context { - return evm.chainConfig.SnowCtx -} - -// GetStateDB returns the evm's StateDB -func (evm *EVM) GetStateDB() contract.StateDB { - return evm.StateDB -} - -// GetBlockContext returns the evm's BlockContext -func (evm *EVM) GetBlockContext() contract.BlockContext { - return &evm.Context -} - -// Interpreter returns the current interpreter -func (evm *EVM) Interpreter() *EVMInterpreter { - return evm.interpreter -} - -// Call executes the contract associated with the addr with the given input as -// parameters. It also handles any necessary value transfer required and takes -// the necessary steps to create accounts and reverses the state in case of an -// execution error or failed value transfer. -func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) { - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, vmerrs.ErrDepth - } - // Fail if we're trying to transfer more than the available balance - if !value.IsZero() && !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { - return nil, gas, vmerrs.ErrInsufficientBalance - } - snapshot := evm.StateDB.Snapshot() - p, isPrecompile := evm.precompile(addr) - debug := evm.Config.Tracer != nil - - if !evm.StateDB.Exist(addr) { - if !isPrecompile && evm.chainRules.IsEIP158 && value.IsZero() { - // Calling a non existing account, don't do anything, but ping the tracer - if debug { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value.ToBig()) - evm.Config.Tracer.CaptureEnd(ret, 0, nil) - } else { - evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value.ToBig()) - evm.Config.Tracer.CaptureExit(ret, 0, nil) - } - } - return nil, gas, nil - } - evm.StateDB.CreateAccount(addr) - } - evm.Context.Transfer(evm.StateDB, caller.Address(), addr, value) - - // Capture the tracer start/end events in debug mode - if debug { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(evm, caller.Address(), addr, false, input, gas, value.ToBig()) - defer func(startGas uint64) { // Lazy evaluation of the parameters - evm.Config.Tracer.CaptureEnd(ret, startGas-gas, err) - }(gas) - } else { - // Handle tracer events for entering and exiting a call frame - evm.Config.Tracer.CaptureEnter(CALL, caller.Address(), addr, input, gas, value.ToBig()) - defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) - }(gas) - } - } - - if isPrecompile { - ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, evm.interpreter.readOnly) - } else { - // Initialise a new contract and set the code that is to be used by the EVM. - // The contract is a scoped environment for this execution context only. - code := evm.StateDB.GetCode(addr) - if len(code) == 0 { - ret, err = nil, nil // gas is unchanged - } else { - addrCopy := addr - // If the account has no code, we can abort here - // The depth-check is already done, and precompiles handled above - contract := NewContract(caller, AccountRef(addrCopy), value, gas) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), code) - ret, err = evm.interpreter.Run(contract, input, false) - gas = contract.Gas - } - } - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in homestead this also counts for code storage gas errors. - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != vmerrs.ErrExecutionReverted { - gas = 0 - } - // TODO: consider clearing up unused snapshots: - //} else { - // evm.StateDB.DiscardSnapshot(snapshot) - } - return ret, gas, err -} - -// CallCode executes the contract associated with the addr with the given input -// as parameters. It also handles any necessary value transfer required and takes -// the necessary steps to create accounts and reverses the state in case of an -// execution error or failed value transfer. -// -// CallCode differs from Call in the sense that it executes the given address' -// code with the caller as context. -func (evm *EVM) CallCode(caller ContractRef, addr common.Address, input []byte, gas uint64, value *uint256.Int) (ret []byte, leftOverGas uint64, err error) { - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, vmerrs.ErrDepth - } - // Fail if we're trying to transfer more than the available balance - // Note although it's noop to transfer X ether to caller itself. But - // if caller doesn't have enough balance, it would be an error to allow - // over-charging itself. So the check here is necessary. - // Note: it is not possible for a negative value to be passed in here due to the fact - // that [value] will be popped from the stack and decoded to a *big.Int, which will - // always yield a positive result. - if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { - return nil, gas, vmerrs.ErrInsufficientBalance - } - var snapshot = evm.StateDB.Snapshot() - - // Invoke tracer hooks that signal entering/exiting a call frame - if evm.Config.Tracer != nil { - evm.Config.Tracer.CaptureEnter(CALLCODE, caller.Address(), addr, input, gas, value.ToBig()) - defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) - }(gas) - } - - // It is allowed to call precompiles, even via delegatecall - if p, isPrecompile := evm.precompile(addr); isPrecompile { - ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, evm.interpreter.readOnly) - } else { - addrCopy := addr - // Initialise a new contract and set the code that is to be used by the EVM. - // The contract is a scoped environment for this execution context only. - contract := NewContract(caller, AccountRef(caller.Address()), value, gas) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) - ret, err = evm.interpreter.Run(contract, input, false) - gas = contract.Gas - } - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != vmerrs.ErrExecutionReverted { - gas = 0 - } - } - return ret, gas, err -} - -// DelegateCall executes the contract associated with the addr with the given input -// as parameters. It reverses the state in case of an execution error. -// -// DelegateCall differs from CallCode in the sense that it executes the given address' -// code with the caller as context and the caller is set to the caller of the caller. -func (evm *EVM) DelegateCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, vmerrs.ErrDepth - } - var snapshot = evm.StateDB.Snapshot() - - // Invoke tracer hooks that signal entering/exiting a call frame - if evm.Config.Tracer != nil { - // NOTE: caller must, at all times be a contract. It should never happen - // that caller is something other than a Contract. - parent := caller.(*Contract) - // DELEGATECALL inherits value from parent call - evm.Config.Tracer.CaptureEnter(DELEGATECALL, caller.Address(), addr, input, gas, parent.value.ToBig()) - defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) - }(gas) - } - - // It is allowed to call precompiles, even via delegatecall - if p, isPrecompile := evm.precompile(addr); isPrecompile { - ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, evm.interpreter.readOnly) - } else { - addrCopy := addr - // Initialise a new contract and make initialise the delegate values - contract := NewContract(caller, AccountRef(caller.Address()), nil, gas).AsDelegate() - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) - ret, err = evm.interpreter.Run(contract, input, false) - gas = contract.Gas - } - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != vmerrs.ErrExecutionReverted { - gas = 0 - } - } - return ret, gas, err -} - -// StaticCall executes the contract associated with the addr with the given input -// as parameters while disallowing any modifications to the state during the call. -// Opcodes that attempt to perform such modifications will result in exceptions -// instead of performing the modifications. -func (evm *EVM) StaticCall(caller ContractRef, addr common.Address, input []byte, gas uint64) (ret []byte, leftOverGas uint64, err error) { - // Fail if we're trying to execute above the call depth limit - if evm.depth > int(params.CallCreateDepth) { - return nil, gas, vmerrs.ErrDepth - } - // We take a snapshot here. This is a bit counter-intuitive, and could probably be skipped. - // However, even a staticcall is considered a 'touch'. On mainnet, static calls were introduced - // after all empty accounts were deleted, so this is not required. However, if we omit this, - // then certain tests start failing; stRevertTest/RevertPrecompiledTouchExactOOG.json. - // We could change this, but for now it's left for legacy reasons - var snapshot = evm.StateDB.Snapshot() - - // We do an AddBalance of zero here, just in order to trigger a touch. - // This doesn't matter on Mainnet, where all empties are gone at the time of Byzantium, - // but is the correct thing to do and matters on other networks, in tests, and potential - // future scenarios - evm.StateDB.AddBalance(addr, new(uint256.Int)) - - // Invoke tracer hooks that signal entering/exiting a call frame - if evm.Config.Tracer != nil { - evm.Config.Tracer.CaptureEnter(STATICCALL, caller.Address(), addr, input, gas, nil) - defer func(startGas uint64) { - evm.Config.Tracer.CaptureExit(ret, startGas-gas, err) - }(gas) - } - - if p, isPrecompile := evm.precompile(addr); isPrecompile { - ret, gas, err = RunStatefulPrecompiledContract(p, evm, caller.Address(), addr, input, gas, true) - } else { - // At this point, we use a copy of address. If we don't, the go compiler will - // leak the 'contract' to the outer scope, and make allocation for 'contract' - // even if the actual execution ends on RunPrecompiled above. - addrCopy := addr - // Initialise a new contract and set the code that is to be used by the EVM. - // The contract is a scoped environment for this execution context only. - contract := NewContract(caller, AccountRef(addrCopy), new(uint256.Int), gas) - contract.SetCallCode(&addrCopy, evm.StateDB.GetCodeHash(addrCopy), evm.StateDB.GetCode(addrCopy)) - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in Homestead this also counts for code storage gas errors. - ret, err = evm.interpreter.Run(contract, input, true) - gas = contract.Gas - } - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != vmerrs.ErrExecutionReverted { - gas = 0 - } - } - return ret, gas, err -} - -type codeAndHash struct { - code []byte - hash common.Hash -} - -func (c *codeAndHash) Hash() common.Hash { - if c.hash == (common.Hash{}) { - c.hash = crypto.Keccak256Hash(c.code) - } - return c.hash -} - -// create creates a new contract using code as deployment code. -func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64, value *uint256.Int, address common.Address, typ OpCode) ([]byte, common.Address, uint64, error) { - // Depth check execution. Fail if we're trying to execute above the - // limit. - if evm.depth > int(params.CallCreateDepth) { - return nil, common.Address{}, gas, vmerrs.ErrDepth - } - // Note: it is not possible for a negative value to be passed in here due to the fact - // that [value] will be popped from the stack and decoded to a *big.Int, which will - // always yield a positive result. - if !evm.Context.CanTransfer(evm.StateDB, caller.Address(), value) { - return nil, common.Address{}, gas, vmerrs.ErrInsufficientBalance - } - // If there is any collision with a prohibited address, return an error instead - // of allowing the contract to be created. - if IsProhibited(address) { - return nil, common.Address{}, gas, vmerrs.ErrAddrProhibited - } - nonce := evm.StateDB.GetNonce(caller.Address()) - if nonce+1 < nonce { - return nil, common.Address{}, gas, vmerrs.ErrNonceUintOverflow - } - evm.StateDB.SetNonce(caller.Address(), nonce+1) - // We add this to the access list _before_ taking a snapshot. Even if the creation fails, - // the access-list change should not be rolled back - if evm.chainRules.IsApricotPhase2 { - evm.StateDB.AddAddressToAccessList(address) - } - // Ensure there's no existing contract already at the designated address - contractHash := evm.StateDB.GetCodeHash(address) - if evm.StateDB.GetNonce(address) != 0 || (contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) { - return nil, common.Address{}, 0, vmerrs.ErrContractAddressCollision - } - // Create a new account on the state - snapshot := evm.StateDB.Snapshot() - evm.StateDB.CreateAccount(address) - if evm.chainRules.IsEIP158 { - evm.StateDB.SetNonce(address, 1) - } - evm.Context.Transfer(evm.StateDB, caller.Address(), address, value) - - // Initialise a new contract and set the code that is to be used by the EVM. - // The contract is a scoped environment for this execution context only. - contract := NewContract(caller, AccountRef(address), value, gas) - contract.SetCodeOptionalHash(&address, codeAndHash) - - if evm.Config.Tracer != nil { - if evm.depth == 0 { - evm.Config.Tracer.CaptureStart(evm, caller.Address(), address, true, codeAndHash.code, gas, value.ToBig()) - } else { - evm.Config.Tracer.CaptureEnter(typ, caller.Address(), address, codeAndHash.code, gas, value.ToBig()) - } - } - - ret, err := evm.interpreter.Run(contract, nil, false) - - // Check whether the max code size has been exceeded, assign err if the case. - if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize { - err = vmerrs.ErrMaxCodeSizeExceeded - } - - // Reject code starting with 0xEF if EIP-3541 is enabled. - if err == nil && len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsApricotPhase3 { - err = vmerrs.ErrInvalidCode - } - - // if the contract creation ran successfully and no errors were returned - // calculate the gas required to store the code. If the code could not - // be stored due to not enough gas set an error and let it be handled - // by the error checking condition below. - if err == nil { - createDataGas := uint64(len(ret)) * params.CreateDataGas - if contract.UseGas(createDataGas) { - evm.StateDB.SetCode(address, ret) - } else { - err = vmerrs.ErrCodeStoreOutOfGas - } - } - - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in homestead this also counts for code storage gas errors. - if err != nil && (evm.chainRules.IsHomestead || err != vmerrs.ErrCodeStoreOutOfGas) { - evm.StateDB.RevertToSnapshot(snapshot) - if err != vmerrs.ErrExecutionReverted { - contract.UseGas(contract.Gas) - } - } - - if evm.Config.Tracer != nil { - if evm.depth == 0 { - evm.Config.Tracer.CaptureEnd(ret, gas-contract.Gas, err) - } else { - evm.Config.Tracer.CaptureExit(ret, gas-contract.Gas, err) - } - } - return ret, address, contract.Gas, err -} - -// Create creates a new contract using code as deployment code. -func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address())) - return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE) -} - -// Create2 creates a new contract using code as deployment code. -// -// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:] -// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at. -func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *uint256.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) { - codeAndHash := &codeAndHash{code: code} - contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes()) - return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2) -} - -// ChainConfig returns the environment's chain configuration -func (evm *EVM) ChainConfig() *params.ChainConfig { return evm.chainConfig } - -// GetChainConfig implements AccessibleState -func (evm *EVM) GetChainConfig() precompileconfig.ChainConfig { return evm.chainConfig } - -func (evm *EVM) NativeAssetCall(caller common.Address, input []byte, suppliedGas uint64, gasCost uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { - if suppliedGas < gasCost { - return nil, 0, vmerrs.ErrOutOfGas - } - remainingGas = suppliedGas - gasCost - - if readOnly { - return nil, remainingGas, vmerrs.ErrExecutionReverted - } - - to, assetID, assetAmount, callData, err := UnpackNativeAssetCallInput(input) - if err != nil { - return nil, remainingGas, vmerrs.ErrExecutionReverted - } - - // Note: it is not possible for a negative assetAmount to be passed in here due to the fact that decoding a - // byte slice into a *big.Int type will always return a positive value. - if assetAmount.Sign() != 0 && !evm.Context.CanTransferMC(evm.StateDB, caller, to, assetID, assetAmount) { - return nil, remainingGas, vmerrs.ErrInsufficientBalance - } - - snapshot := evm.StateDB.Snapshot() - - if !evm.StateDB.Exist(to) { - if remainingGas < params.CallNewAccountGas { - return nil, 0, vmerrs.ErrOutOfGas - } - remainingGas -= params.CallNewAccountGas - evm.StateDB.CreateAccount(to) - } - - // Increment the call depth which is restricted to 1024 - evm.depth++ - defer func() { evm.depth-- }() - - // Send [assetAmount] of [assetID] to [to] address - evm.Context.TransferMultiCoin(evm.StateDB, caller, to, assetID, assetAmount) - ret, remainingGas, err = evm.Call(AccountRef(caller), to, callData, remainingGas, new(uint256.Int)) - - // When an error was returned by the EVM or when setting the creation code - // above we revert to the snapshot and consume any gas remaining. Additionally - // when we're in homestead this also counts for code storage gas errors. - if err != nil { - evm.StateDB.RevertToSnapshot(snapshot) - if err != vmerrs.ErrExecutionReverted { - remainingGas = 0 - } - // TODO: consider clearing up unused snapshots: - //} else { - // evm.StateDB.DiscardSnapshot(snapshot) - } - return ret, remainingGas, err -} diff --git a/core/vm/evm_test.go b/core/vm/evm_test.go deleted file mode 100644 index 5a7e72f3f4..0000000000 --- a/core/vm/evm_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// (c) 2022, Ava Labs, Inc. All rights reserved. -// See the file LICENSE for licensing terms. - -package vm - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/assert" -) - -func TestIsProhibited(t *testing.T) { - // reserved addresses - assert.True(t, IsProhibited(common.HexToAddress("0x0100000000000000000000000000000000000000"))) - assert.True(t, IsProhibited(common.HexToAddress("0x0100000000000000000000000000000000000010"))) - assert.True(t, IsProhibited(common.HexToAddress("0x01000000000000000000000000000000000000f0"))) - assert.True(t, IsProhibited(common.HexToAddress("0x01000000000000000000000000000000000000ff"))) - assert.True(t, IsProhibited(common.HexToAddress("0x0200000000000000000000000000000000000000"))) - assert.True(t, IsProhibited(common.HexToAddress("0x0200000000000000000000000000000000000010"))) - assert.True(t, IsProhibited(common.HexToAddress("0x02000000000000000000000000000000000000f0"))) - assert.True(t, IsProhibited(common.HexToAddress("0x02000000000000000000000000000000000000ff"))) - // reserved addresses (custom precompiles) - assert.True(t, IsProhibited(common.HexToAddress("0x0300000000000000000000000000000000000000"))) - assert.True(t, IsProhibited(common.HexToAddress("0x0300000000000000000000000000000000000010"))) - assert.True(t, IsProhibited(common.HexToAddress("0x03000000000000000000000000000000000000f0"))) - assert.True(t, IsProhibited(common.HexToAddress("0x03000000000000000000000000000000000000ff"))) - - // allowed for use - assert.False(t, IsProhibited(common.HexToAddress("0x00000000000000000000000000000000000000ff"))) - assert.False(t, IsProhibited(common.HexToAddress("0x00ffffffffffffffffffffffffffffffffffffff"))) - assert.False(t, IsProhibited(common.HexToAddress("0x0100000000000000000000000000000000000100"))) - assert.False(t, IsProhibited(common.HexToAddress("0x0200000000000000000000000000000000000100"))) - assert.False(t, IsProhibited(common.HexToAddress("0x0300000000000000000000000000000000000100"))) -} diff --git a/core/vm/gas.go b/core/vm/gas.go deleted file mode 100644 index 1a195acf2a..0000000000 --- a/core/vm/gas.go +++ /dev/null @@ -1,64 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "github.com/ava-labs/coreth/vmerrs" - "github.com/holiman/uint256" -) - -// Gas costs -const ( - GasQuickStep uint64 = 2 - GasFastestStep uint64 = 3 - GasFastStep uint64 = 5 - GasMidStep uint64 = 8 - GasSlowStep uint64 = 10 - GasExtStep uint64 = 20 -) - -// callGas returns the actual gas cost of the call. -// -// The cost of gas was changed during the homestead price change HF. -// As part of EIP 150 (TangerineWhistle), the returned gas is gas - base * 63 / 64. -func callGas(isEip150 bool, availableGas, base uint64, callCost *uint256.Int) (uint64, error) { - if isEip150 { - availableGas = availableGas - base - gas := availableGas - availableGas/64 - // If the bit length exceeds 64 bit we know that the newly calculated "gas" for EIP150 - // is smaller than the requested amount. Therefore we return the new gas instead - // of returning an error. - if !callCost.IsUint64() || gas < callCost.Uint64() { - return gas, nil - } - } - if !callCost.IsUint64() { - return 0, vmerrs.ErrGasUintOverflow - } - - return callCost.Uint64(), nil -} diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go deleted file mode 100644 index 68a2ae2d58..0000000000 --- a/core/vm/gas_table.go +++ /dev/null @@ -1,545 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "errors" - - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" -) - -// memoryGasCost calculates the quadratic gas for memory expansion. It does so -// only for the memory region that is expanded, not the total memory. -func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) { - if newMemSize == 0 { - return 0, nil - } - // The maximum that will fit in a uint64 is max_word_count - 1. Anything above - // that will result in an overflow. Additionally, a newMemSize which results in - // a newMemSizeWords larger than 0xFFFFFFFF will cause the square operation to - // overflow. The constant 0x1FFFFFFFE0 is the highest number that can be used - // without overflowing the gas calculation. - if newMemSize > 0x1FFFFFFFE0 { - return 0, vmerrs.ErrGasUintOverflow - } - newMemSizeWords := toWordSize(newMemSize) - newMemSize = newMemSizeWords * 32 - - if newMemSize > uint64(mem.Len()) { - square := newMemSizeWords * newMemSizeWords - linCoef := newMemSizeWords * params.MemoryGas - quadCoef := square / params.QuadCoeffDiv - newTotalFee := linCoef + quadCoef - - fee := newTotalFee - mem.lastGasCost - mem.lastGasCost = newTotalFee - - return fee, nil - } - return 0, nil -} - -// memoryCopierGas creates the gas functions for the following opcodes, and takes -// the stack position of the operand which determines the size of the data to copy -// as argument: -// CALLDATACOPY (stack position 2) -// CODECOPY (stack position 2) -// MCOPY (stack position 2) -// EXTCODECOPY (stack position 3) -// RETURNDATACOPY (stack position 2) -func memoryCopierGas(stackpos int) gasFunc { - return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - // Gas for expanding the memory - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - // And gas for copying data, charged per word at param.CopyGas - words, overflow := stack.Back(stackpos).Uint64WithOverflow() - if overflow { - return 0, vmerrs.ErrGasUintOverflow - } - - if words, overflow = math.SafeMul(toWordSize(words), params.CopyGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - - if gas, overflow = math.SafeAdd(gas, words); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil - } -} - -var ( - gasCallDataCopy = memoryCopierGas(2) - gasCodeCopy = memoryCopierGas(2) - gasMcopy = memoryCopierGas(2) - gasExtCodeCopy = memoryCopierGas(3) - gasReturnDataCopy = memoryCopierGas(2) -) - -func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var ( - y, x = stack.Back(1), stack.Back(0) - current = evm.StateDB.GetState(contract.Address(), x.Bytes32()) - ) - // The legacy gas metering only takes into consideration the current state - // Legacy rules should be applied if we are in Petersburg (removal of EIP-1283) - // OR Constantinople is not active - if evm.chainRules.IsPetersburg || !evm.chainRules.IsConstantinople { - // This checks for 3 scenarios and calculates gas accordingly: - // - // 1. From a zero-value address to a non-zero value (NEW VALUE) - // 2. From a non-zero value address to a zero-value address (DELETE) - // 3. From a non-zero to a non-zero (CHANGE) - switch { - case current == (common.Hash{}) && y.Sign() != 0: // 0 => non 0 - return params.SstoreSetGas, nil - case current != (common.Hash{}) && y.Sign() == 0: // non 0 => 0 - evm.StateDB.AddRefund(params.SstoreRefundGas) - return params.SstoreClearGas, nil - default: // non 0 => non 0 (or 0 => 0) - return params.SstoreResetGas, nil - } - } - - // The new gas metering is based on net gas costs (EIP-1283): - // - // (1.) If current value equals new value (this is a no-op), 200 gas is deducted. - // (2.) If current value does not equal new value - // (2.1.) If original value equals current value (this storage slot has not been changed by the current execution context) - // (2.1.1.) If original value is 0, 20000 gas is deducted. - // (2.1.2.) Otherwise, 5000 gas is deducted. If new value is 0, add 15000 gas to refund counter. - // (2.2.) If original value does not equal current value (this storage slot is dirty), 200 gas is deducted. Apply both of the following clauses. - // (2.2.1.) If original value is not 0 - // (2.2.1.1.) If current value is 0 (also means that new value is not 0), remove 15000 gas from refund counter. We can prove that refund counter will never go below 0. - // (2.2.1.2.) If new value is 0 (also means that current value is not 0), add 15000 gas to refund counter. - // (2.2.2.) If original value equals new value (this storage slot is reset) - // (2.2.2.1.) If original value is 0, add 19800 gas to refund counter. - // (2.2.2.2.) Otherwise, add 4800 gas to refund counter. - value := common.Hash(y.Bytes32()) - if current == value { // noop (1) - return params.NetSstoreNoopGas, nil - } - original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32()) - if original == current { - if original == (common.Hash{}) { // create slot (2.1.1) - return params.NetSstoreInitGas, nil - } - if value == (common.Hash{}) { // delete slot (2.1.2b) - evm.StateDB.AddRefund(params.NetSstoreClearRefund) - } - return params.NetSstoreCleanGas, nil // write existing slot (2.1.2) - } - if original != (common.Hash{}) { - if current == (common.Hash{}) { // recreate slot (2.2.1.1) - evm.StateDB.SubRefund(params.NetSstoreClearRefund) - } else if value == (common.Hash{}) { // delete slot (2.2.1.2) - evm.StateDB.AddRefund(params.NetSstoreClearRefund) - } - } - if original == value { - if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1) - evm.StateDB.AddRefund(params.NetSstoreResetClearRefund) - } else { // reset to original existing slot (2.2.2.2) - evm.StateDB.AddRefund(params.NetSstoreResetRefund) - } - } - return params.NetSstoreDirtyGas, nil -} - -// Here come the EIP2200 rules: -// -// (0.) If *gasleft* is less than or equal to 2300, fail the current call. -// (1.) If current value equals new value (this is a no-op), SLOAD_GAS is deducted. -// (2.) If current value does not equal new value: -// (2.1.) If original value equals current value (this storage slot has not been changed by the current execution context): -// (2.1.1.) If original value is 0, SSTORE_SET_GAS (20K) gas is deducted. -// (2.1.2.) Otherwise, SSTORE_RESET_GAS gas is deducted. If new value is 0, add SSTORE_CLEARS_SCHEDULE to refund counter. -// (2.2.) If original value does not equal current value (this storage slot is dirty), SLOAD_GAS gas is deducted. Apply both of the following clauses: -// (2.2.1.) If original value is not 0: -// (2.2.1.1.) If current value is 0 (also means that new value is not 0), subtract SSTORE_CLEARS_SCHEDULE gas from refund counter. -// (2.2.1.2.) If new value is 0 (also means that current value is not 0), add SSTORE_CLEARS_SCHEDULE gas to refund counter. -// (2.2.2.) If original value equals new value (this storage slot is reset): -// (2.2.2.1.) If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter. -// (2.2.2.2.) Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter. -func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - // If we fail the minimum gas availability invariant, fail (0) - if contract.Gas <= params.SstoreSentryGasEIP2200 { - return 0, errors.New("not enough gas for reentrancy sentry") - } - // Gas sentry honoured, do the actual gas calculation based on the stored value - var ( - y, x = stack.Back(1), stack.Back(0) - current = evm.StateDB.GetState(contract.Address(), x.Bytes32()) - ) - value := common.Hash(y.Bytes32()) - - if current == value { // noop (1) - return params.SloadGasEIP2200, nil - } - original := evm.StateDB.GetCommittedState(contract.Address(), x.Bytes32()) - if original == current { - if original == (common.Hash{}) { // create slot (2.1.1) - return params.SstoreSetGasEIP2200, nil - } - if value == (common.Hash{}) { // delete slot (2.1.2b) - evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200) - } - return params.SstoreResetGasEIP2200, nil // write existing slot (2.1.2) - } - if original != (common.Hash{}) { - if current == (common.Hash{}) { // recreate slot (2.2.1.1) - evm.StateDB.SubRefund(params.SstoreClearsScheduleRefundEIP2200) - } else if value == (common.Hash{}) { // delete slot (2.2.1.2) - evm.StateDB.AddRefund(params.SstoreClearsScheduleRefundEIP2200) - } - } - if original == value { - if original == (common.Hash{}) { // reset to original inexistent slot (2.2.2.1) - evm.StateDB.AddRefund(params.SstoreSetGasEIP2200 - params.SloadGasEIP2200) - } else { // reset to original existing slot (2.2.2.2) - evm.StateDB.AddRefund(params.SstoreResetGasEIP2200 - params.SloadGasEIP2200) - } - } - return params.SloadGasEIP2200, nil // dirty update (2.2) -} - -// gasSStoreAP1 simplifies the dynamic gas cost of SSTORE by removing all refund logic -// -// 0. If *gasleft* is less than or equal to 2300, fail the current call. -// 1. If current value equals new value (this is a no-op), SLOAD_GAS is deducted. -// 2. If current value does not equal new value: -// 2.1. If original value equals current value (this storage slot has not been changed by the current execution context): -// 2.1.1. If original value is 0, SSTORE_SET_GAS (20K) gas is deducted. -// 2.1.2. Otherwise, SSTORE_RESET_GAS gas is deducted. If new value is 0, add SSTORE_CLEARS_SCHEDULE to refund counter. -// 2.2. If original value does not equal current value (this storage slot is dirty), SLOAD_GAS gas is deducted. Apply both of the following clauses: -func gasSStoreAP1(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - // If we fail the minimum gas availability invariant, fail (0) - if contract.Gas <= params.SstoreSentryGasEIP2200 { - return 0, errors.New("not enough gas for reentrancy sentry") - } - // Gas sentry honoured, do the actual gas calculation based on the stored value - var ( - y, x = stack.Back(1), stack.Back(0) - current = evm.StateDB.GetState(contract.Address(), x.Bytes32()) - ) - value := common.Hash(y.Bytes32()) - - if current == value { // noop (1) - return params.SloadGasEIP2200, nil - } - original := evm.StateDB.GetCommittedStateAP1(contract.Address(), x.Bytes32()) - if original == current { - if original == (common.Hash{}) { // create slot (2.1.1) - return params.SstoreSetGasEIP2200, nil - } - return params.SstoreResetGasEIP2200, nil // write existing slot (2.1.2) - } - - return params.SloadGasEIP2200, nil // dirty update (2.2) -} - -func makeGasLog(n uint64) gasFunc { - return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - requestedSize, overflow := stack.Back(1).Uint64WithOverflow() - if overflow { - return 0, vmerrs.ErrGasUintOverflow - } - - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - - if gas, overflow = math.SafeAdd(gas, params.LogGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, n*params.LogTopicGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - - var memorySizeGas uint64 - if memorySizeGas, overflow = math.SafeMul(requestedSize, params.LogDataGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, memorySizeGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil - } -} - -func gasKeccak256(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - wordGas, overflow := stack.Back(1).Uint64WithOverflow() - if overflow { - return 0, vmerrs.ErrGasUintOverflow - } - if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Keccak256WordGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, wordGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -// pureMemoryGascost is used by several operations, which aside from their -// static cost have a dynamic cost which is solely based on the memory -// expansion -func pureMemoryGascost(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - return memoryGasCost(mem, memorySize) -} - -var ( - gasReturn = pureMemoryGascost - gasRevert = pureMemoryGascost - gasMLoad = pureMemoryGascost - gasMStore8 = pureMemoryGascost - gasMStore = pureMemoryGascost - gasCreate = pureMemoryGascost -) - -func gasCreate2(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - wordGas, overflow := stack.Back(2).Uint64WithOverflow() - if overflow { - return 0, vmerrs.ErrGasUintOverflow - } - if wordGas, overflow = math.SafeMul(toWordSize(wordGas), params.Keccak256WordGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - if gas, overflow = math.SafeAdd(gas, wordGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasCreateEip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - size, overflow := stack.Back(2).Uint64WithOverflow() - if overflow || size > params.MaxInitCodeSize { - return 0, vmerrs.ErrGasUintOverflow - } - // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow - moreGas := params.InitCodeWordGas * ((size + 31) / 32) - if gas, overflow = math.SafeAdd(gas, moreGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} -func gasCreate2Eip3860(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - size, overflow := stack.Back(2).Uint64WithOverflow() - if overflow || size > params.MaxInitCodeSize { - return 0, vmerrs.ErrGasUintOverflow - } - // Since size <= params.MaxInitCodeSize, these multiplication cannot overflow - moreGas := (params.InitCodeWordGas + params.Keccak256WordGas) * ((size + 31) / 32) - if gas, overflow = math.SafeAdd(gas, moreGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasExpFrontier(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8) - - var ( - gas = expByteLen * params.ExpByteFrontier // no overflow check required. Max is 256 * ExpByte gas - overflow bool - ) - if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasExpEIP158(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - expByteLen := uint64((stack.data[stack.len()-2].BitLen() + 7) / 8) - - var ( - gas = expByteLen * params.ExpByteEIP158 // no overflow check required. Max is 256 * ExpByte gas - overflow bool - ) - if gas, overflow = math.SafeAdd(gas, params.ExpGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var ( - gas uint64 - transfersValue = !stack.Back(2).IsZero() - address = common.Address(stack.Back(1).Bytes20()) - ) - if evm.chainRules.IsEIP158 { - if transfersValue && evm.StateDB.Empty(address) { - gas += params.CallNewAccountGas - } - } else if !evm.StateDB.Exist(address) { - gas += params.CallNewAccountGas - } - if transfersValue { - gas += params.CallValueTransferGas - } - memoryGas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - - evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasCallCode(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - memoryGas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - var ( - gas uint64 - overflow bool - ) - if stack.Back(2).Sign() != 0 { - gas += params.CallValueTransferGas - } - if gas, overflow = math.SafeAdd(gas, memoryGas); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasDelegateCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - gas, err := memoryGasCost(mem, memorySize) - if err != nil { - return 0, err - } - evm.callGasTemp, err = callGas(evm.chainRules.IsEIP150, contract.Gas, gas, stack.Back(0)) - if err != nil { - return 0, err - } - var overflow bool - if gas, overflow = math.SafeAdd(gas, evm.callGasTemp); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil -} - -func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var gas uint64 - // EIP150 homestead gas reprice fork: - if evm.chainRules.IsEIP150 { - gas = params.SelfdestructGasEIP150 - var address = common.Address(stack.Back(0).Bytes20()) - - if evm.chainRules.IsEIP158 { - // if empty and transfers value - if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { - gas += params.CreateBySelfdestructGas - } - } else if !evm.StateDB.Exist(address) { - gas += params.CreateBySelfdestructGas - } - } - - if !evm.StateDB.HasSelfDestructed(contract.Address()) { - evm.StateDB.AddRefund(params.SelfdestructRefundGas) - } - return gas, nil -} - -func gasSelfdestructAP1(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var gas uint64 - // EIP150 homestead gas reprice fork: - if evm.chainRules.IsEIP150 { - gas = params.SelfdestructGasEIP150 - var address = common.Address(stack.Back(0).Bytes20()) - - if evm.chainRules.IsEIP158 { - // if empty and transfers value - if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { - gas += params.CreateBySelfdestructGas - } - } else if !evm.StateDB.Exist(address) { - gas += params.CreateBySelfdestructGas - } - } - - return gas, nil -} diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go deleted file mode 100644 index c6da37c789..0000000000 --- a/core/vm/gas_table_test.go +++ /dev/null @@ -1,194 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "bytes" - "math" - "math/big" - "sort" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/holiman/uint256" -) - -func TestMemoryGasCost(t *testing.T) { - tests := []struct { - size uint64 - cost uint64 - overflow bool - }{ - {0x1fffffffe0, 36028809887088637, false}, - {0x1fffffffe1, 0, true}, - } - for i, tt := range tests { - v, err := memoryGasCost(&Memory{}, tt.size) - if (err == vmerrs.ErrGasUintOverflow) != tt.overflow { - t.Errorf("test %d: overflow mismatch: have %v, want %v", i, err == vmerrs.ErrGasUintOverflow, tt.overflow) - } - if v != tt.cost { - t.Errorf("test %d: gas cost mismatch: have %v, want %v", i, v, tt.cost) - } - } -} - -var eip2200Tests = []struct { - original byte - gaspool uint64 - input string - used uint64 - refund uint64 - failure error -}{ - {0, math.MaxUint64, "0x60006000556000600055", 1612, 0, nil}, // 0 -> 0 -> 0 - {0, math.MaxUint64, "0x60006000556001600055", 20812, 0, nil}, // 0 -> 0 -> 1 - {0, math.MaxUint64, "0x60016000556000600055", 20812, 19200, nil}, // 0 -> 1 -> 0 - {0, math.MaxUint64, "0x60016000556002600055", 20812, 0, nil}, // 0 -> 1 -> 2 - {0, math.MaxUint64, "0x60016000556001600055", 20812, 0, nil}, // 0 -> 1 -> 1 - {1, math.MaxUint64, "0x60006000556000600055", 5812, 15000, nil}, // 1 -> 0 -> 0 - {1, math.MaxUint64, "0x60006000556001600055", 5812, 4200, nil}, // 1 -> 0 -> 1 - {1, math.MaxUint64, "0x60006000556002600055", 5812, 0, nil}, // 1 -> 0 -> 2 - {1, math.MaxUint64, "0x60026000556000600055", 5812, 15000, nil}, // 1 -> 2 -> 0 - {1, math.MaxUint64, "0x60026000556003600055", 5812, 0, nil}, // 1 -> 2 -> 3 - {1, math.MaxUint64, "0x60026000556001600055", 5812, 4200, nil}, // 1 -> 2 -> 1 - {1, math.MaxUint64, "0x60026000556002600055", 5812, 0, nil}, // 1 -> 2 -> 2 - {1, math.MaxUint64, "0x60016000556000600055", 5812, 15000, nil}, // 1 -> 1 -> 0 - {1, math.MaxUint64, "0x60016000556002600055", 5812, 0, nil}, // 1 -> 1 -> 2 - {1, math.MaxUint64, "0x60016000556001600055", 1612, 0, nil}, // 1 -> 1 -> 1 - {0, math.MaxUint64, "0x600160005560006000556001600055", 40818, 19200, nil}, // 0 -> 1 -> 0 -> 1 - {1, math.MaxUint64, "0x600060005560016000556000600055", 10818, 19200, nil}, // 1 -> 0 -> 1 -> 0 - {1, 2306, "0x6001600055", 2306, 0, vmerrs.ErrOutOfGas}, // 1 -> 1 (2300 sentry + 2xPUSH) - {1, 2307, "0x6001600055", 806, 0, nil}, // 1 -> 1 (2301 sentry + 2xPUSH) -} - -func TestEIP2200(t *testing.T) { - for i, tt := range eip2200Tests { - address := common.BytesToAddress([]byte("contract")) - - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - statedb.CreateAccount(address) - statedb.SetCode(address, hexutil.MustDecode(tt.input)) - statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original})) - statedb.Finalise(true) // Push the state into the "original" slot - - vmctx := BlockContext{ - CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true }, - Transfer: func(StateDB, common.Address, common.Address, *uint256.Int) {}, - } - vmenv := NewEVM(vmctx, TxContext{}, statedb, params.TestChainConfig, Config{ExtraEips: []int{2200}}) - - _, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, tt.gaspool, new(uint256.Int)) - if err != tt.failure { - t.Errorf("test %d: failure mismatch: have %v, want %v", i, err, tt.failure) - } - if used := tt.gaspool - gas; used != tt.used { - t.Errorf("test %d: gas used mismatch: have %v, want %v", i, used, tt.used) - } - if refund := vmenv.StateDB.GetRefund(); refund != tt.refund { - t.Errorf("test %d: gas refund mismatch: have %v, want %v", i, refund, tt.refund) - } - } -} - -var createGasTests = []struct { - code string - eip3860 bool - gasUsed uint64 - minimumGas uint64 -}{ - // legacy create(0, 0, 0xc000) without 3860 used - {"0x61C00060006000f0" + "600052" + "60206000F3", false, 41237, 41237}, - // legacy create(0, 0, 0xc000) _with_ 3860 - {"0x61C00060006000f0" + "600052" + "60206000F3", true, 44309, 44309}, - // create2(0, 0, 0xc001, 0) without 3860 - {"0x600061C00160006000f5" + "600052" + "60206000F3", false, 50471, 50471}, - // create2(0, 0, 0xc001, 0) (too large), with 3860 - {"0x600061C00160006000f5" + "600052" + "60206000F3", true, 32012, 100_000}, - // create2(0, 0, 0xc000, 0) - // This case is trying to deploy code at (within) the limit - {"0x600061C00060006000f5" + "600052" + "60206000F3", true, 53528, 53528}, - // create2(0, 0, 0xc001, 0) - // This case is trying to deploy code exceeding the limit - {"0x600061C00160006000f5" + "600052" + "60206000F3", true, 32024, 100000}, -} - -func TestCreateGas(t *testing.T) { - for i, tt := range createGasTests { - var gasUsed = uint64(0) - doCheck := func(testGas int) bool { - address := common.BytesToAddress([]byte("contract")) - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - statedb.CreateAccount(address) - statedb.SetCode(address, hexutil.MustDecode(tt.code)) - statedb.Finalise(true) - vmctx := BlockContext{ - CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true }, - Transfer: func(StateDB, common.Address, common.Address, *uint256.Int) {}, - BlockNumber: big.NewInt(0), - } - config := Config{} - if tt.eip3860 { - config.ExtraEips = []int{3860} - } - - // Note: we use Cortina instead of AllEthashProtocolChanges (upstream) - // because it is the last fork before the activation of EIP-3860 - vmenv := NewEVM(vmctx, TxContext{}, statedb, params.TestCortinaChainConfig, config) - var startGas = uint64(testGas) - ret, gas, err := vmenv.Call(AccountRef(common.Address{}), address, nil, startGas, new(uint256.Int)) - if err != nil { - return false - } - gasUsed = startGas - gas - if len(ret) != 32 { - t.Fatalf("test %d: expected 32 bytes returned, have %d", i, len(ret)) - } - if bytes.Equal(ret, make([]byte, 32)) { - // Failure - return false - } - return true - } - minGas := sort.Search(100_000, doCheck) - if uint64(minGas) != tt.minimumGas { - t.Fatalf("test %d: min gas error, want %d, have %d", i, tt.minimumGas, minGas) - } - // If the deployment succeeded, we also check the gas used - if minGas < 100_000 { - if gasUsed != tt.gasUsed { - t.Errorf("test %d: gas used mismatch: have %v, want %v", i, gasUsed, tt.gasUsed) - } - } - } -} diff --git a/core/vm/instructions.go b/core/vm/instructions.go deleted file mode 100644 index 72047c260d..0000000000 --- a/core/vm/instructions.go +++ /dev/null @@ -1,919 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "math" - - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/holiman/uint256" -) - -func opAdd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.Add(&x, y) - return nil, nil -} - -func opSub(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.Sub(&x, y) - return nil, nil -} - -func opMul(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.Mul(&x, y) - return nil, nil -} - -func opDiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.Div(&x, y) - return nil, nil -} - -func opSdiv(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.SDiv(&x, y) - return nil, nil -} - -func opMod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.Mod(&x, y) - return nil, nil -} - -func opSmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.SMod(&x, y) - return nil, nil -} - -func opExp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - base, exponent := scope.Stack.pop(), scope.Stack.peek() - exponent.Exp(&base, exponent) - return nil, nil -} - -func opSignExtend(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - back, num := scope.Stack.pop(), scope.Stack.peek() - num.ExtendSign(num, &back) - return nil, nil -} - -func opNot(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x := scope.Stack.peek() - x.Not(x) - return nil, nil -} - -func opLt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - if x.Lt(y) { - y.SetOne() - } else { - y.Clear() - } - return nil, nil -} - -func opGt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - if x.Gt(y) { - y.SetOne() - } else { - y.Clear() - } - return nil, nil -} - -func opSlt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - if x.Slt(y) { - y.SetOne() - } else { - y.Clear() - } - return nil, nil -} - -func opSgt(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - if x.Sgt(y) { - y.SetOne() - } else { - y.Clear() - } - return nil, nil -} - -func opEq(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - if x.Eq(y) { - y.SetOne() - } else { - y.Clear() - } - return nil, nil -} - -func opIszero(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x := scope.Stack.peek() - if x.IsZero() { - x.SetOne() - } else { - x.Clear() - } - return nil, nil -} - -func opAnd(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.And(&x, y) - return nil, nil -} - -func opOr(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.Or(&x, y) - return nil, nil -} - -func opXor(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y := scope.Stack.pop(), scope.Stack.peek() - y.Xor(&x, y) - return nil, nil -} - -func opByte(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - th, val := scope.Stack.pop(), scope.Stack.peek() - val.Byte(&th) - return nil, nil -} - -func opAddmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek() - if z.IsZero() { - z.Clear() - } else { - z.AddMod(&x, &y, z) - } - return nil, nil -} - -func opMulmod(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x, y, z := scope.Stack.pop(), scope.Stack.pop(), scope.Stack.peek() - z.MulMod(&x, &y, z) - return nil, nil -} - -// opSHL implements Shift Left -// The SHL instruction (shift left) pops 2 values from the stack, first arg1 and then arg2, -// and pushes on the stack arg2 shifted to the left by arg1 number of bits. -func opSHL(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards - shift, value := scope.Stack.pop(), scope.Stack.peek() - if shift.LtUint64(256) { - value.Lsh(value, uint(shift.Uint64())) - } else { - value.Clear() - } - return nil, nil -} - -// opSHR implements Logical Shift Right -// The SHR instruction (logical shift right) pops 2 values from the stack, first arg1 and then arg2, -// and pushes on the stack arg2 shifted to the right by arg1 number of bits with zero fill. -func opSHR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - // Note, second operand is left in the stack; accumulate result into it, and no need to push it afterwards - shift, value := scope.Stack.pop(), scope.Stack.peek() - if shift.LtUint64(256) { - value.Rsh(value, uint(shift.Uint64())) - } else { - value.Clear() - } - return nil, nil -} - -// opSAR implements Arithmetic Shift Right -// The SAR instruction (arithmetic shift right) pops 2 values from the stack, first arg1 and then arg2, -// and pushes on the stack arg2 shifted to the right by arg1 number of bits with sign extension. -func opSAR(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - shift, value := scope.Stack.pop(), scope.Stack.peek() - if shift.GtUint64(256) { - if value.Sign() >= 0 { - value.Clear() - } else { - // Max negative shift: all bits set - value.SetAllOne() - } - return nil, nil - } - n := uint(shift.Uint64()) - value.SRsh(value, n) - return nil, nil -} - -func opKeccak256(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - offset, size := scope.Stack.pop(), scope.Stack.peek() - data := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) - - if interpreter.hasher == nil { - interpreter.hasher = crypto.NewKeccakState() - } else { - interpreter.hasher.Reset() - } - interpreter.hasher.Write(data) - interpreter.hasher.Read(interpreter.hasherBuf[:]) - - evm := interpreter.evm - if evm.Config.EnablePreimageRecording { - evm.StateDB.AddPreimage(interpreter.hasherBuf, data) - } - - size.SetBytes(interpreter.hasherBuf[:]) - return nil, nil -} - -func opAddress(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Address().Bytes())) - return nil, nil -} - -func opBalance(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - slot := scope.Stack.peek() - address := common.Address(slot.Bytes20()) - slot.Set(interpreter.evm.StateDB.GetBalance(address)) - return nil, nil -} - -func opOrigin(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Origin.Bytes())) - return nil, nil -} - -func opCaller(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetBytes(scope.Contract.Caller().Bytes())) - return nil, nil -} - -func opCallValue(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(scope.Contract.value) - return nil, nil -} - -func opCallDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - x := scope.Stack.peek() - if offset, overflow := x.Uint64WithOverflow(); !overflow { - data := getData(scope.Contract.Input, offset, 32) - x.SetBytes(data) - } else { - x.Clear() - } - return nil, nil -} - -func opCallDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Input)))) - return nil, nil -} - -func opCallDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - var ( - memOffset = scope.Stack.pop() - dataOffset = scope.Stack.pop() - length = scope.Stack.pop() - ) - dataOffset64, overflow := dataOffset.Uint64WithOverflow() - if overflow { - dataOffset64 = 0xffffffffffffffff - } - // These values are checked for overflow during gas cost calculation - memOffset64 := memOffset.Uint64() - length64 := length.Uint64() - scope.Memory.Set(memOffset64, length64, getData(scope.Contract.Input, dataOffset64, length64)) - - return nil, nil -} - -func opReturnDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(interpreter.returnData)))) - return nil, nil -} - -func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - var ( - memOffset = scope.Stack.pop() - dataOffset = scope.Stack.pop() - length = scope.Stack.pop() - ) - - offset64, overflow := dataOffset.Uint64WithOverflow() - if overflow { - return nil, vmerrs.ErrReturnDataOutOfBounds - } - // we can reuse dataOffset now (aliasing it for clarity) - var end = dataOffset - end.Add(&dataOffset, &length) - end64, overflow := end.Uint64WithOverflow() - if overflow || uint64(len(interpreter.returnData)) < end64 { - return nil, vmerrs.ErrReturnDataOutOfBounds - } - scope.Memory.Set(memOffset.Uint64(), length.Uint64(), interpreter.returnData[offset64:end64]) - return nil, nil -} - -func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - slot := scope.Stack.peek() - slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20()))) - return nil, nil -} - -func opCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(uint64(len(scope.Contract.Code)))) - return nil, nil -} - -func opCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - var ( - memOffset = scope.Stack.pop() - codeOffset = scope.Stack.pop() - length = scope.Stack.pop() - ) - uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() - if overflow { - uint64CodeOffset = math.MaxUint64 - } - codeCopy := getData(scope.Contract.Code, uint64CodeOffset, length.Uint64()) - scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - - return nil, nil -} - -func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - var ( - stack = scope.Stack - a = stack.pop() - memOffset = stack.pop() - codeOffset = stack.pop() - length = stack.pop() - ) - uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() - if overflow { - uint64CodeOffset = math.MaxUint64 - } - addr := common.Address(a.Bytes20()) - codeCopy := getData(interpreter.evm.StateDB.GetCode(addr), uint64CodeOffset, length.Uint64()) - scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) - - return nil, nil -} - -// opExtCodeHash returns the code hash of a specified account. -// There are several cases when the function is called, while we can relay everything -// to `state.GetCodeHash` function to ensure the correctness. -// -// 1. Caller tries to get the code hash of a normal contract account, state -// should return the relative code hash and set it as the result. -// -// 2. Caller tries to get the code hash of a non-existent account, state should -// return common.Hash{} and zero will be set as the result. -// -// 3. Caller tries to get the code hash for an account without contract code, state -// should return emptyCodeHash(0xc5d246...) as the result. -// -// 4. Caller tries to get the code hash of a precompiled account, the result should be -// zero or emptyCodeHash. -// -// It is worth noting that in order to avoid unnecessary create and clean, all precompile -// accounts on mainnet have been transferred 1 wei, so the return here should be -// emptyCodeHash. If the precompile account is not transferred any amount on a private or -// customized chain, the return value will be zero. -// -// 5. Caller tries to get the code hash for an account which is marked as self-destructed -// in the current transaction, the code hash of this account should be returned. -// -// 6. Caller tries to get the code hash for an account which is marked as deleted, this -// account should be regarded as a non-existent account and zero should be returned. -func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - slot := scope.Stack.peek() - address := common.Address(slot.Bytes20()) - if interpreter.evm.StateDB.Empty(address) { - slot.Clear() - } else { - slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) - } - return nil, nil -} - -func opGasprice(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - v, _ := uint256.FromBig(interpreter.evm.GasPrice) - scope.Stack.push(v) - return nil, nil -} - -func opBlockhash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - num := scope.Stack.peek() - num64, overflow := num.Uint64WithOverflow() - if overflow { - num.Clear() - return nil, nil - } - var upper, lower uint64 - upper = interpreter.evm.Context.BlockNumber.Uint64() - if upper < 257 { - lower = 0 - } else { - lower = upper - 256 - } - if num64 >= lower && num64 < upper { - num.SetBytes(interpreter.evm.Context.GetHash(num64).Bytes()) - } else { - num.Clear() - } - return nil, nil -} - -func opCoinbase(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetBytes(interpreter.evm.Context.Coinbase.Bytes())) - return nil, nil -} - -func opTimestamp(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.Time)) - return nil, nil -} - -func opNumber(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - v, _ := uint256.FromBig(interpreter.evm.Context.BlockNumber) - scope.Stack.push(v) - return nil, nil -} - -func opDifficulty(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - v, _ := uint256.FromBig(interpreter.evm.Context.Difficulty) - scope.Stack.push(v) - return nil, nil -} - -func opGasLimit(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(interpreter.evm.Context.GasLimit)) - return nil, nil -} - -func opPop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.pop() - return nil, nil -} - -func opMload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - v := scope.Stack.peek() - offset := int64(v.Uint64()) - v.SetBytes(scope.Memory.GetPtr(offset, 32)) - return nil, nil -} - -func opMstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - // pop value of the stack - mStart, val := scope.Stack.pop(), scope.Stack.pop() - scope.Memory.Set32(mStart.Uint64(), &val) - return nil, nil -} - -func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - off, val := scope.Stack.pop(), scope.Stack.pop() - scope.Memory.store[off.Uint64()] = byte(val.Uint64()) - return nil, nil -} - -func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - loc := scope.Stack.peek() - hash := common.Hash(loc.Bytes32()) - val := interpreter.evm.StateDB.GetState(scope.Contract.Address(), hash) - loc.SetBytes(val.Bytes()) - return nil, nil -} - -func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.readOnly { - return nil, vmerrs.ErrWriteProtection - } - loc := scope.Stack.pop() - val := scope.Stack.pop() - interpreter.evm.StateDB.SetState(scope.Contract.Address(), loc.Bytes32(), val.Bytes32()) - return nil, nil -} - -func opJump(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.evm.abort.Load() { - return nil, errStopToken - } - pos := scope.Stack.pop() - if !scope.Contract.validJumpdest(&pos) { - return nil, vmerrs.ErrInvalidJump - } - *pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop - return nil, nil -} - -func opJumpi(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.evm.abort.Load() { - return nil, errStopToken - } - pos, cond := scope.Stack.pop(), scope.Stack.pop() - if !cond.IsZero() { - if !scope.Contract.validJumpdest(&pos) { - return nil, vmerrs.ErrInvalidJump - } - *pc = pos.Uint64() - 1 // pc will be increased by the interpreter loop - } - return nil, nil -} - -func opJumpdest(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - return nil, nil -} - -func opPc(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(*pc)) - return nil, nil -} - -func opMsize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(uint64(scope.Memory.Len()))) - return nil, nil -} - -func opGas(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.push(new(uint256.Int).SetUint64(scope.Contract.Gas)) - return nil, nil -} - -func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.readOnly { - return nil, vmerrs.ErrWriteProtection - } - var ( - value = scope.Stack.pop() - offset, size = scope.Stack.pop(), scope.Stack.pop() - input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) - gas = scope.Contract.Gas - ) - if interpreter.evm.chainRules.IsEIP150 { - gas -= gas / 64 - } - // reuse size int for stackvalue - stackvalue := size - - scope.Contract.UseGas(gas) - - res, addr, returnGas, suberr := interpreter.evm.Create(scope.Contract, input, gas, &value) - // Push item on the stack based on the returned error. If the ruleset is - // homestead we must check for CodeStoreOutOfGasError (homestead only - // rule) and treat as an error, if the ruleset is frontier we must - // ignore this error and pretend the operation was successful. - if interpreter.evm.chainRules.IsHomestead && suberr == vmerrs.ErrCodeStoreOutOfGas { - stackvalue.Clear() - } else if suberr != nil && suberr != vmerrs.ErrCodeStoreOutOfGas { - stackvalue.Clear() - } else { - stackvalue.SetBytes(addr.Bytes()) - } - scope.Stack.push(&stackvalue) - scope.Contract.Gas += returnGas - - if suberr == vmerrs.ErrExecutionReverted { - interpreter.returnData = res // set REVERT data to return data buffer - return res, nil - } - interpreter.returnData = nil // clear dirty return data buffer - return nil, nil -} - -func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.readOnly { - return nil, vmerrs.ErrWriteProtection - } - var ( - endowment = scope.Stack.pop() - offset, size = scope.Stack.pop(), scope.Stack.pop() - salt = scope.Stack.pop() - input = scope.Memory.GetCopy(int64(offset.Uint64()), int64(size.Uint64())) - gas = scope.Contract.Gas - ) - // Apply EIP150 - gas -= gas / 64 - scope.Contract.UseGas(gas) - // reuse size int for stackvalue - stackvalue := size - res, addr, returnGas, suberr := interpreter.evm.Create2(scope.Contract, input, gas, - &endowment, &salt) - // Push item on the stack based on the returned error. - if suberr != nil { - stackvalue.Clear() - } else { - stackvalue.SetBytes(addr.Bytes()) - } - scope.Stack.push(&stackvalue) - scope.Contract.Gas += returnGas - - if suberr == vmerrs.ErrExecutionReverted { - interpreter.returnData = res // set REVERT data to return data buffer - return res, nil - } - interpreter.returnData = nil // clear dirty return data buffer - return nil, nil -} - -func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - stack := scope.Stack - // Pop gas. The actual gas in interpreter.evm.callGasTemp. - // We can use this as a temporary value - temp := stack.pop() - gas := interpreter.evm.callGasTemp - // Pop other call parameters. - addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() - toAddr := common.Address(addr.Bytes20()) - // Get the arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) - - if interpreter.readOnly && !value.IsZero() { - return nil, vmerrs.ErrWriteProtection - } - if !value.IsZero() { - gas += params.CallStipend - } - ret, returnGas, err := interpreter.evm.Call(scope.Contract, toAddr, args, gas, &value) - - if err != nil { - temp.Clear() - } else { - temp.SetOne() - } - stack.push(&temp) - if err == nil || err == vmerrs.ErrExecutionReverted { - scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) - } - scope.Contract.Gas += returnGas - - interpreter.returnData = ret - return ret, nil -} - -func opCallCode(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - // Pop gas. The actual gas is in interpreter.evm.callGasTemp. - stack := scope.Stack - // We use it as a temporary value - temp := stack.pop() - gas := interpreter.evm.callGasTemp - // Pop other call parameters. - addr, value, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() - toAddr := common.Address(addr.Bytes20()) - // Get arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) - - if !value.IsZero() { - gas += params.CallStipend - } - - ret, returnGas, err := interpreter.evm.CallCode(scope.Contract, toAddr, args, gas, &value) - if err != nil { - temp.Clear() - } else { - temp.SetOne() - } - stack.push(&temp) - if err == nil || err == vmerrs.ErrExecutionReverted { - scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) - } - scope.Contract.Gas += returnGas - - interpreter.returnData = ret - return ret, nil -} - -func opDelegateCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - stack := scope.Stack - // Pop gas. The actual gas is in interpreter.evm.callGasTemp. - // We use it as a temporary value - temp := stack.pop() - gas := interpreter.evm.callGasTemp - // Pop other call parameters. - addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() - toAddr := common.Address(addr.Bytes20()) - // Get arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) - - ret, returnGas, err := interpreter.evm.DelegateCall(scope.Contract, toAddr, args, gas) - if err != nil { - temp.Clear() - } else { - temp.SetOne() - } - stack.push(&temp) - if err == nil || err == vmerrs.ErrExecutionReverted { - scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) - } - scope.Contract.Gas += returnGas - - interpreter.returnData = ret - return ret, nil -} - -func opStaticCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - // Pop gas. The actual gas is in interpreter.evm.callGasTemp. - stack := scope.Stack - // We use it as a temporary value - temp := stack.pop() - gas := interpreter.evm.callGasTemp - // Pop other call parameters. - addr, inOffset, inSize, retOffset, retSize := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop() - toAddr := common.Address(addr.Bytes20()) - // Get arguments from the memory. - args := scope.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64())) - - ret, returnGas, err := interpreter.evm.StaticCall(scope.Contract, toAddr, args, gas) - if err != nil { - temp.Clear() - } else { - temp.SetOne() - } - stack.push(&temp) - if err == nil || err == vmerrs.ErrExecutionReverted { - scope.Memory.Set(retOffset.Uint64(), retSize.Uint64(), ret) - } - scope.Contract.Gas += returnGas - - interpreter.returnData = ret - return ret, nil -} - -func opReturn(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - offset, size := scope.Stack.pop(), scope.Stack.pop() - ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) - - return ret, errStopToken -} - -func opRevert(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - offset, size := scope.Stack.pop(), scope.Stack.pop() - ret := scope.Memory.GetPtr(int64(offset.Uint64()), int64(size.Uint64())) - - interpreter.returnData = ret - return ret, vmerrs.ErrExecutionReverted -} - -func opUndefined(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - return nil, &ErrInvalidOpCode{opcode: OpCode(scope.Contract.Code[*pc])} -} - -func opStop(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - return nil, errStopToken -} - -func opSelfdestruct(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.readOnly { - return nil, vmerrs.ErrWriteProtection - } - beneficiary := scope.Stack.pop() - balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) - interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) - interpreter.evm.StateDB.SelfDestruct(scope.Contract.Address()) - if tracer := interpreter.evm.Config.Tracer; tracer != nil { - tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) - tracer.CaptureExit([]byte{}, 0, nil) - } - return nil, errStopToken -} - -func opSelfdestruct6780(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.readOnly { - return nil, vmerrs.ErrWriteProtection - } - beneficiary := scope.Stack.pop() - balance := interpreter.evm.StateDB.GetBalance(scope.Contract.Address()) - interpreter.evm.StateDB.SubBalance(scope.Contract.Address(), balance) - interpreter.evm.StateDB.AddBalance(beneficiary.Bytes20(), balance) - interpreter.evm.StateDB.Selfdestruct6780(scope.Contract.Address()) - if tracer := interpreter.evm.Config.Tracer; tracer != nil { - tracer.CaptureEnter(SELFDESTRUCT, scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) - tracer.CaptureExit([]byte{}, 0, nil) - } - return nil, errStopToken -} - -// following functions are used by the instruction jump table - -// make log instruction function -func makeLog(size int) executionFunc { - return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - if interpreter.readOnly { - return nil, vmerrs.ErrWriteProtection - } - topics := make([]common.Hash, size) - stack := scope.Stack - mStart, mSize := stack.pop(), stack.pop() - for i := 0; i < size; i++ { - addr := stack.pop() - topics[i] = addr.Bytes32() - } - - d := scope.Memory.GetCopy(int64(mStart.Uint64()), int64(mSize.Uint64())) - interpreter.evm.StateDB.AddLog( - scope.Contract.Address(), - topics, - d, - // This is a non-consensus field, but assigned here because - // core/state doesn't know the current block number. - interpreter.evm.Context.BlockNumber.Uint64(), - ) - - return nil, nil - } -} - -// opPush1 is a specialized version of pushN -func opPush1(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - var ( - codeLen = uint64(len(scope.Contract.Code)) - integer = new(uint256.Int) - ) - *pc += 1 - if *pc < codeLen { - scope.Stack.push(integer.SetUint64(uint64(scope.Contract.Code[*pc]))) - } else { - scope.Stack.push(integer.Clear()) - } - return nil, nil -} - -// make push instruction function -func makePush(size uint64, pushByteSize int) executionFunc { - return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - codeLen := len(scope.Contract.Code) - - startMin := codeLen - if int(*pc+1) < startMin { - startMin = int(*pc + 1) - } - - endMin := codeLen - if startMin+pushByteSize < endMin { - endMin = startMin + pushByteSize - } - - integer := new(uint256.Int) - scope.Stack.push(integer.SetBytes(common.RightPadBytes( - scope.Contract.Code[startMin:endMin], pushByteSize))) - - *pc += size - return nil, nil - } -} - -// make dup instruction function -func makeDup(size int64) executionFunc { - return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.dup(int(size)) - return nil, nil - } -} - -// make swap instruction function -func makeSwap(size int64) executionFunc { - // switch n + 1 otherwise n would be swapped with n - size++ - return func(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { - scope.Stack.swap(int(size)) - return nil, nil - } -} diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go deleted file mode 100644 index cf28289974..0000000000 --- a/core/vm/instructions_test.go +++ /dev/null @@ -1,945 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "bytes" - "encoding/json" - "fmt" - "math/big" - "os" - "strings" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/holiman/uint256" -) - -type TwoOperandTestcase struct { - X string - Y string - Expected string -} - -type twoOperandParams struct { - x string - y string -} - -var alphabetSoup = "ABCDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff" -var commonParams []*twoOperandParams -var twoOpMethods map[string]executionFunc - -type contractRef struct { - addr common.Address -} - -func (c contractRef) Address() common.Address { - return c.addr -} - -func init() { - // Params is a list of common edgecases that should be used for some common tests - params := []string{ - "0000000000000000000000000000000000000000000000000000000000000000", // 0 - "0000000000000000000000000000000000000000000000000000000000000001", // +1 - "0000000000000000000000000000000000000000000000000000000000000005", // +5 - "7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", // + max -1 - "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // + max - "8000000000000000000000000000000000000000000000000000000000000000", // - max - "8000000000000000000000000000000000000000000000000000000000000001", // - max+1 - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb", // - 5 - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", // - 1 - } - // Params are combined so each param is used on each 'side' - commonParams = make([]*twoOperandParams, len(params)*len(params)) - for i, x := range params { - for j, y := range params { - commonParams[i*len(params)+j] = &twoOperandParams{x, y} - } - } - twoOpMethods = map[string]executionFunc{ - "add": opAdd, - "sub": opSub, - "mul": opMul, - "div": opDiv, - "sdiv": opSdiv, - "mod": opMod, - "smod": opSmod, - "exp": opExp, - "signext": opSignExtend, - "lt": opLt, - "gt": opGt, - "slt": opSlt, - "sgt": opSgt, - "eq": opEq, - "and": opAnd, - "or": opOr, - "xor": opXor, - "byte": opByte, - "shl": opSHL, - "shr": opSHR, - "sar": opSAR, - } -} - -func testTwoOperandOp(t *testing.T, tests []TwoOperandTestcase, opFn executionFunc, name string) { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - pc = uint64(0) - evmInterpreter = env.interpreter - ) - - for i, test := range tests { - x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.X)) - y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Y)) - expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.Expected)) - stack.push(x) - stack.push(y) - opFn(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) - if len(stack.data) != 1 { - t.Errorf("Expected one item on stack after %v, got %d: ", name, len(stack.data)) - } - actual := stack.pop() - - if actual.Cmp(expected) != 0 { - t.Errorf("Testcase %v %d, %v(%x, %x): expected %x, got %x", name, i, name, x, y, expected, actual) - } - } -} - -func TestByteOp(t *testing.T) { - tests := []TwoOperandTestcase{ - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "00", "AB"}, - {"ABCDEF0908070605040302010000000000000000000000000000000000000000", "01", "CD"}, - {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "00", "00"}, - {"00CDEF090807060504030201ffffffffffffffffffffffffffffffffffffffff", "01", "CD"}, - {"0000000000000000000000000000000000000000000000000000000000102030", "1F", "30"}, - {"0000000000000000000000000000000000000000000000000000000000102030", "1E", "20"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "20", "00"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "FFFFFFFFFFFFFFFF", "00"}, - } - testTwoOperandOp(t, tests, opByte, "byte") -} - -func TestSHL(t *testing.T) { - // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shl-shift-left - tests := []TwoOperandTestcase{ - {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000002"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "ff", "8000000000000000000000000000000000000000000000000000000000000000"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "0101", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "8000000000000000000000000000000000000000000000000000000000000000"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"}, - } - testTwoOperandOp(t, tests, opSHL, "shl") -} - -func TestSHR(t *testing.T) { - // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#shr-logical-shift-right - tests := []TwoOperandTestcase{ - {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "01", "4000000000000000000000000000000000000000000000000000000000000000"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "ff", "0000000000000000000000000000000000000000000000000000000000000001"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "0101", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000001"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, - } - testTwoOperandOp(t, tests, opSHR, "shr") -} - -func TestSAR(t *testing.T) { - // Testcases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-145.md#sar-arithmetic-shift-right - tests := []TwoOperandTestcase{ - {"0000000000000000000000000000000000000000000000000000000000000001", "00", "0000000000000000000000000000000000000000000000000000000000000001"}, - {"0000000000000000000000000000000000000000000000000000000000000001", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "01", "c000000000000000000000000000000000000000000000000000000000000000"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"8000000000000000000000000000000000000000000000000000000000000000", "0101", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "00", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "01", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, - {"0000000000000000000000000000000000000000000000000000000000000000", "01", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"4000000000000000000000000000000000000000000000000000000000000000", "fe", "0000000000000000000000000000000000000000000000000000000000000001"}, - {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "f8", "000000000000000000000000000000000000000000000000000000000000007f"}, - {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "fe", "0000000000000000000000000000000000000000000000000000000000000001"}, - {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "ff", "0000000000000000000000000000000000000000000000000000000000000000"}, - {"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0100", "0000000000000000000000000000000000000000000000000000000000000000"}, - } - - testTwoOperandOp(t, tests, opSAR, "sar") -} - -func TestAddMod(t *testing.T) { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - evmInterpreter = NewEVMInterpreter(env) - pc = uint64(0) - ) - tests := []struct { - x string - y string - z string - expected string - }{ - {"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", - }, - } - // x + y = 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd - // in 256 bit repr, fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd - - for i, test := range tests { - x := new(uint256.Int).SetBytes(common.Hex2Bytes(test.x)) - y := new(uint256.Int).SetBytes(common.Hex2Bytes(test.y)) - z := new(uint256.Int).SetBytes(common.Hex2Bytes(test.z)) - expected := new(uint256.Int).SetBytes(common.Hex2Bytes(test.expected)) - stack.push(z) - stack.push(y) - stack.push(x) - opAddmod(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) - actual := stack.pop() - if actual.Cmp(expected) != 0 { - t.Errorf("Testcase %d, expected %x, got %x", i, expected, actual) - } - } -} - -// utility function to fill the json-file with testcases -// Enable this test to generate the 'testcases_xx.json' files -func TestWriteExpectedValues(t *testing.T) { - t.Skip("Enable this test to create json test cases.") - - // getResult is a convenience function to generate the expected values - getResult := func(args []*twoOperandParams, opFn executionFunc) []TwoOperandTestcase { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - pc = uint64(0) - interpreter = env.interpreter - ) - result := make([]TwoOperandTestcase, len(args)) - for i, param := range args { - x := new(uint256.Int).SetBytes(common.Hex2Bytes(param.x)) - y := new(uint256.Int).SetBytes(common.Hex2Bytes(param.y)) - stack.push(x) - stack.push(y) - opFn(&pc, interpreter, &ScopeContext{nil, stack, nil}) - actual := stack.pop() - result[i] = TwoOperandTestcase{param.x, param.y, fmt.Sprintf("%064x", actual)} - } - return result - } - - for name, method := range twoOpMethods { - data, err := json.Marshal(getResult(commonParams, method)) - if err != nil { - t.Fatal(err) - } - _ = os.WriteFile(fmt.Sprintf("testdata/testcases_%v.json", name), data, 0644) - if err != nil { - t.Fatal(err) - } - } -} - -// TestJsonTestcases runs through all the testcases defined as json-files -func TestJsonTestcases(t *testing.T) { - for name := range twoOpMethods { - data, err := os.ReadFile(fmt.Sprintf("testdata/testcases_%v.json", name)) - if err != nil { - t.Fatal("Failed to read file", err) - } - var testcases []TwoOperandTestcase - json.Unmarshal(data, &testcases) - testTwoOperandOp(t, testcases, twoOpMethods[name], name) - } -} - -func opBenchmark(bench *testing.B, op executionFunc, args ...string) { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - scope = &ScopeContext{nil, stack, nil} - evmInterpreter = NewEVMInterpreter(env) - ) - - env.interpreter = evmInterpreter - // convert args - intArgs := make([]*uint256.Int, len(args)) - for i, arg := range args { - intArgs[i] = new(uint256.Int).SetBytes(common.Hex2Bytes(arg)) - } - pc := uint64(0) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { - for _, arg := range intArgs { - stack.push(arg) - } - op(&pc, evmInterpreter, scope) - stack.pop() - } - bench.StopTimer() - - for i, arg := range args { - want := new(uint256.Int).SetBytes(common.Hex2Bytes(arg)) - if have := intArgs[i]; !want.Eq(have) { - bench.Fatalf("input #%d mutated, have %x want %x", i, have, want) - } - } -} - -func BenchmarkOpAdd64(b *testing.B) { - x := "ffffffff" - y := "fd37f3e2bba2c4f" - - opBenchmark(b, opAdd, x, y) -} - -func BenchmarkOpAdd128(b *testing.B) { - x := "ffffffffffffffff" - y := "f5470b43c6549b016288e9a65629687" - - opBenchmark(b, opAdd, x, y) -} - -func BenchmarkOpAdd256(b *testing.B) { - x := "0802431afcbce1fc194c9eaa417b2fb67dc75a95db0bc7ec6b1c8af11df6a1da9" - y := "a1f5aac137876480252e5dcac62c354ec0d42b76b0642b6181ed099849ea1d57" - - opBenchmark(b, opAdd, x, y) -} - -func BenchmarkOpSub64(b *testing.B) { - x := "51022b6317003a9d" - y := "a20456c62e00753a" - - opBenchmark(b, opSub, x, y) -} - -func BenchmarkOpSub128(b *testing.B) { - x := "4dde30faaacdc14d00327aac314e915d" - y := "9bbc61f5559b829a0064f558629d22ba" - - opBenchmark(b, opSub, x, y) -} - -func BenchmarkOpSub256(b *testing.B) { - x := "4bfcd8bb2ac462735b48a17580690283980aa2d679f091c64364594df113ea37" - y := "97f9b1765588c4e6b69142eb00d20507301545acf3e1238c86c8b29be227d46e" - - opBenchmark(b, opSub, x, y) -} - -func BenchmarkOpMul(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opMul, x, y) -} - -func BenchmarkOpDiv256(b *testing.B) { - x := "ff3f9014f20db29ae04af2c2d265de17" - y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611" - opBenchmark(b, opDiv, x, y) -} - -func BenchmarkOpDiv128(b *testing.B) { - x := "fdedc7f10142ff97" - y := "fbdfda0e2ce356173d1993d5f70a2b11" - opBenchmark(b, opDiv, x, y) -} - -func BenchmarkOpDiv64(b *testing.B) { - x := "fcb34eb3" - y := "f97180878e839129" - opBenchmark(b, opDiv, x, y) -} - -func BenchmarkOpSdiv(b *testing.B) { - x := "ff3f9014f20db29ae04af2c2d265de17" - y := "fe7fb0d1f59dfe9492ffbf73683fd1e870eec79504c60144cc7f5fc2bad1e611" - - opBenchmark(b, opSdiv, x, y) -} - -func BenchmarkOpMod(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opMod, x, y) -} - -func BenchmarkOpSmod(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opSmod, x, y) -} - -func BenchmarkOpExp(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opExp, x, y) -} - -func BenchmarkOpSignExtend(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opSignExtend, x, y) -} - -func BenchmarkOpLt(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opLt, x, y) -} - -func BenchmarkOpGt(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opGt, x, y) -} - -func BenchmarkOpSlt(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opSlt, x, y) -} - -func BenchmarkOpSgt(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opSgt, x, y) -} - -func BenchmarkOpEq(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opEq, x, y) -} -func BenchmarkOpEq2(b *testing.B) { - x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" - y := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201fffffffe" - opBenchmark(b, opEq, x, y) -} -func BenchmarkOpAnd(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opAnd, x, y) -} - -func BenchmarkOpOr(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opOr, x, y) -} - -func BenchmarkOpXor(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opXor, x, y) -} - -func BenchmarkOpByte(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - - opBenchmark(b, opByte, x, y) -} - -func BenchmarkOpAddmod(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - z := alphabetSoup - - opBenchmark(b, opAddmod, x, y, z) -} - -func BenchmarkOpMulmod(b *testing.B) { - x := alphabetSoup - y := alphabetSoup - z := alphabetSoup - - opBenchmark(b, opMulmod, x, y, z) -} - -func BenchmarkOpSHL(b *testing.B) { - x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" - y := "ff" - - opBenchmark(b, opSHL, x, y) -} -func BenchmarkOpSHR(b *testing.B) { - x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" - y := "ff" - - opBenchmark(b, opSHR, x, y) -} -func BenchmarkOpSAR(b *testing.B) { - x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" - y := "ff" - - opBenchmark(b, opSAR, x, y) -} -func BenchmarkOpIsZero(b *testing.B) { - x := "FBCDEF090807060504030201ffffffffFBCDEF090807060504030201ffffffff" - opBenchmark(b, opIszero, x) -} - -func TestOpMstore(t *testing.T) { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - mem = NewMemory() - evmInterpreter = NewEVMInterpreter(env) - ) - - env.interpreter = evmInterpreter - mem.Resize(64) - pc := uint64(0) - v := "abcdef00000000000000abba000000000deaf000000c0de00100000000133700" - stack.push(new(uint256.Int).SetBytes(common.Hex2Bytes(v))) - stack.push(new(uint256.Int)) - opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) - if got := common.Bytes2Hex(mem.GetCopy(0, 32)); got != v { - t.Fatalf("Mstore fail, got %v, expected %v", got, v) - } - stack.push(new(uint256.Int).SetUint64(0x1)) - stack.push(new(uint256.Int)) - opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) - if common.Bytes2Hex(mem.GetCopy(0, 32)) != "0000000000000000000000000000000000000000000000000000000000000001" { - t.Fatalf("Mstore failed to overwrite previous value") - } -} - -func BenchmarkOpMstore(bench *testing.B) { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - mem = NewMemory() - evmInterpreter = NewEVMInterpreter(env) - ) - - env.interpreter = evmInterpreter - mem.Resize(64) - pc := uint64(0) - memStart := new(uint256.Int) - value := new(uint256.Int).SetUint64(0x1337) - - bench.ResetTimer() - for i := 0; i < bench.N; i++ { - stack.push(value) - stack.push(memStart) - opMstore(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) - } -} - -func TestOpTstore(t *testing.T) { - var ( - statedb, _ = state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - env = NewEVM(BlockContext{}, TxContext{}, statedb, params.TestChainConfig, Config{}) - stack = newstack() - mem = NewMemory() - evmInterpreter = NewEVMInterpreter(env) - caller = common.Address{} - to = common.Address{1} - contractRef = contractRef{caller} - contract = NewContract(contractRef, AccountRef(to), new(uint256.Int), 0) - scopeContext = ScopeContext{mem, stack, contract} - value = common.Hex2Bytes("abcdef00000000000000abba000000000deaf000000c0de00100000000133700") - ) - - // Add a stateObject for the caller and the contract being called - statedb.CreateAccount(caller) - statedb.CreateAccount(to) - - env.interpreter = evmInterpreter - pc := uint64(0) - // push the value to the stack - stack.push(new(uint256.Int).SetBytes(value)) - // push the location to the stack - stack.push(new(uint256.Int)) - opTstore(&pc, evmInterpreter, &scopeContext) - // there should be no elements on the stack after TSTORE - if stack.len() != 0 { - t.Fatal("stack wrong size") - } - // push the location to the stack - stack.push(new(uint256.Int)) - opTload(&pc, evmInterpreter, &scopeContext) - // there should be one element on the stack after TLOAD - if stack.len() != 1 { - t.Fatal("stack wrong size") - } - val := stack.peek() - if !bytes.Equal(val.Bytes(), value) { - t.Fatal("incorrect element read from transient storage") - } -} - -func BenchmarkOpKeccak256(bench *testing.B) { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - mem = NewMemory() - evmInterpreter = NewEVMInterpreter(env) - ) - env.interpreter = evmInterpreter - mem.Resize(32) - pc := uint64(0) - start := new(uint256.Int) - - bench.ResetTimer() - for i := 0; i < bench.N; i++ { - stack.push(uint256.NewInt(32)) - stack.push(start) - opKeccak256(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) - } -} - -func TestCreate2Addreses(t *testing.T) { - type testcase struct { - origin string - salt string - code string - expected string - } - - for i, tt := range []testcase{ - { - origin: "0x0000000000000000000000000000000000000000", - salt: "0x0000000000000000000000000000000000000000", - code: "0x00", - expected: "0x4d1a2e2bb4f88f0250f26ffff098b0b30b26bf38", - }, - { - origin: "0xdeadbeef00000000000000000000000000000000", - salt: "0x0000000000000000000000000000000000000000", - code: "0x00", - expected: "0xB928f69Bb1D91Cd65274e3c79d8986362984fDA3", - }, - { - origin: "0xdeadbeef00000000000000000000000000000000", - salt: "0xfeed000000000000000000000000000000000000", - code: "0x00", - expected: "0xD04116cDd17beBE565EB2422F2497E06cC1C9833", - }, - { - origin: "0x0000000000000000000000000000000000000000", - salt: "0x0000000000000000000000000000000000000000", - code: "0xdeadbeef", - expected: "0x70f2b2914A2a4b783FaEFb75f459A580616Fcb5e", - }, - { - origin: "0x00000000000000000000000000000000deadbeef", - salt: "0xcafebabe", - code: "0xdeadbeef", - expected: "0x60f3f640a8508fC6a86d45DF051962668E1e8AC7", - }, - { - origin: "0x00000000000000000000000000000000deadbeef", - salt: "0xcafebabe", - code: "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef", - expected: "0x1d8bfDC5D46DC4f61D6b6115972536eBE6A8854C", - }, - { - origin: "0x0000000000000000000000000000000000000000", - salt: "0x0000000000000000000000000000000000000000", - code: "0x", - expected: "0xE33C0C7F7df4809055C3ebA6c09CFe4BaF1BD9e0", - }, - } { - origin := common.BytesToAddress(common.FromHex(tt.origin)) - salt := common.BytesToHash(common.FromHex(tt.salt)) - code := common.FromHex(tt.code) - codeHash := crypto.Keccak256(code) - address := crypto.CreateAddress2(origin, salt, codeHash) - /* - stack := newstack() - // salt, but we don't need that for this test - stack.push(big.NewInt(int64(len(code)))) //size - stack.push(big.NewInt(0)) // memstart - stack.push(big.NewInt(0)) // value - gas, _ := gasCreate2(params.GasTable{}, nil, nil, stack, nil, 0) - fmt.Printf("Example %d\n* address `0x%x`\n* salt `0x%x`\n* init_code `0x%x`\n* gas (assuming no mem expansion): `%v`\n* result: `%s`\n\n", i,origin, salt, code, gas, address.String()) - */ - expected := common.BytesToAddress(common.FromHex(tt.expected)) - if !bytes.Equal(expected.Bytes(), address.Bytes()) { - t.Errorf("test %d: expected %s, got %s", i, expected.String(), address.String()) - } - } -} - -// TestRandom is a test for the RANDOM opcode in geth, which we do not support. Therefore, we use this test to check that DIFFICULTY opcode continues to work -// the same as the RANDOM opcode except using the Difficulty value in the block context. -// Note: this should not be used as a source of randomness in coreth since the difficulty is required to be 1. -func TestRandom(t *testing.T) { - type testcase struct { - name string - random common.Hash - } - - for _, tt := range []testcase{ - {name: "empty hash", random: common.Hash{}}, - {name: "1", random: common.Hash{0}}, - {name: "emptyCodeHash", random: types.EmptyCodeHash}, - {name: "hash(0x010203)", random: crypto.Keccak256Hash([]byte{0x01, 0x02, 0x03})}, - } { - var ( - env = NewEVM(BlockContext{Difficulty: tt.random.Big()}, TxContext{}, nil, params.TestChainConfig, Config{}) // Note: we convert random hash to *big.Int for backwards compatibility - stack = newstack() - pc = uint64(0) - evmInterpreter = env.interpreter - ) - // Note: we use opDifficulty instead of opRandom since we do not migrate from opDifficulty to opRandom, but expect it to work the same - opDifficulty(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) - if len(stack.data) != 1 { - t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data)) - } - actual := stack.pop() - expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.random.Bytes())) - if overflow { - t.Errorf("Testcase %v: invalid overflow", tt.name) - } - if actual.Cmp(expected) != 0 { - t.Errorf("Testcase %v: expected %x, got %x", tt.name, expected, actual) - } - } -} - -func TestBlobHash(t *testing.T) { - type testcase struct { - name string - idx uint64 - expect common.Hash - hashes []common.Hash - } - var ( - zero = common.Hash{0} - one = common.Hash{1} - two = common.Hash{2} - three = common.Hash{3} - ) - for _, tt := range []testcase{ - {name: "[{1}]", idx: 0, expect: one, hashes: []common.Hash{one}}, - {name: "[1,{2},3]", idx: 2, expect: three, hashes: []common.Hash{one, two, three}}, - {name: "out-of-bounds (empty)", idx: 10, expect: zero, hashes: []common.Hash{}}, - {name: "out-of-bounds", idx: 25, expect: zero, hashes: []common.Hash{one, two, three}}, - {name: "out-of-bounds (nil)", idx: 25, expect: zero, hashes: nil}, - } { - var ( - env = NewEVM(BlockContext{}, TxContext{BlobHashes: tt.hashes}, nil, params.TestChainConfig, Config{}) - stack = newstack() - pc = uint64(0) - evmInterpreter = env.interpreter - ) - stack.push(uint256.NewInt(tt.idx)) - opBlobHash(&pc, evmInterpreter, &ScopeContext{nil, stack, nil}) - if len(stack.data) != 1 { - t.Errorf("Expected one item on stack after %v, got %d: ", tt.name, len(stack.data)) - } - actual := stack.pop() - expected, overflow := uint256.FromBig(new(big.Int).SetBytes(tt.expect.Bytes())) - if overflow { - t.Errorf("Testcase %v: invalid overflow", tt.name) - } - if actual.Cmp(expected) != 0 { - t.Errorf("Testcase %v: expected %x, got %x", tt.name, expected, actual) - } - } -} - -func TestOpMCopy(t *testing.T) { - // Test cases from https://eips.ethereum.org/EIPS/eip-5656#test-cases - for i, tc := range []struct { - dst, src, len string - pre string - want string - wantGas uint64 - }{ - { // MCOPY 0 32 32 - copy 32 bytes from offset 32 to offset 0. - dst: "0x0", src: "0x20", len: "0x20", - pre: "0000000000000000000000000000000000000000000000000000000000000000 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", - want: "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", - wantGas: 6, - }, - - { // MCOPY 0 0 32 - copy 32 bytes from offset 0 to offset 0. - dst: "0x0", src: "0x0", len: "0x20", - pre: "0101010101010101010101010101010101010101010101010101010101010101", - want: "0101010101010101010101010101010101010101010101010101010101010101", - wantGas: 6, - }, - { // MCOPY 0 1 8 - copy 8 bytes from offset 1 to offset 0 (overlapping). - dst: "0x0", src: "0x1", len: "0x8", - pre: "000102030405060708 000000000000000000000000000000000000000000000000", - want: "010203040506070808 000000000000000000000000000000000000000000000000", - wantGas: 6, - }, - { // MCOPY 1 0 8 - copy 8 bytes from offset 0 to offset 1 (overlapping). - dst: "0x1", src: "0x0", len: "0x8", - pre: "000102030405060708 000000000000000000000000000000000000000000000000", - want: "000001020304050607 000000000000000000000000000000000000000000000000", - wantGas: 6, - }, - // Tests below are not in the EIP, but maybe should be added - { // MCOPY 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds index(overlapping). - dst: "0xFFFFFFFFFFFF", src: "0xFFFFFFFFFFFF", len: "0x0", - pre: "11", - want: "11", - wantGas: 3, - }, - { // MCOPY 0xFFFFFFFFFFFF 0 0 - copy zero bytes from start of mem to out-of-bounds. - dst: "0xFFFFFFFFFFFF", src: "0x0", len: "0x0", - pre: "11", - want: "11", - wantGas: 3, - }, - { // MCOPY 0 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds to start of mem - dst: "0x0", src: "0xFFFFFFFFFFFF", len: "0x0", - pre: "11", - want: "11", - wantGas: 3, - }, - { // MCOPY - copy 1 from space outside of uint64 space - dst: "0x0", src: "0x10000000000000000", len: "0x1", - pre: "0", - }, - { // MCOPY - copy 1 from 0 to space outside of uint64 - dst: "0x10000000000000000", src: "0x0", len: "0x1", - pre: "0", - }, - { // MCOPY - copy nothing from 0 to space outside of uint64 - dst: "0x10000000000000000", src: "0x0", len: "0x0", - pre: "", - want: "", - wantGas: 3, - }, - { // MCOPY - copy 1 from 0x20 to 0x10, with no prior allocated mem - dst: "0x10", src: "0x20", len: "0x1", - pre: "", - // 64 bytes - want: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - wantGas: 12, - }, - { // MCOPY - copy 1 from 0x19 to 0x10, with no prior allocated mem - dst: "0x10", src: "0x19", len: "0x1", - pre: "", - // 32 bytes - want: "0x0000000000000000000000000000000000000000000000000000000000000000", - wantGas: 9, - }, - } { - var ( - env = NewEVM(BlockContext{}, TxContext{}, nil, params.TestChainConfig, Config{}) - stack = newstack() - pc = uint64(0) - evmInterpreter = env.interpreter - ) - data := common.FromHex(strings.ReplaceAll(tc.pre, " ", "")) - // Set pre - mem := NewMemory() - mem.Resize(uint64(len(data))) - mem.Set(0, uint64(len(data)), data) - // Push stack args - len, _ := uint256.FromHex(tc.len) - src, _ := uint256.FromHex(tc.src) - dst, _ := uint256.FromHex(tc.dst) - - stack.push(len) - stack.push(src) - stack.push(dst) - wantErr := (tc.wantGas == 0) - // Calc mem expansion - var memorySize uint64 - if memSize, overflow := memoryMcopy(stack); overflow { - if wantErr { - continue - } - t.Errorf("overflow") - } else { - var overflow bool - if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow { - t.Error(vmerrs.ErrGasUintOverflow) - } - } - // and the dynamic cost - var haveGas uint64 - if dynamicCost, err := gasMcopy(env, nil, stack, mem, memorySize); err != nil { - t.Error(err) - } else { - haveGas = GasFastestStep + dynamicCost - } - // Expand mem - if memorySize > 0 { - mem.Resize(memorySize) - } - // Do the copy - opMcopy(&pc, evmInterpreter, &ScopeContext{mem, stack, nil}) - want := common.FromHex(strings.ReplaceAll(tc.want, " ", "")) - if have := mem.store; !bytes.Equal(want, have) { - t.Errorf("case %d: \nwant: %#x\nhave: %#x\n", i, want, have) - } - wantGas := tc.wantGas - if haveGas != wantGas { - t.Errorf("case %d: gas wrong, want %d have %d\n", i, wantGas, haveGas) - } - } -} diff --git a/core/vm/interface.go b/core/vm/interface.go deleted file mode 100644 index f9bc01ca86..0000000000 --- a/core/vm/interface.go +++ /dev/null @@ -1,116 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "math/big" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -// StateDB is an EVM database for full state querying. -type StateDB interface { - CreateAccount(common.Address) - - SubBalance(common.Address, *uint256.Int) - AddBalance(common.Address, *uint256.Int) - GetBalance(common.Address) *uint256.Int - - SubBalanceMultiCoin(common.Address, common.Hash, *big.Int) - AddBalanceMultiCoin(common.Address, common.Hash, *big.Int) - GetBalanceMultiCoin(common.Address, common.Hash) *big.Int - - GetNonce(common.Address) uint64 - SetNonce(common.Address, uint64) - - GetCodeHash(common.Address) common.Hash - GetCode(common.Address) []byte - SetCode(common.Address, []byte) - GetCodeSize(common.Address) int - - AddRefund(uint64) - SubRefund(uint64) - GetRefund() uint64 - - GetCommittedState(common.Address, common.Hash) common.Hash - GetCommittedStateAP1(common.Address, common.Hash) common.Hash - GetState(common.Address, common.Hash) common.Hash - SetState(common.Address, common.Hash, common.Hash) - - GetTransientState(addr common.Address, key common.Hash) common.Hash - SetTransientState(addr common.Address, key, value common.Hash) - - SelfDestruct(common.Address) - HasSelfDestructed(common.Address) bool - - Selfdestruct6780(common.Address) - - // Exist reports whether the given account exists in state. - // Notably this should also return true for self-destructed accounts. - Exist(common.Address) bool - // Empty returns whether the given account is empty. Empty - // is defined according to EIP161 (balance = nonce = code = 0). - Empty(common.Address) bool - - AddressInAccessList(addr common.Address) bool - SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) - // AddAddressToAccessList adds the given address to the access list. This operation is safe to perform - // even if the feature/fork is not active yet - AddAddressToAccessList(addr common.Address) - // AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform - // even if the feature/fork is not active yet - AddSlotToAccessList(addr common.Address, slot common.Hash) - Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) - - RevertToSnapshot(int) - Snapshot() int - - AddLog(addr common.Address, topics []common.Hash, data []byte, blockNumber uint64) - GetLogData() (topics [][]common.Hash, data [][]byte) - GetPredicateStorageSlots(address common.Address, index int) ([]byte, bool) - SetPredicateStorageSlots(address common.Address, predicates [][]byte) - - GetTxHash() common.Hash - - AddPreimage(common.Hash, []byte) -} - -// CallContext provides a basic interface for the EVM calling conventions. The EVM -// depends on this context being implemented for doing subcalls and initialising new EVM contracts. -type CallContext interface { - // Call calls another contract. - Call(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) - // CallCode takes another contracts code and execute within our own context - CallCode(env *EVM, me ContractRef, addr common.Address, data []byte, gas, value *big.Int) ([]byte, error) - // DelegateCall is same as CallCode except sender and value is propagated from parent to child scope - DelegateCall(env *EVM, me ContractRef, addr common.Address, data []byte, gas *big.Int) ([]byte, error) - // Create creates a new contract - Create(env *EVM, me ContractRef, data []byte, gas, value *big.Int) ([]byte, common.Address, error) -} diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go deleted file mode 100644 index 5d495f0af6..0000000000 --- a/core/vm/interpreter.go +++ /dev/null @@ -1,257 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" -) - -// Config are the configuration options for the Interpreter -type Config struct { - Tracer EVMLogger // Opcode logger - NoBaseFee bool // Forces the EIP-1559 baseFee to 0 (needed for 0 price calls) - EnablePreimageRecording bool // Enables recording of SHA3/keccak preimages - ExtraEips []int // Additional EIPS that are to be enabled -} - -// ScopeContext contains the things that are per-call, such as stack and memory, -// but not transients like pc and gas -type ScopeContext struct { - Memory *Memory - Stack *Stack - Contract *Contract -} - -// EVMInterpreter represents an EVM interpreter -type EVMInterpreter struct { - evm *EVM - table *JumpTable - - hasher crypto.KeccakState // Keccak256 hasher instance shared across opcodes - hasherBuf common.Hash // Keccak256 hasher result array shared across opcodes - - readOnly bool // Whether to throw on stateful modifications - returnData []byte // Last CALL's return data for subsequent reuse -} - -// NewEVMInterpreter returns a new instance of the Interpreter. -func NewEVMInterpreter(evm *EVM) *EVMInterpreter { - // If jump table was not initialised we set the default one. - var table *JumpTable - switch { - case evm.chainRules.IsCancun: - table = &cancunInstructionSet - case evm.chainRules.IsDurango: - table = &durangoInstructionSet - case evm.chainRules.IsApricotPhase3: - table = &apricotPhase3InstructionSet - case evm.chainRules.IsApricotPhase2: - table = &apricotPhase2InstructionSet - case evm.chainRules.IsApricotPhase1: - table = &apricotPhase1InstructionSet - case evm.chainRules.IsIstanbul: - table = &istanbulInstructionSet - case evm.chainRules.IsConstantinople: - table = &constantinopleInstructionSet - case evm.chainRules.IsByzantium: - table = &byzantiumInstructionSet - case evm.chainRules.IsEIP158: - table = &spuriousDragonInstructionSet - case evm.chainRules.IsEIP150: - table = &tangerineWhistleInstructionSet - case evm.chainRules.IsHomestead: - table = &homesteadInstructionSet - default: - table = &frontierInstructionSet - } - var extraEips []int - if len(evm.Config.ExtraEips) > 0 { - // Deep-copy jumptable to prevent modification of opcodes in other tables - table = copyJumpTable(table) - } - for _, eip := range evm.Config.ExtraEips { - if err := EnableEIP(eip, table); err != nil { - // Disable it, so caller can check if it's activated or not - log.Error("EIP activation failed", "eip", eip, "error", err) - } else { - extraEips = append(extraEips, eip) - } - } - evm.Config.ExtraEips = extraEips - return &EVMInterpreter{evm: evm, table: table} -} - -// Run loops and evaluates the contract's code with the given input data and returns -// the return byte-slice and an error if one occurred. -// -// It's important to note that any errors returned by the interpreter should be -// considered a revert-and-consume-all-gas operation except for -// ErrExecutionReverted which means revert-and-keep-gas-left. -func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) { - // Increment the call depth which is restricted to 1024 - in.evm.depth++ - defer func() { in.evm.depth-- }() - - // Make sure the readOnly is only set if we aren't in readOnly yet. - // This also makes sure that the readOnly flag isn't removed for child calls. - if readOnly && !in.readOnly { - in.readOnly = true - defer func() { in.readOnly = false }() - } - - // Reset the previous call's return data. It's unimportant to preserve the old buffer - // as every returning call will return new data anyway. - in.returnData = nil - - // Don't bother with the execution if there's no code. - // Note: this avoids invoking the tracer in any way for simple value - // transfers to EOA accounts. - if len(contract.Code) == 0 { - return nil, nil - } - - var ( - op OpCode // current opcode - mem = NewMemory() // bound memory - stack = newstack() // local stack - callContext = &ScopeContext{ - Memory: mem, - Stack: stack, - Contract: contract, - } - // For optimisation reason we're using uint64 as the program counter. - // It's theoretically possible to go above 2^64. The YP defines the PC - // to be uint256. Practically much less so feasible. - pc = uint64(0) // program counter - cost uint64 - // copies used by tracer - pcCopy uint64 // needed for the deferred EVMLogger - gasCopy uint64 // for EVMLogger to log gas remaining before execution - logged bool // deferred EVMLogger should ignore already logged steps - res []byte // result of the opcode execution function - debug = in.evm.Config.Tracer != nil - ) - - // Don't move this deferred function, it's placed before the capturestate-deferred method, - // so that it gets executed _after_: the capturestate needs the stacks before - // they are returned to the pools - defer func() { - returnStack(stack) - }() - contract.Input = input - - if debug { - defer func() { - if err != nil { - if !logged { - in.evm.Config.Tracer.CaptureState(pcCopy, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err) - } else { - in.evm.Config.Tracer.CaptureFault(pcCopy, op, gasCopy, cost, callContext, in.evm.depth, err) - } - } - }() - } - // The Interpreter main run loop (contextual). This loop runs until either an - // explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during - // the execution of one of the operations or until the done flag is set by the - // parent context. - for { - if debug { - // Capture pre-execution values for tracing. - logged, pcCopy, gasCopy = false, pc, contract.Gas - } - // Get the operation from the jump table and validate the stack to ensure there are - // enough stack items available to perform the operation. - op = contract.GetOp(pc) - operation := in.table[op] - cost = operation.constantGas // For tracing - // Validate stack - if sLen := stack.len(); sLen < operation.minStack { - return nil, &ErrStackUnderflow{stackLen: sLen, required: operation.minStack} - } else if sLen > operation.maxStack { - return nil, &ErrStackOverflow{stackLen: sLen, limit: operation.maxStack} - } - if !contract.UseGas(cost) { - return nil, vmerrs.ErrOutOfGas - } - - if operation.dynamicGas != nil { - // All ops with a dynamic memory usage also has a dynamic gas cost. - var memorySize uint64 - // calculate the new memory size and expand the memory to fit - // the operation - // Memory check needs to be done prior to evaluating the dynamic gas portion, - // to detect calculation overflows - if operation.memorySize != nil { - memSize, overflow := operation.memorySize(stack) - if overflow { - return nil, vmerrs.ErrGasUintOverflow - } - // memory is expanded in words of 32 bytes. Gas - // is also calculated in words. - if memorySize, overflow = math.SafeMul(toWordSize(memSize), 32); overflow { - return nil, vmerrs.ErrGasUintOverflow - } - } - // Consume the gas and return an error if not enough gas is available. - // cost is explicitly set so that the capture state defer method can get the proper cost - var dynamicCost uint64 - dynamicCost, err = operation.dynamicGas(in.evm, contract, stack, mem, memorySize) - cost += dynamicCost // for tracing - if err != nil || !contract.UseGas(dynamicCost) { - return nil, vmerrs.ErrOutOfGas - } - // Do tracing before memory expansion - if debug { - in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err) - logged = true - } - if memorySize > 0 { - mem.Resize(memorySize) - } - } else if debug { - in.evm.Config.Tracer.CaptureState(pc, op, gasCopy, cost, callContext, in.returnData, in.evm.depth, err) - logged = true - } - - // execute the operation - res, err = operation.execute(&pc, in, callContext) - if err != nil { - break - } - pc++ - } - if err == errStopToken { - err = nil // clear stop token error - } - - return res, err -} diff --git a/core/vm/interpreter_test.go b/core/vm/interpreter_test.go deleted file mode 100644 index 32453ddb79..0000000000 --- a/core/vm/interpreter_test.go +++ /dev/null @@ -1,87 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "testing" - "time" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/holiman/uint256" -) - -var loopInterruptTests = []string{ - // infinite loop using JUMP: push(2) jumpdest dup1 jump - "60025b8056", - // infinite loop using JUMPI: push(1) push(4) jumpdest dup2 dup2 jumpi - "600160045b818157", -} - -func TestLoopInterrupt(t *testing.T) { - address := common.BytesToAddress([]byte("contract")) - vmctx := BlockContext{ - Transfer: func(StateDB, common.Address, common.Address, *uint256.Int) {}, - } - - for i, tt := range loopInterruptTests { - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - statedb.CreateAccount(address) - statedb.SetCode(address, common.Hex2Bytes(tt)) - statedb.Finalise(true) - - evm := NewEVM(vmctx, TxContext{}, statedb, params.TestChainConfig, Config{}) - - errChannel := make(chan error) - timeout := make(chan bool) - - go func(evm *EVM) { - _, _, err := evm.Call(AccountRef(common.Address{}), address, nil, math.MaxUint64, new(uint256.Int)) - errChannel <- err - }(evm) - - go func() { - <-time.After(time.Second) - timeout <- true - }() - - evm.Cancel() - - select { - case <-timeout: - t.Errorf("test %d timed out", i) - case err := <-errChannel: - if err != nil { - t.Errorf("test %d failure: %v", i, err) - } - } - } -} diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go deleted file mode 100644 index f642f1cb8a..0000000000 --- a/core/vm/jump_table.go +++ /dev/null @@ -1,1090 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "fmt" - - "github.com/ava-labs/coreth/params" -) - -type ( - executionFunc func(pc *uint64, interpreter *EVMInterpreter, callContext *ScopeContext) ([]byte, error) - gasFunc func(*EVM, *Contract, *Stack, *Memory, uint64) (uint64, error) // last parameter is the requested memory size as a uint64 - // memorySizeFunc returns the required size, and whether the operation overflowed a uint64 - memorySizeFunc func(*Stack) (size uint64, overflow bool) -) - -type operation struct { - // execute is the operation function - execute executionFunc - constantGas uint64 - dynamicGas gasFunc - // minStack tells how many stack items are required - minStack int - // maxStack specifies the max length the stack can have for this operation - // to not overflow the stack. - maxStack int - - // memorySize returns the memory size required for the operation - memorySize memorySizeFunc -} - -var ( - frontierInstructionSet = newFrontierInstructionSet() - homesteadInstructionSet = newHomesteadInstructionSet() - tangerineWhistleInstructionSet = newTangerineWhistleInstructionSet() - spuriousDragonInstructionSet = newSpuriousDragonInstructionSet() - byzantiumInstructionSet = newByzantiumInstructionSet() - constantinopleInstructionSet = newConstantinopleInstructionSet() - istanbulInstructionSet = newIstanbulInstructionSet() - apricotPhase1InstructionSet = newApricotPhase1InstructionSet() - apricotPhase2InstructionSet = newApricotPhase2InstructionSet() - apricotPhase3InstructionSet = newApricotPhase3InstructionSet() - durangoInstructionSet = newDurangoInstructionSet() - cancunInstructionSet = newCancunInstructionSet() -) - -// JumpTable contains the EVM opcodes supported at a given fork. -type JumpTable [256]*operation - -func validate(jt JumpTable) JumpTable { - for i, op := range jt { - if op == nil { - panic(fmt.Sprintf("op %#x is not set", i)) - } - // The interpreter has an assumption that if the memorySize function is - // set, then the dynamicGas function is also set. This is a somewhat - // arbitrary assumption, and can be removed if we need to -- but it - // allows us to avoid a condition check. As long as we have that assumption - // in there, this little sanity check prevents us from merging in a - // change which violates it. - if op.memorySize != nil && op.dynamicGas == nil { - panic(fmt.Sprintf("op %v has dynamic memory but not dynamic gas", OpCode(i).String())) - } - } - return jt -} - -func newCancunInstructionSet() JumpTable { - instructionSet := newDurangoInstructionSet() - enable4844(&instructionSet) // EIP-4844 (BLOBHASH opcode) - enable7516(&instructionSet) // EIP-7516 (BLOBBASEFEE opcode) - enable1153(&instructionSet) // EIP-1153 "Transient Storage" - enable5656(&instructionSet) // EIP-5656 (MCOPY opcode) - enable6780(&instructionSet) // EIP-6780 SELFDESTRUCT only in same transaction - return validate(instructionSet) -} - -// newDurangoInstructionSet returns the frontier, homestead, byzantium, -// constantinople, istanbul, petersburg, apricotPhase1, 2, and 3, durango instructions. -func newDurangoInstructionSet() JumpTable { - instructionSet := newApricotPhase3InstructionSet() - enable3855(&instructionSet) // PUSH0 instruction - enable3860(&instructionSet) // Limit and meter initcode - - return validate(instructionSet) -} - -// newApricotPhase3InstructionSet returns the frontier, homestead, byzantium, -// constantinople, istanbul, petersburg, apricotPhase1, 2, and 3 instructions. -func newApricotPhase3InstructionSet() JumpTable { - instructionSet := newApricotPhase2InstructionSet() - enable3198(&instructionSet) // Base fee opcode https://eips.ethereum.org/EIPS/eip-3198 - return validate(instructionSet) -} - -// newApricotPhase2InstructionSet returns the frontier, -// homestead, byzantium, constantinople petersburg, -// istanbul, and apricotPhase1 instructions. -func newApricotPhase2InstructionSet() JumpTable { - instructionSet := newApricotPhase1InstructionSet() - - enable2929(&instructionSet) - - return validate(instructionSet) -} - -// newApricotPhase1InstructionSet returns the frontier, -// homestead, byzantium, constantinople petersburg, -// and istanbul instructions. -func newApricotPhase1InstructionSet() JumpTable { - instructionSet := newIstanbulInstructionSet() - - enableAP1(&instructionSet) - - return validate(instructionSet) -} - -// newIstanbulInstructionSet returns the frontier, -// homestead, byzantium, constantinople and petersburg instructions. -func newIstanbulInstructionSet() JumpTable { - instructionSet := newConstantinopleInstructionSet() - - enable1344(&instructionSet) // ChainID opcode - https://eips.ethereum.org/EIPS/eip-1344 - enable1884(&instructionSet) // Reprice reader opcodes - https://eips.ethereum.org/EIPS/eip-1884 - enable2200(&instructionSet) // Net metered SSTORE - https://eips.ethereum.org/EIPS/eip-2200 - - return validate(instructionSet) -} - -// newConstantinopleInstructionSet returns the frontier, homestead, -// byzantium and constantinople instructions. -func newConstantinopleInstructionSet() JumpTable { - instructionSet := newByzantiumInstructionSet() - instructionSet[SHL] = &operation{ - execute: opSHL, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - } - instructionSet[SHR] = &operation{ - execute: opSHR, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - } - instructionSet[SAR] = &operation{ - execute: opSAR, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - } - instructionSet[EXTCODEHASH] = &operation{ - execute: opExtCodeHash, - constantGas: params.ExtcodeHashGasConstantinople, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - } - instructionSet[CREATE2] = &operation{ - execute: opCreate2, - constantGas: params.Create2Gas, - dynamicGas: gasCreate2, - minStack: minStack(4, 1), - maxStack: maxStack(4, 1), - memorySize: memoryCreate2, - } - return validate(instructionSet) -} - -// newByzantiumInstructionSet returns the frontier, homestead and -// byzantium instructions. -func newByzantiumInstructionSet() JumpTable { - instructionSet := newSpuriousDragonInstructionSet() - instructionSet[STATICCALL] = &operation{ - execute: opStaticCall, - constantGas: params.CallGasEIP150, - dynamicGas: gasStaticCall, - minStack: minStack(6, 1), - maxStack: maxStack(6, 1), - memorySize: memoryStaticCall, - } - instructionSet[RETURNDATASIZE] = &operation{ - execute: opReturnDataSize, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - } - instructionSet[RETURNDATACOPY] = &operation{ - execute: opReturnDataCopy, - constantGas: GasFastestStep, - dynamicGas: gasReturnDataCopy, - minStack: minStack(3, 0), - maxStack: maxStack(3, 0), - memorySize: memoryReturnDataCopy, - } - instructionSet[REVERT] = &operation{ - execute: opRevert, - dynamicGas: gasRevert, - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - memorySize: memoryRevert, - } - return validate(instructionSet) -} - -// EIP 158 a.k.a Spurious Dragon -func newSpuriousDragonInstructionSet() JumpTable { - instructionSet := newTangerineWhistleInstructionSet() - instructionSet[EXP].dynamicGas = gasExpEIP158 - return validate(instructionSet) -} - -// EIP 150 a.k.a Tangerine Whistle -func newTangerineWhistleInstructionSet() JumpTable { - instructionSet := newHomesteadInstructionSet() - instructionSet[BALANCE].constantGas = params.BalanceGasEIP150 - instructionSet[EXTCODESIZE].constantGas = params.ExtcodeSizeGasEIP150 - instructionSet[SLOAD].constantGas = params.SloadGasEIP150 - instructionSet[EXTCODECOPY].constantGas = params.ExtcodeCopyBaseEIP150 - instructionSet[CALL].constantGas = params.CallGasEIP150 - instructionSet[CALLCODE].constantGas = params.CallGasEIP150 - instructionSet[DELEGATECALL].constantGas = params.CallGasEIP150 - return validate(instructionSet) -} - -// newHomesteadInstructionSet returns the frontier and homestead -// instructions that can be executed during the homestead phase. -func newHomesteadInstructionSet() JumpTable { - instructionSet := newFrontierInstructionSet() - instructionSet[DELEGATECALL] = &operation{ - execute: opDelegateCall, - dynamicGas: gasDelegateCall, - constantGas: params.CallGasFrontier, - minStack: minStack(6, 1), - maxStack: maxStack(6, 1), - memorySize: memoryDelegateCall, - } - return validate(instructionSet) -} - -// newFrontierInstructionSet returns the frontier instructions -// that can be executed during the frontier phase. -func newFrontierInstructionSet() JumpTable { - tbl := JumpTable{ - STOP: { - execute: opStop, - constantGas: 0, - minStack: minStack(0, 0), - maxStack: maxStack(0, 0), - }, - ADD: { - execute: opAdd, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - MUL: { - execute: opMul, - constantGas: GasFastStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - SUB: { - execute: opSub, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - DIV: { - execute: opDiv, - constantGas: GasFastStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - SDIV: { - execute: opSdiv, - constantGas: GasFastStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - MOD: { - execute: opMod, - constantGas: GasFastStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - SMOD: { - execute: opSmod, - constantGas: GasFastStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - ADDMOD: { - execute: opAddmod, - constantGas: GasMidStep, - minStack: minStack(3, 1), - maxStack: maxStack(3, 1), - }, - MULMOD: { - execute: opMulmod, - constantGas: GasMidStep, - minStack: minStack(3, 1), - maxStack: maxStack(3, 1), - }, - EXP: { - execute: opExp, - dynamicGas: gasExpFrontier, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - SIGNEXTEND: { - execute: opSignExtend, - constantGas: GasFastStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - LT: { - execute: opLt, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - GT: { - execute: opGt, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - SLT: { - execute: opSlt, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - SGT: { - execute: opSgt, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - EQ: { - execute: opEq, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - ISZERO: { - execute: opIszero, - constantGas: GasFastestStep, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - }, - AND: { - execute: opAnd, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - XOR: { - execute: opXor, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - OR: { - execute: opOr, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - NOT: { - execute: opNot, - constantGas: GasFastestStep, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - }, - BYTE: { - execute: opByte, - constantGas: GasFastestStep, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - }, - KECCAK256: { - execute: opKeccak256, - constantGas: params.Keccak256Gas, - dynamicGas: gasKeccak256, - minStack: minStack(2, 1), - maxStack: maxStack(2, 1), - memorySize: memoryKeccak256, - }, - ADDRESS: { - execute: opAddress, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - BALANCE: { - execute: opBalance, - constantGas: params.BalanceGasFrontier, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - }, - ORIGIN: { - execute: opOrigin, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - CALLER: { - execute: opCaller, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - CALLVALUE: { - execute: opCallValue, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - CALLDATALOAD: { - execute: opCallDataLoad, - constantGas: GasFastestStep, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - }, - CALLDATASIZE: { - execute: opCallDataSize, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - CALLDATACOPY: { - execute: opCallDataCopy, - constantGas: GasFastestStep, - dynamicGas: gasCallDataCopy, - minStack: minStack(3, 0), - maxStack: maxStack(3, 0), - memorySize: memoryCallDataCopy, - }, - CODESIZE: { - execute: opCodeSize, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - CODECOPY: { - execute: opCodeCopy, - constantGas: GasFastestStep, - dynamicGas: gasCodeCopy, - minStack: minStack(3, 0), - maxStack: maxStack(3, 0), - memorySize: memoryCodeCopy, - }, - GASPRICE: { - execute: opGasprice, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - EXTCODESIZE: { - execute: opExtCodeSize, - constantGas: params.ExtcodeSizeGasFrontier, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - }, - EXTCODECOPY: { - execute: opExtCodeCopy, - constantGas: params.ExtcodeCopyBaseFrontier, - dynamicGas: gasExtCodeCopy, - minStack: minStack(4, 0), - maxStack: maxStack(4, 0), - memorySize: memoryExtCodeCopy, - }, - BLOCKHASH: { - execute: opBlockhash, - constantGas: GasExtStep, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - }, - COINBASE: { - execute: opCoinbase, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - TIMESTAMP: { - execute: opTimestamp, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - NUMBER: { - execute: opNumber, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - DIFFICULTY: { - execute: opDifficulty, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - GASLIMIT: { - execute: opGasLimit, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - POP: { - execute: opPop, - constantGas: GasQuickStep, - minStack: minStack(1, 0), - maxStack: maxStack(1, 0), - }, - MLOAD: { - execute: opMload, - constantGas: GasFastestStep, - dynamicGas: gasMLoad, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - memorySize: memoryMLoad, - }, - MSTORE: { - execute: opMstore, - constantGas: GasFastestStep, - dynamicGas: gasMStore, - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - memorySize: memoryMStore, - }, - MSTORE8: { - execute: opMstore8, - constantGas: GasFastestStep, - dynamicGas: gasMStore8, - memorySize: memoryMStore8, - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - }, - SLOAD: { - execute: opSload, - constantGas: params.SloadGasFrontier, - minStack: minStack(1, 1), - maxStack: maxStack(1, 1), - }, - SSTORE: { - execute: opSstore, - dynamicGas: gasSStore, - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - }, - JUMP: { - execute: opJump, - constantGas: GasMidStep, - minStack: minStack(1, 0), - maxStack: maxStack(1, 0), - }, - JUMPI: { - execute: opJumpi, - constantGas: GasSlowStep, - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - }, - PC: { - execute: opPc, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - MSIZE: { - execute: opMsize, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - GAS: { - execute: opGas, - constantGas: GasQuickStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - JUMPDEST: { - execute: opJumpdest, - constantGas: params.JumpdestGas, - minStack: minStack(0, 0), - maxStack: maxStack(0, 0), - }, - PUSH1: { - execute: opPush1, - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH2: { - execute: makePush(2, 2), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH3: { - execute: makePush(3, 3), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH4: { - execute: makePush(4, 4), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH5: { - execute: makePush(5, 5), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH6: { - execute: makePush(6, 6), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH7: { - execute: makePush(7, 7), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH8: { - execute: makePush(8, 8), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH9: { - execute: makePush(9, 9), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH10: { - execute: makePush(10, 10), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH11: { - execute: makePush(11, 11), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH12: { - execute: makePush(12, 12), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH13: { - execute: makePush(13, 13), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH14: { - execute: makePush(14, 14), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH15: { - execute: makePush(15, 15), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH16: { - execute: makePush(16, 16), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH17: { - execute: makePush(17, 17), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH18: { - execute: makePush(18, 18), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH19: { - execute: makePush(19, 19), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH20: { - execute: makePush(20, 20), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH21: { - execute: makePush(21, 21), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH22: { - execute: makePush(22, 22), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH23: { - execute: makePush(23, 23), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH24: { - execute: makePush(24, 24), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH25: { - execute: makePush(25, 25), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH26: { - execute: makePush(26, 26), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH27: { - execute: makePush(27, 27), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH28: { - execute: makePush(28, 28), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH29: { - execute: makePush(29, 29), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH30: { - execute: makePush(30, 30), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH31: { - execute: makePush(31, 31), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - PUSH32: { - execute: makePush(32, 32), - constantGas: GasFastestStep, - minStack: minStack(0, 1), - maxStack: maxStack(0, 1), - }, - DUP1: { - execute: makeDup(1), - constantGas: GasFastestStep, - minStack: minDupStack(1), - maxStack: maxDupStack(1), - }, - DUP2: { - execute: makeDup(2), - constantGas: GasFastestStep, - minStack: minDupStack(2), - maxStack: maxDupStack(2), - }, - DUP3: { - execute: makeDup(3), - constantGas: GasFastestStep, - minStack: minDupStack(3), - maxStack: maxDupStack(3), - }, - DUP4: { - execute: makeDup(4), - constantGas: GasFastestStep, - minStack: minDupStack(4), - maxStack: maxDupStack(4), - }, - DUP5: { - execute: makeDup(5), - constantGas: GasFastestStep, - minStack: minDupStack(5), - maxStack: maxDupStack(5), - }, - DUP6: { - execute: makeDup(6), - constantGas: GasFastestStep, - minStack: minDupStack(6), - maxStack: maxDupStack(6), - }, - DUP7: { - execute: makeDup(7), - constantGas: GasFastestStep, - minStack: minDupStack(7), - maxStack: maxDupStack(7), - }, - DUP8: { - execute: makeDup(8), - constantGas: GasFastestStep, - minStack: minDupStack(8), - maxStack: maxDupStack(8), - }, - DUP9: { - execute: makeDup(9), - constantGas: GasFastestStep, - minStack: minDupStack(9), - maxStack: maxDupStack(9), - }, - DUP10: { - execute: makeDup(10), - constantGas: GasFastestStep, - minStack: minDupStack(10), - maxStack: maxDupStack(10), - }, - DUP11: { - execute: makeDup(11), - constantGas: GasFastestStep, - minStack: minDupStack(11), - maxStack: maxDupStack(11), - }, - DUP12: { - execute: makeDup(12), - constantGas: GasFastestStep, - minStack: minDupStack(12), - maxStack: maxDupStack(12), - }, - DUP13: { - execute: makeDup(13), - constantGas: GasFastestStep, - minStack: minDupStack(13), - maxStack: maxDupStack(13), - }, - DUP14: { - execute: makeDup(14), - constantGas: GasFastestStep, - minStack: minDupStack(14), - maxStack: maxDupStack(14), - }, - DUP15: { - execute: makeDup(15), - constantGas: GasFastestStep, - minStack: minDupStack(15), - maxStack: maxDupStack(15), - }, - DUP16: { - execute: makeDup(16), - constantGas: GasFastestStep, - minStack: minDupStack(16), - maxStack: maxDupStack(16), - }, - SWAP1: { - execute: makeSwap(1), - constantGas: GasFastestStep, - minStack: minSwapStack(2), - maxStack: maxSwapStack(2), - }, - SWAP2: { - execute: makeSwap(2), - constantGas: GasFastestStep, - minStack: minSwapStack(3), - maxStack: maxSwapStack(3), - }, - SWAP3: { - execute: makeSwap(3), - constantGas: GasFastestStep, - minStack: minSwapStack(4), - maxStack: maxSwapStack(4), - }, - SWAP4: { - execute: makeSwap(4), - constantGas: GasFastestStep, - minStack: minSwapStack(5), - maxStack: maxSwapStack(5), - }, - SWAP5: { - execute: makeSwap(5), - constantGas: GasFastestStep, - minStack: minSwapStack(6), - maxStack: maxSwapStack(6), - }, - SWAP6: { - execute: makeSwap(6), - constantGas: GasFastestStep, - minStack: minSwapStack(7), - maxStack: maxSwapStack(7), - }, - SWAP7: { - execute: makeSwap(7), - constantGas: GasFastestStep, - minStack: minSwapStack(8), - maxStack: maxSwapStack(8), - }, - SWAP8: { - execute: makeSwap(8), - constantGas: GasFastestStep, - minStack: minSwapStack(9), - maxStack: maxSwapStack(9), - }, - SWAP9: { - execute: makeSwap(9), - constantGas: GasFastestStep, - minStack: minSwapStack(10), - maxStack: maxSwapStack(10), - }, - SWAP10: { - execute: makeSwap(10), - constantGas: GasFastestStep, - minStack: minSwapStack(11), - maxStack: maxSwapStack(11), - }, - SWAP11: { - execute: makeSwap(11), - constantGas: GasFastestStep, - minStack: minSwapStack(12), - maxStack: maxSwapStack(12), - }, - SWAP12: { - execute: makeSwap(12), - constantGas: GasFastestStep, - minStack: minSwapStack(13), - maxStack: maxSwapStack(13), - }, - SWAP13: { - execute: makeSwap(13), - constantGas: GasFastestStep, - minStack: minSwapStack(14), - maxStack: maxSwapStack(14), - }, - SWAP14: { - execute: makeSwap(14), - constantGas: GasFastestStep, - minStack: minSwapStack(15), - maxStack: maxSwapStack(15), - }, - SWAP15: { - execute: makeSwap(15), - constantGas: GasFastestStep, - minStack: minSwapStack(16), - maxStack: maxSwapStack(16), - }, - SWAP16: { - execute: makeSwap(16), - constantGas: GasFastestStep, - minStack: minSwapStack(17), - maxStack: maxSwapStack(17), - }, - LOG0: { - execute: makeLog(0), - dynamicGas: makeGasLog(0), - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - memorySize: memoryLog, - }, - LOG1: { - execute: makeLog(1), - dynamicGas: makeGasLog(1), - minStack: minStack(3, 0), - maxStack: maxStack(3, 0), - memorySize: memoryLog, - }, - LOG2: { - execute: makeLog(2), - dynamicGas: makeGasLog(2), - minStack: minStack(4, 0), - maxStack: maxStack(4, 0), - memorySize: memoryLog, - }, - LOG3: { - execute: makeLog(3), - dynamicGas: makeGasLog(3), - minStack: minStack(5, 0), - maxStack: maxStack(5, 0), - memorySize: memoryLog, - }, - LOG4: { - execute: makeLog(4), - dynamicGas: makeGasLog(4), - minStack: minStack(6, 0), - maxStack: maxStack(6, 0), - memorySize: memoryLog, - }, - CREATE: { - execute: opCreate, - constantGas: params.CreateGas, - dynamicGas: gasCreate, - minStack: minStack(3, 1), - maxStack: maxStack(3, 1), - memorySize: memoryCreate, - }, - CALL: { - execute: opCall, - constantGas: params.CallGasFrontier, - dynamicGas: gasCall, - minStack: minStack(7, 1), - maxStack: maxStack(7, 1), - memorySize: memoryCall, - }, - CALLCODE: { - execute: opCallCode, - constantGas: params.CallGasFrontier, - dynamicGas: gasCallCode, - minStack: minStack(7, 1), - maxStack: maxStack(7, 1), - memorySize: memoryCall, - }, - RETURN: { - execute: opReturn, - dynamicGas: gasReturn, - minStack: minStack(2, 0), - maxStack: maxStack(2, 0), - memorySize: memoryReturn, - }, - SELFDESTRUCT: { - execute: opSelfdestruct, - dynamicGas: gasSelfdestruct, - minStack: minStack(1, 0), - maxStack: maxStack(1, 0), - }, - } - - // Fill all unassigned slots with opUndefined. - for i, entry := range tbl { - if entry == nil { - tbl[i] = &operation{execute: opUndefined, maxStack: maxStack(0, 0)} - } - } - - return validate(tbl) -} - -func copyJumpTable(source *JumpTable) *JumpTable { - dest := *source - for i, op := range source { - if op != nil { - opCopy := *op - dest[i] = &opCopy - } - } - return &dest -} diff --git a/core/vm/jump_table_export.go b/core/vm/jump_table_export.go deleted file mode 100644 index cb57e20b1b..0000000000 --- a/core/vm/jump_table_export.go +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "github.com/ava-labs/coreth/params" -) - -// LookupInstructionSet returns the instruction set for the fork configured by -// the rules. -func LookupInstructionSet(rules params.Rules) (JumpTable, error) { - switch { - case rules.IsCancun: - return newCancunInstructionSet(), nil - case rules.IsDurango: - return newDurangoInstructionSet(), nil - case rules.IsApricotPhase3, rules.IsApricotPhase4, - rules.IsApricotPhase5, rules.IsApricotPhasePre6, - rules.IsApricotPhase6, rules.IsApricotPhasePost6, - rules.IsBanff, rules.IsCortina: - return newApricotPhase3InstructionSet(), nil - case rules.IsApricotPhase2: - return newApricotPhase2InstructionSet(), nil - case rules.IsApricotPhase1: - return newApricotPhase1InstructionSet(), nil - case rules.IsIstanbul: - return newIstanbulInstructionSet(), nil - case rules.IsConstantinople: - return newConstantinopleInstructionSet(), nil - case rules.IsByzantium: - return newByzantiumInstructionSet(), nil - case rules.IsEIP158: - return newSpuriousDragonInstructionSet(), nil - case rules.IsEIP150: - return newTangerineWhistleInstructionSet(), nil - case rules.IsHomestead: - return newHomesteadInstructionSet(), nil - } - return newFrontierInstructionSet(), nil -} - -// Stack returns the minimum and maximum stack requirements. -func (op *operation) Stack() (int, int) { - return op.minStack, op.maxStack -} - -// HasCost returns true if the opcode has a cost. Opcodes which do _not_ have -// a cost assigned are one of two things: -// - undefined, a.k.a invalid opcodes, -// - the STOP opcode. -// This method can thus be used to check if an opcode is "Invalid (or STOP)". -func (op *operation) HasCost() bool { - // Ideally, we'd check this: - // return op.execute == opUndefined - // However, go-lang does now allow that. So we'll just check some other - // 'indicators' that this is an invalid op. Alas, STOP is impossible to - // filter out - return op.dynamicGas != nil || op.constantGas != 0 -} diff --git a/core/vm/jump_table_test.go b/core/vm/jump_table_test.go deleted file mode 100644 index 5fa9a532cb..0000000000 --- a/core/vm/jump_table_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -// TestJumpTableCopy tests that deep copy is necessary to prevent modify shared jump table -func TestJumpTableCopy(t *testing.T) { - tbl := newDurangoInstructionSet() - require.Equal(t, uint64(0), tbl[SLOAD].constantGas) - - // a deep copy won't modify the shared jump table - deepCopy := copyJumpTable(&tbl) - deepCopy[SLOAD].constantGas = 100 - require.Equal(t, uint64(100), deepCopy[SLOAD].constantGas) - require.Equal(t, uint64(0), tbl[SLOAD].constantGas) -} diff --git a/core/vm/logger.go b/core/vm/logger.go deleted file mode 100644 index 397aff7077..0000000000 --- a/core/vm/logger.go +++ /dev/null @@ -1,53 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/common" -) - -// EVMLogger is used to collect execution traces from an EVM transaction -// execution. CaptureState is called for each step of the VM with the -// current VM state. -// Note that reference types are actual VM data structures; make copies -// if you need to retain them beyond the current call. -type EVMLogger interface { - // Transaction level - CaptureTxStart(gasLimit uint64) - CaptureTxEnd(restGas uint64) - // Top call frame - CaptureStart(env *EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) - CaptureEnd(output []byte, gasUsed uint64, err error) - // Rest of call frames - CaptureEnter(typ OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) - CaptureExit(output []byte, gasUsed uint64, err error) - // Opcode level - CaptureState(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) - CaptureFault(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, depth int, err error) -} diff --git a/core/vm/memory.go b/core/vm/memory.go deleted file mode 100644 index 259b7bf463..0000000000 --- a/core/vm/memory.go +++ /dev/null @@ -1,126 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "github.com/holiman/uint256" -) - -// Memory implements a simple memory model for the ethereum virtual machine. -type Memory struct { - store []byte - lastGasCost uint64 -} - -// NewMemory returns a new memory model. -func NewMemory() *Memory { - return &Memory{} -} - -// Set sets offset + size to value -func (m *Memory) Set(offset, size uint64, value []byte) { - // It's possible the offset is greater than 0 and size equals 0. This is because - // the calcMemSize (common.go) could potentially return 0 when size is zero (NO-OP) - if size > 0 { - // length of store may never be less than offset + size. - // The store should be resized PRIOR to setting the memory - if offset+size > uint64(len(m.store)) { - panic("invalid memory: store empty") - } - copy(m.store[offset:offset+size], value) - } -} - -// Set32 sets the 32 bytes starting at offset to the value of val, left-padded with zeroes to -// 32 bytes. -func (m *Memory) Set32(offset uint64, val *uint256.Int) { - // length of store may never be less than offset + size. - // The store should be resized PRIOR to setting the memory - if offset+32 > uint64(len(m.store)) { - panic("invalid memory: store empty") - } - // Fill in relevant bits - b32 := val.Bytes32() - copy(m.store[offset:], b32[:]) -} - -// Resize resizes the memory to size -func (m *Memory) Resize(size uint64) { - if uint64(m.Len()) < size { - m.store = append(m.store, make([]byte, size-uint64(m.Len()))...) - } -} - -// GetCopy returns offset + size as a new slice -func (m *Memory) GetCopy(offset, size int64) (cpy []byte) { - if size == 0 { - return nil - } - - if len(m.store) > int(offset) { - cpy = make([]byte, size) - copy(cpy, m.store[offset:offset+size]) - - return - } - - return -} - -// GetPtr returns the offset + size -func (m *Memory) GetPtr(offset, size int64) []byte { - if size == 0 { - return nil - } - - if len(m.store) > int(offset) { - return m.store[offset : offset+size] - } - - return nil -} - -// Len returns the length of the backing slice -func (m *Memory) Len() int { - return len(m.store) -} - -// Data returns the backing slice -func (m *Memory) Data() []byte { - return m.store -} - -// Copy copies data from the src position slice into the dst position. -// The source and destination may overlap. -// OBS: This operation assumes that any necessary memory expansion has already been performed, -// and this method may panic otherwise. -func (m *Memory) Copy(dst, src, len uint64) { - if len == 0 { - return - } - copy(m.store[dst:], m.store[src:src+len]) -} diff --git a/core/vm/memory_table.go b/core/vm/memory_table.go deleted file mode 100644 index 276e1bd2a3..0000000000 --- a/core/vm/memory_table.go +++ /dev/null @@ -1,132 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -func memoryKeccak256(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(0), stack.Back(1)) -} - -func memoryCallDataCopy(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(0), stack.Back(2)) -} - -func memoryReturnDataCopy(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(0), stack.Back(2)) -} - -func memoryCodeCopy(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(0), stack.Back(2)) -} - -func memoryExtCodeCopy(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(1), stack.Back(3)) -} - -func memoryMLoad(stack *Stack) (uint64, bool) { - return calcMemSize64WithUint(stack.Back(0), 32) -} - -func memoryMStore8(stack *Stack) (uint64, bool) { - return calcMemSize64WithUint(stack.Back(0), 1) -} - -func memoryMStore(stack *Stack) (uint64, bool) { - return calcMemSize64WithUint(stack.Back(0), 32) -} - -func memoryMcopy(stack *Stack) (uint64, bool) { - mStart := stack.Back(0) // stack[0]: dest - if stack.Back(1).Gt(mStart) { - mStart = stack.Back(1) // stack[1]: source - } - return calcMemSize64(mStart, stack.Back(2)) // stack[2]: length -} - -func memoryCreate(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(1), stack.Back(2)) -} - -func memoryCreate2(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(1), stack.Back(2)) -} - -func memoryCall(stack *Stack) (uint64, bool) { - x, overflow := calcMemSize64(stack.Back(5), stack.Back(6)) - if overflow { - return 0, true - } - y, overflow := calcMemSize64(stack.Back(3), stack.Back(4)) - if overflow { - return 0, true - } - if x > y { - return x, false - } - return y, false -} - -func memoryDelegateCall(stack *Stack) (uint64, bool) { - x, overflow := calcMemSize64(stack.Back(4), stack.Back(5)) - if overflow { - return 0, true - } - y, overflow := calcMemSize64(stack.Back(2), stack.Back(3)) - if overflow { - return 0, true - } - if x > y { - return x, false - } - return y, false -} - -func memoryStaticCall(stack *Stack) (uint64, bool) { - x, overflow := calcMemSize64(stack.Back(4), stack.Back(5)) - if overflow { - return 0, true - } - y, overflow := calcMemSize64(stack.Back(2), stack.Back(3)) - if overflow { - return 0, true - } - if x > y { - return x, false - } - return y, false -} - -func memoryReturn(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(0), stack.Back(1)) -} - -func memoryRevert(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(0), stack.Back(1)) -} - -func memoryLog(stack *Stack) (uint64, bool) { - return calcMemSize64(stack.Back(0), stack.Back(1)) -} diff --git a/core/vm/memory_test.go b/core/vm/memory_test.go deleted file mode 100644 index ba36f8023c..0000000000 --- a/core/vm/memory_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package vm - -import ( - "bytes" - "strings" - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func TestMemoryCopy(t *testing.T) { - // Test cases from https://eips.ethereum.org/EIPS/eip-5656#test-cases - for i, tc := range []struct { - dst, src, len uint64 - pre string - want string - }{ - { // MCOPY 0 32 32 - copy 32 bytes from offset 32 to offset 0. - 0, 32, 32, - "0000000000000000000000000000000000000000000000000000000000000000 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", - "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", - }, - - { // MCOPY 0 0 32 - copy 32 bytes from offset 0 to offset 0. - 0, 0, 32, - "0101010101010101010101010101010101010101010101010101010101010101", - "0101010101010101010101010101010101010101010101010101010101010101", - }, - { // MCOPY 0 1 8 - copy 8 bytes from offset 1 to offset 0 (overlapping). - 0, 1, 8, - "000102030405060708 000000000000000000000000000000000000000000000000", - "010203040506070808 000000000000000000000000000000000000000000000000", - }, - { // MCOPY 1 0 8 - copy 8 bytes from offset 0 to offset 1 (overlapping). - 1, 0, 8, - "000102030405060708 000000000000000000000000000000000000000000000000", - "000001020304050607 000000000000000000000000000000000000000000000000", - }, - // Tests below are not in the EIP, but maybe should be added - { // MCOPY 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds index(overlapping). - 0xFFFFFFFFFFFF, 0xFFFFFFFFFFFF, 0, - "11", - "11", - }, - { // MCOPY 0xFFFFFFFFFFFF 0 0 - copy zero bytes from start of mem to out-of-bounds. - 0xFFFFFFFFFFFF, 0, 0, - "11", - "11", - }, - { // MCOPY 0 0xFFFFFFFFFFFF 0 - copy zero bytes from out-of-bounds to start of mem - 0, 0xFFFFFFFFFFFF, 0, - "11", - "11", - }, - } { - m := NewMemory() - // Clean spaces - data := common.FromHex(strings.ReplaceAll(tc.pre, " ", "")) - // Set pre - m.Resize(uint64(len(data))) - m.Set(0, uint64(len(data)), data) - // Do the copy - m.Copy(tc.dst, tc.src, tc.len) - want := common.FromHex(strings.ReplaceAll(tc.want, " ", "")) - if have := m.store; !bytes.Equal(want, have) { - t.Errorf("case %d: want: %#x\nhave: %#x\n", i, want, have) - } - } -} diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go deleted file mode 100644 index c4e99b0669..0000000000 --- a/core/vm/opcodes.go +++ /dev/null @@ -1,570 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "fmt" -) - -// OpCode is an EVM opcode -type OpCode byte - -// IsPush specifies if an opcode is a PUSH opcode. -func (op OpCode) IsPush() bool { - return PUSH0 <= op && op <= PUSH32 -} - -// 0x0 range - arithmetic ops. -const ( - STOP OpCode = 0x0 - ADD OpCode = 0x1 - MUL OpCode = 0x2 - SUB OpCode = 0x3 - DIV OpCode = 0x4 - SDIV OpCode = 0x5 - MOD OpCode = 0x6 - SMOD OpCode = 0x7 - ADDMOD OpCode = 0x8 - MULMOD OpCode = 0x9 - EXP OpCode = 0xa - SIGNEXTEND OpCode = 0xb -) - -// 0x10 range - comparison ops. -const ( - LT OpCode = 0x10 - GT OpCode = 0x11 - SLT OpCode = 0x12 - SGT OpCode = 0x13 - EQ OpCode = 0x14 - ISZERO OpCode = 0x15 - AND OpCode = 0x16 - OR OpCode = 0x17 - XOR OpCode = 0x18 - NOT OpCode = 0x19 - BYTE OpCode = 0x1a - SHL OpCode = 0x1b - SHR OpCode = 0x1c - SAR OpCode = 0x1d -) - -// 0x20 range - crypto. -const ( - KECCAK256 OpCode = 0x20 -) - -// 0x30 range - closure state. -const ( - ADDRESS OpCode = 0x30 - BALANCE OpCode = 0x31 - ORIGIN OpCode = 0x32 - CALLER OpCode = 0x33 - CALLVALUE OpCode = 0x34 - CALLDATALOAD OpCode = 0x35 - CALLDATASIZE OpCode = 0x36 - CALLDATACOPY OpCode = 0x37 - CODESIZE OpCode = 0x38 - CODECOPY OpCode = 0x39 - GASPRICE OpCode = 0x3a - EXTCODESIZE OpCode = 0x3b - EXTCODECOPY OpCode = 0x3c - RETURNDATASIZE OpCode = 0x3d - RETURNDATACOPY OpCode = 0x3e - EXTCODEHASH OpCode = 0x3f -) - -// 0x40 range - block operations. -const ( - BLOCKHASH OpCode = 0x40 - COINBASE OpCode = 0x41 - TIMESTAMP OpCode = 0x42 - NUMBER OpCode = 0x43 - DIFFICULTY OpCode = 0x44 - GASLIMIT OpCode = 0x45 - CHAINID OpCode = 0x46 - SELFBALANCE OpCode = 0x47 - BASEFEE OpCode = 0x48 - BLOBHASH OpCode = 0x49 - BLOBBASEFEE OpCode = 0x4a -) - -// 0x50 range - 'storage' and execution. -const ( - POP OpCode = 0x50 - MLOAD OpCode = 0x51 - MSTORE OpCode = 0x52 - MSTORE8 OpCode = 0x53 - SLOAD OpCode = 0x54 - SSTORE OpCode = 0x55 - JUMP OpCode = 0x56 - JUMPI OpCode = 0x57 - PC OpCode = 0x58 - MSIZE OpCode = 0x59 - GAS OpCode = 0x5a - JUMPDEST OpCode = 0x5b - TLOAD OpCode = 0x5c - TSTORE OpCode = 0x5d - MCOPY OpCode = 0x5e - PUSH0 OpCode = 0x5f -) - -// 0x60 range - pushes. -const ( - PUSH1 OpCode = 0x60 + iota - PUSH2 - PUSH3 - PUSH4 - PUSH5 - PUSH6 - PUSH7 - PUSH8 - PUSH9 - PUSH10 - PUSH11 - PUSH12 - PUSH13 - PUSH14 - PUSH15 - PUSH16 - PUSH17 - PUSH18 - PUSH19 - PUSH20 - PUSH21 - PUSH22 - PUSH23 - PUSH24 - PUSH25 - PUSH26 - PUSH27 - PUSH28 - PUSH29 - PUSH30 - PUSH31 - PUSH32 -) - -// 0x80 range - dups. -const ( - DUP1 = 0x80 + iota - DUP2 - DUP3 - DUP4 - DUP5 - DUP6 - DUP7 - DUP8 - DUP9 - DUP10 - DUP11 - DUP12 - DUP13 - DUP14 - DUP15 - DUP16 -) - -// 0x90 range - swaps. -const ( - SWAP1 = 0x90 + iota - SWAP2 - SWAP3 - SWAP4 - SWAP5 - SWAP6 - SWAP7 - SWAP8 - SWAP9 - SWAP10 - SWAP11 - SWAP12 - SWAP13 - SWAP14 - SWAP15 - SWAP16 -) - -// 0xa0 range - logging ops. -const ( - LOG0 OpCode = 0xa0 + iota - LOG1 - LOG2 - LOG3 - LOG4 -) - -// 0xf0 range - closures. -const ( - CREATE OpCode = 0xf0 - CALL OpCode = 0xf1 - CALLCODE OpCode = 0xf2 - RETURN OpCode = 0xf3 - DELEGATECALL OpCode = 0xf4 - CREATE2 OpCode = 0xf5 - - STATICCALL OpCode = 0xfa - REVERT OpCode = 0xfd - INVALID OpCode = 0xfe - SELFDESTRUCT OpCode = 0xff -) - -var opCodeToString = [256]string{ - // 0x0 range - arithmetic ops. - STOP: "STOP", - ADD: "ADD", - MUL: "MUL", - SUB: "SUB", - DIV: "DIV", - SDIV: "SDIV", - MOD: "MOD", - SMOD: "SMOD", - EXP: "EXP", - NOT: "NOT", - LT: "LT", - GT: "GT", - SLT: "SLT", - SGT: "SGT", - EQ: "EQ", - ISZERO: "ISZERO", - SIGNEXTEND: "SIGNEXTEND", - - // 0x10 range - bit ops. - AND: "AND", - OR: "OR", - XOR: "XOR", - BYTE: "BYTE", - SHL: "SHL", - SHR: "SHR", - SAR: "SAR", - ADDMOD: "ADDMOD", - MULMOD: "MULMOD", - - // 0x20 range - crypto. - KECCAK256: "KECCAK256", - - // 0x30 range - closure state. - ADDRESS: "ADDRESS", - BALANCE: "BALANCE", - ORIGIN: "ORIGIN", - CALLER: "CALLER", - CALLVALUE: "CALLVALUE", - CALLDATALOAD: "CALLDATALOAD", - CALLDATASIZE: "CALLDATASIZE", - CALLDATACOPY: "CALLDATACOPY", - CODESIZE: "CODESIZE", - CODECOPY: "CODECOPY", - GASPRICE: "GASPRICE", - EXTCODESIZE: "EXTCODESIZE", - EXTCODECOPY: "EXTCODECOPY", - RETURNDATASIZE: "RETURNDATASIZE", - RETURNDATACOPY: "RETURNDATACOPY", - EXTCODEHASH: "EXTCODEHASH", - - // 0x40 range - block operations. - BLOCKHASH: "BLOCKHASH", - COINBASE: "COINBASE", - TIMESTAMP: "TIMESTAMP", - NUMBER: "NUMBER", - DIFFICULTY: "DIFFICULTY", - GASLIMIT: "GASLIMIT", - CHAINID: "CHAINID", - SELFBALANCE: "SELFBALANCE", - BASEFEE: "BASEFEE", - BLOBHASH: "BLOBHASH", - BLOBBASEFEE: "BLOBBASEFEE", - - // 0x50 range - 'storage' and execution. - POP: "POP", - MLOAD: "MLOAD", - MSTORE: "MSTORE", - MSTORE8: "MSTORE8", - SLOAD: "SLOAD", - SSTORE: "SSTORE", - JUMP: "JUMP", - JUMPI: "JUMPI", - PC: "PC", - MSIZE: "MSIZE", - GAS: "GAS", - JUMPDEST: "JUMPDEST", - TLOAD: "TLOAD", - TSTORE: "TSTORE", - MCOPY: "MCOPY", - PUSH0: "PUSH0", - - // 0x60 range - pushes. - PUSH1: "PUSH1", - PUSH2: "PUSH2", - PUSH3: "PUSH3", - PUSH4: "PUSH4", - PUSH5: "PUSH5", - PUSH6: "PUSH6", - PUSH7: "PUSH7", - PUSH8: "PUSH8", - PUSH9: "PUSH9", - PUSH10: "PUSH10", - PUSH11: "PUSH11", - PUSH12: "PUSH12", - PUSH13: "PUSH13", - PUSH14: "PUSH14", - PUSH15: "PUSH15", - PUSH16: "PUSH16", - PUSH17: "PUSH17", - PUSH18: "PUSH18", - PUSH19: "PUSH19", - PUSH20: "PUSH20", - PUSH21: "PUSH21", - PUSH22: "PUSH22", - PUSH23: "PUSH23", - PUSH24: "PUSH24", - PUSH25: "PUSH25", - PUSH26: "PUSH26", - PUSH27: "PUSH27", - PUSH28: "PUSH28", - PUSH29: "PUSH29", - PUSH30: "PUSH30", - PUSH31: "PUSH31", - PUSH32: "PUSH32", - - // 0x80 - dups. - DUP1: "DUP1", - DUP2: "DUP2", - DUP3: "DUP3", - DUP4: "DUP4", - DUP5: "DUP5", - DUP6: "DUP6", - DUP7: "DUP7", - DUP8: "DUP8", - DUP9: "DUP9", - DUP10: "DUP10", - DUP11: "DUP11", - DUP12: "DUP12", - DUP13: "DUP13", - DUP14: "DUP14", - DUP15: "DUP15", - DUP16: "DUP16", - - // 0x90 - swaps. - SWAP1: "SWAP1", - SWAP2: "SWAP2", - SWAP3: "SWAP3", - SWAP4: "SWAP4", - SWAP5: "SWAP5", - SWAP6: "SWAP6", - SWAP7: "SWAP7", - SWAP8: "SWAP8", - SWAP9: "SWAP9", - SWAP10: "SWAP10", - SWAP11: "SWAP11", - SWAP12: "SWAP12", - SWAP13: "SWAP13", - SWAP14: "SWAP14", - SWAP15: "SWAP15", - SWAP16: "SWAP16", - - // 0xa0 range - logging ops. - LOG0: "LOG0", - LOG1: "LOG1", - LOG2: "LOG2", - LOG3: "LOG3", - LOG4: "LOG4", - - // 0xf0 range - closures. - CREATE: "CREATE", - CALL: "CALL", - RETURN: "RETURN", - CALLCODE: "CALLCODE", - DELEGATECALL: "DELEGATECALL", - CREATE2: "CREATE2", - STATICCALL: "STATICCALL", - REVERT: "REVERT", - INVALID: "INVALID", - SELFDESTRUCT: "SELFDESTRUCT", -} - -func (op OpCode) String() string { - if s := opCodeToString[op]; s != "" { - return s - } - return fmt.Sprintf("opcode %#x not defined", int(op)) -} - -var stringToOp = map[string]OpCode{ - "STOP": STOP, - "ADD": ADD, - "MUL": MUL, - "SUB": SUB, - "DIV": DIV, - "SDIV": SDIV, - "MOD": MOD, - "SMOD": SMOD, - "EXP": EXP, - "NOT": NOT, - "LT": LT, - "GT": GT, - "SLT": SLT, - "SGT": SGT, - "EQ": EQ, - "ISZERO": ISZERO, - "SIGNEXTEND": SIGNEXTEND, - "AND": AND, - "OR": OR, - "XOR": XOR, - "BYTE": BYTE, - "SHL": SHL, - "SHR": SHR, - "SAR": SAR, - "ADDMOD": ADDMOD, - "MULMOD": MULMOD, - "KECCAK256": KECCAK256, - "ADDRESS": ADDRESS, - "BALANCE": BALANCE, - "ORIGIN": ORIGIN, - "CALLER": CALLER, - "CALLVALUE": CALLVALUE, - "CALLDATALOAD": CALLDATALOAD, - "CALLDATASIZE": CALLDATASIZE, - "CALLDATACOPY": CALLDATACOPY, - "CHAINID": CHAINID, - "BASEFEE": BASEFEE, - "BLOBHASH": BLOBHASH, - "BLOBBASEFEE": BLOBBASEFEE, - "DELEGATECALL": DELEGATECALL, - "STATICCALL": STATICCALL, - "CODESIZE": CODESIZE, - "CODECOPY": CODECOPY, - "GASPRICE": GASPRICE, - "EXTCODESIZE": EXTCODESIZE, - "EXTCODECOPY": EXTCODECOPY, - "RETURNDATASIZE": RETURNDATASIZE, - "RETURNDATACOPY": RETURNDATACOPY, - "EXTCODEHASH": EXTCODEHASH, - "BLOCKHASH": BLOCKHASH, - "COINBASE": COINBASE, - "TIMESTAMP": TIMESTAMP, - "NUMBER": NUMBER, - "DIFFICULTY": DIFFICULTY, - "GASLIMIT": GASLIMIT, - "SELFBALANCE": SELFBALANCE, - "POP": POP, - "MLOAD": MLOAD, - "MSTORE": MSTORE, - "MSTORE8": MSTORE8, - "SLOAD": SLOAD, - "SSTORE": SSTORE, - "JUMP": JUMP, - "JUMPI": JUMPI, - "PC": PC, - "MSIZE": MSIZE, - "GAS": GAS, - "JUMPDEST": JUMPDEST, - "TLOAD": TLOAD, - "TSTORE": TSTORE, - "MCOPY": MCOPY, - "PUSH0": PUSH0, - "PUSH1": PUSH1, - "PUSH2": PUSH2, - "PUSH3": PUSH3, - "PUSH4": PUSH4, - "PUSH5": PUSH5, - "PUSH6": PUSH6, - "PUSH7": PUSH7, - "PUSH8": PUSH8, - "PUSH9": PUSH9, - "PUSH10": PUSH10, - "PUSH11": PUSH11, - "PUSH12": PUSH12, - "PUSH13": PUSH13, - "PUSH14": PUSH14, - "PUSH15": PUSH15, - "PUSH16": PUSH16, - "PUSH17": PUSH17, - "PUSH18": PUSH18, - "PUSH19": PUSH19, - "PUSH20": PUSH20, - "PUSH21": PUSH21, - "PUSH22": PUSH22, - "PUSH23": PUSH23, - "PUSH24": PUSH24, - "PUSH25": PUSH25, - "PUSH26": PUSH26, - "PUSH27": PUSH27, - "PUSH28": PUSH28, - "PUSH29": PUSH29, - "PUSH30": PUSH30, - "PUSH31": PUSH31, - "PUSH32": PUSH32, - "DUP1": DUP1, - "DUP2": DUP2, - "DUP3": DUP3, - "DUP4": DUP4, - "DUP5": DUP5, - "DUP6": DUP6, - "DUP7": DUP7, - "DUP8": DUP8, - "DUP9": DUP9, - "DUP10": DUP10, - "DUP11": DUP11, - "DUP12": DUP12, - "DUP13": DUP13, - "DUP14": DUP14, - "DUP15": DUP15, - "DUP16": DUP16, - "SWAP1": SWAP1, - "SWAP2": SWAP2, - "SWAP3": SWAP3, - "SWAP4": SWAP4, - "SWAP5": SWAP5, - "SWAP6": SWAP6, - "SWAP7": SWAP7, - "SWAP8": SWAP8, - "SWAP9": SWAP9, - "SWAP10": SWAP10, - "SWAP11": SWAP11, - "SWAP12": SWAP12, - "SWAP13": SWAP13, - "SWAP14": SWAP14, - "SWAP15": SWAP15, - "SWAP16": SWAP16, - "LOG0": LOG0, - "LOG1": LOG1, - "LOG2": LOG2, - "LOG3": LOG3, - "LOG4": LOG4, - "CREATE": CREATE, - "CREATE2": CREATE2, - "CALL": CALL, - "RETURN": RETURN, - "CALLCODE": CALLCODE, - "REVERT": REVERT, - "INVALID": INVALID, - "SELFDESTRUCT": SELFDESTRUCT, -} - -// StringToOp finds the opcode whose name is stored in `str`. -func StringToOp(str string) OpCode { - return stringToOp[str] -} diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go deleted file mode 100644 index 3cc56ef8be..0000000000 --- a/core/vm/operations_acl.go +++ /dev/null @@ -1,232 +0,0 @@ -// (c) 2019-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "errors" - - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" -) - -func makeGasSStoreFunc() gasFunc { - return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - // If we fail the minimum gas availability invariant, fail (0) - if contract.Gas <= params.SstoreSentryGasEIP2200 { - return 0, errors.New("not enough gas for reentrancy sentry") - } - // Gas sentry honoured, do the actual gas calculation based on the stored value - var ( - y, x = stack.Back(1), stack.peek() - slot = common.Hash(x.Bytes32()) - current = evm.StateDB.GetState(contract.Address(), slot) - cost = uint64(0) - ) - // Check slot presence in the access list - if addrPresent, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent { - cost = params.ColdSloadCostEIP2929 - // If the caller cannot afford the cost, this change will be rolled back - evm.StateDB.AddSlotToAccessList(contract.Address(), slot) - if !addrPresent { - // Once we're done with YOLOv2 and schedule this for mainnet, might - // be good to remove this panic here, which is just really a - // canary to have during testing - panic("impossible case: address was not present in access list during sstore op") - } - } - value := common.Hash(y.Bytes32()) - - if current == value { // noop (1) - // EIP 2200 original clause: - // return params.SloadGasEIP2200, nil - return cost + params.WarmStorageReadCostEIP2929, nil // SLOAD_GAS - } - original := evm.StateDB.GetCommittedStateAP1(contract.Address(), x.Bytes32()) - if original == current { - if original == (common.Hash{}) { // create slot (2.1.1) - return cost + params.SstoreSetGasEIP2200, nil - } - // EIP-2200 original clause: - // return params.SstoreResetGasEIP2200, nil // write existing slot (2.1.2) - return cost + (params.SstoreResetGasEIP2200 - params.ColdSloadCostEIP2929), nil // write existing slot (2.1.2) - } - - // EIP-2200 original clause: - //return params.SloadGasEIP2200, nil // dirty update (2.2) - return cost + params.WarmStorageReadCostEIP2929, nil // dirty update (2.2) - } -} - -// gasSLoadEIP2929 calculates dynamic gas for SLOAD according to EIP-2929 -// For SLOAD, if the (address, storage_key) pair (where address is the address of the contract -// whose storage is being read) is not yet in accessed_storage_keys, -// charge 2100 gas and add the pair to accessed_storage_keys. -// If the pair is already in accessed_storage_keys, charge 100 gas. -func gasSLoadEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - loc := stack.peek() - slot := common.Hash(loc.Bytes32()) - // Check slot presence in the access list - if _, slotPresent := evm.StateDB.SlotInAccessList(contract.Address(), slot); !slotPresent { - // If the caller cannot afford the cost, this change will be rolled back - // If he does afford it, we can skip checking the same thing later on, during execution - evm.StateDB.AddSlotToAccessList(contract.Address(), slot) - return params.ColdSloadCostEIP2929, nil - } - return params.WarmStorageReadCostEIP2929, nil -} - -// gasExtCodeCopyEIP2929 implements extcodecopy according to EIP-2929 -// EIP spec: -// > If the target is not in accessed_addresses, -// > charge COLD_ACCOUNT_ACCESS_COST gas, and add the address to accessed_addresses. -// > Otherwise, charge WARM_STORAGE_READ_COST gas. -func gasExtCodeCopyEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - // memory expansion first (dynamic part of pre-2929 implementation) - gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize) - if err != nil { - return 0, err - } - addr := common.Address(stack.peek().Bytes20()) - // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(addr) { - evm.StateDB.AddAddressToAccessList(addr) - var overflow bool - // We charge (cold-warm), since 'warm' is already charged as constantGas - if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929-params.WarmStorageReadCostEIP2929); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil - } - return gas, nil -} - -// gasEip2929AccountCheck checks whether the first stack item (as address) is present in the access list. -// If it is, this method returns '0', otherwise 'cold-warm' gas, presuming that the opcode using it -// is also using 'warm' as constant factor. -// This method is used by: -// - extcodehash, -// - extcodesize, -// - (ext) balance -func gasEip2929AccountCheck(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - addr := common.Address(stack.peek().Bytes20()) - // Check slot presence in the access list - if !evm.StateDB.AddressInAccessList(addr) { - // If the caller cannot afford the cost, this change will be rolled back - evm.StateDB.AddAddressToAccessList(addr) - // The warm storage read cost is already charged as constantGas - return params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929, nil - } - return 0, nil -} - -func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc { - return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - addr := common.Address(stack.Back(1).Bytes20()) - // Check slot presence in the access list - warmAccess := evm.StateDB.AddressInAccessList(addr) - // The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so - // the cost to charge for cold access, if any, is Cold - Warm - coldCost := params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929 - if !warmAccess { - evm.StateDB.AddAddressToAccessList(addr) - // Charge the remaining difference here already, to correctly calculate available - // gas for call - if !contract.UseGas(coldCost) { - return 0, vmerrs.ErrOutOfGas - } - } - // Now call the old calculator, which takes into account - // - create new account - // - transfer value - // - memory expansion - // - 63/64ths rule - gas, err := oldCalculator(evm, contract, stack, mem, memorySize) - if warmAccess || err != nil { - return gas, err - } - // In case of a cold access, we temporarily add the cold charge back, and also - // add it to the returned gas. By adding it to the return, it will be charged - // outside of this function, as part of the dynamic gas, and that will make it - // also become correctly reported to tracers. - contract.Gas += coldCost - - var overflow bool - if gas, overflow = math.SafeAdd(gas, coldCost); overflow { - return 0, vmerrs.ErrGasUintOverflow - } - return gas, nil - } -} - -var ( - gasCallEIP2929 = makeCallVariantGasCallEIP2929(gasCall) - gasDelegateCallEIP2929 = makeCallVariantGasCallEIP2929(gasDelegateCall) - gasStaticCallEIP2929 = makeCallVariantGasCallEIP2929(gasStaticCall) - gasCallCodeEIP2929 = makeCallVariantGasCallEIP2929(gasCallCode) - gasSelfdestructEIP2929 = makeSelfdestructGasFn(false) // Note: refunds were never enabled on Avalanche - // gasSelfdestructEIP3529 implements the changes in EIP-3529 (no refunds) - gasSelfdestructEIP3529 = makeSelfdestructGasFn(false) - // gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929 - // - // When calling SSTORE, check if the (address, storage_key) pair is in accessed_storage_keys. - // If it is not, charge an additional COLD_SLOAD_COST gas, and add the pair to accessed_storage_keys. - // Additionally, modify the parameters defined in EIP 2200 as follows: - // - // Parameter Old value New value - // SLOAD_GAS 800 = WARM_STORAGE_READ_COST - // SSTORE_RESET_GAS 5000 5000 - COLD_SLOAD_COST - // - //The other parameters defined in EIP 2200 are unchanged. - // see gasSStoreEIP2200(...) in core/vm/gas_table.go for more info about how EIP 2200 is specified - gasSStoreEIP2929 = makeGasSStoreFunc() -) - -// makeSelfdestructGasFn can create the selfdestruct dynamic gas function for EIP-2929 and EIP-3529 -func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { - gasFunc := func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { - var ( - gas uint64 - address = common.Address(stack.peek().Bytes20()) - ) - if !evm.StateDB.AddressInAccessList(address) { - // If the caller cannot afford the cost, this change will be rolled back - evm.StateDB.AddAddressToAccessList(address) - gas = params.ColdAccountAccessCostEIP2929 - } - // if empty and transfers value - if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { - gas += params.CreateBySelfdestructGas - } - if refundsEnabled && !evm.StateDB.HasSelfDestructed(contract.Address()) { - evm.StateDB.AddRefund(params.SelfdestructRefundGas) - } - return gas, nil - } - return gasFunc -} diff --git a/core/vm/runtime/env.go b/core/vm/runtime/env.go index 41fa4f54d3..a59d623b79 100644 --- a/core/vm/runtime/env.go +++ b/core/vm/runtime/env.go @@ -28,7 +28,7 @@ package runtime import ( "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/vm" + "github.com/ava-labs/libevm/core/vm" ) func NewEnv(cfg *Config) *vm.EVM { @@ -39,18 +39,17 @@ func NewEnv(cfg *Config) *vm.EVM { BlobFeeCap: cfg.BlobFeeCap, } blockContext := vm.BlockContext{ - CanTransfer: core.CanTransfer, - CanTransferMC: core.CanTransferMC, - Transfer: core.Transfer, - TransferMultiCoin: core.TransferMultiCoin, - GetHash: cfg.GetHashFn, - Coinbase: cfg.Coinbase, - BlockNumber: cfg.BlockNumber, - Time: cfg.Time, - Difficulty: cfg.Difficulty, - GasLimit: cfg.GasLimit, - BaseFee: cfg.BaseFee, - BlobBaseFee: cfg.BlobBaseFee, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + GetHash: cfg.GetHashFn, + Coinbase: cfg.Coinbase, + BlockNumber: cfg.BlockNumber, + Time: cfg.Time, + Difficulty: cfg.Difficulty, + GasLimit: cfg.GasLimit, + BaseFee: cfg.BaseFee, + BlobBaseFee: cfg.BlobBaseFee, + Random: cfg.Random, } return vm.NewEVM(blockContext, txContext, cfg.State, cfg.ChainConfig, cfg.EVMConfig) diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index b0d4758223..9f7b4f36f9 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -30,14 +30,15 @@ import ( "math" "math/big" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" "github.com/holiman/uint256" ) @@ -68,26 +69,32 @@ type Config struct { // sets defaults on the config func setDefaults(cfg *Config) { if cfg.ChainConfig == nil { - cfg.ChainConfig = ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: new(big.Int), - DAOForkBlock: new(big.Int), - DAOForkSupport: false, - EIP150Block: new(big.Int), - EIP155Block: new(big.Int), - EIP158Block: new(big.Int), - ByzantiumBlock: new(big.Int), - ConstantinopleBlock: new(big.Int), - PetersburgBlock: new(big.Int), - IstanbulBlock: new(big.Int), - MuirGlacierBlock: new(big.Int), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: new(uint64), - ApricotPhase2BlockTimestamp: new(uint64), - ApricotPhase3BlockTimestamp: new(uint64), - ApricotPhase4BlockTimestamp: new(uint64), + cfg.ChainConfig = params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: new(big.Int), + DAOForkBlock: new(big.Int), + DAOForkSupport: false, + EIP150Block: new(big.Int), + EIP155Block: new(big.Int), + EIP158Block: new(big.Int), + ByzantiumBlock: new(big.Int), + ConstantinopleBlock: new(big.Int), + PetersburgBlock: new(big.Int), + IstanbulBlock: new(big.Int), + MuirGlacierBlock: new(big.Int), + LondonBlock: new(big.Int), + BerlinBlock: new(big.Int), }, - } + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: new(uint64), + ApricotPhase2BlockTimestamp: new(uint64), + ApricotPhase3BlockTimestamp: new(uint64), + ApricotPhase4BlockTimestamp: new(uint64), + }, + }, + ) } if cfg.Difficulty == nil { @@ -136,7 +143,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { address = common.BytesToAddress([]byte("contract")) vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) - rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Time) + rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, params.IsMergeTODO, vmenv.Context.Time) ) // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin/ApricotPhase2) @@ -170,7 +177,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) { var ( vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) - rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Time) + rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, params.IsMergeTODO, vmenv.Context.Time) ) // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin/ApricotPhase2) @@ -199,7 +206,7 @@ func Call(address common.Address, input []byte, cfg *Config) ([]byte, uint64, er vmenv = NewEnv(cfg) sender = vm.AccountRef(cfg.Origin) statedb = cfg.State - rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, vmenv.Context.Time) + rules = cfg.ChainConfig.Rules(vmenv.Context.BlockNumber, params.IsMergeTODO, vmenv.Context.Time) ) // Execute the preparatory steps for state transition which includes: // - prepare accessList(post-berlin/ApricotPhase2) diff --git a/core/vm/runtime/runtime_example_test.go b/core/vm/runtime/runtime_example_test.go index 9850e283be..82651d3f1d 100644 --- a/core/vm/runtime/runtime_example_test.go +++ b/core/vm/runtime/runtime_example_test.go @@ -30,7 +30,7 @@ import ( "fmt" "github.com/ava-labs/coreth/core/vm/runtime" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) func ExampleExecute() { diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index 2ccf6c160f..c29e0886da 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -36,18 +36,18 @@ import ( "github.com/ava-labs/coreth/accounts/abi" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/eth/tracers" - "github.com/ava-labs/coreth/eth/tracers/logger" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/asm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/asm" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/eth/tracers/logger" // force-load js tracers to trigger registration - _ "github.com/ava-labs/coreth/eth/tracers/js" + _ "github.com/ava-labs/libevm/eth/tracers/js" "github.com/holiman/uint256" ) diff --git a/core/vm/stack.go b/core/vm/stack.go deleted file mode 100644 index 5463b2d75a..0000000000 --- a/core/vm/stack.go +++ /dev/null @@ -1,92 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vm - -import ( - "sync" - - "github.com/holiman/uint256" -) - -var stackPool = sync.Pool{ - New: func() interface{} { - return &Stack{data: make([]uint256.Int, 0, 16)} - }, -} - -// Stack is an object for basic stack operations. Items popped to the stack are -// expected to be changed and modified. stack does not take care of adding newly -// initialised objects. -type Stack struct { - data []uint256.Int -} - -func newstack() *Stack { - return stackPool.Get().(*Stack) -} - -func returnStack(s *Stack) { - s.data = s.data[:0] - stackPool.Put(s) -} - -// Data returns the underlying uint256.Int array. -func (st *Stack) Data() []uint256.Int { - return st.data -} - -func (st *Stack) push(d *uint256.Int) { - // NOTE push limit (1024) is checked in baseCheck - st.data = append(st.data, *d) -} - -func (st *Stack) pop() (ret uint256.Int) { - ret = st.data[len(st.data)-1] - st.data = st.data[:len(st.data)-1] - return -} - -func (st *Stack) len() int { - return len(st.data) -} - -func (st *Stack) swap(n int) { - st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n] -} - -func (st *Stack) dup(n int) { - st.push(&st.data[st.len()-n]) -} - -func (st *Stack) peek() *uint256.Int { - return &st.data[st.len()-1] -} - -// Back returns the n'th item in stack -func (st *Stack) Back(n int) *uint256.Int { - return &st.data[st.len()-n-1] -} diff --git a/eth/api.go b/eth/api.go index 5842cb5625..dbea129203 100644 --- a/eth/api.go +++ b/eth/api.go @@ -27,7 +27,7 @@ package eth import ( - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // EthereumAPI provides an API to access Ethereum full node-related information. diff --git a/eth/api_admin.go b/eth/api_admin.go index f8945c1d2d..c821d5de9b 100644 --- a/eth/api_admin.go +++ b/eth/api_admin.go @@ -35,8 +35,8 @@ import ( "strings" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" ) // AdminAPI is the collection of Ethereum full node related APIs for node diff --git a/eth/api_backend.go b/eth/api_backend.go index e76dc39b73..bf284eddf8 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -32,23 +32,23 @@ import ( "math/big" "time" - "github.com/ava-labs/coreth/accounts" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/bloombits" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/eth/gasprice" "github.com/ava-labs/coreth/eth/tracers" "github.com/ava-labs/coreth/internal/ethapi" "github.com/ava-labs/coreth/params" customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/accounts" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" ) var ErrUnfinalizedData = errors.New("cannot query unfinalized data") @@ -527,7 +527,8 @@ func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Blo } func (b *EthAPIBackend) MinRequiredTip(ctx context.Context, header *types.Header) (*big.Int, error) { - return customheader.EstimateRequiredTip(b.ChainConfig(), header) + config := params.GetExtra(b.ChainConfig()) + return customheader.EstimateRequiredTip(config, header) } func (b *EthAPIBackend) isLatestAndAllowed(number rpc.BlockNumber) bool { diff --git a/eth/api_backend_test.go b/eth/api_backend_test.go index e58fab0954..b4cef1abd8 100644 --- a/eth/api_backend_test.go +++ b/eth/api_backend_test.go @@ -30,9 +30,9 @@ import ( "fmt" "testing" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/eth/api_debug.go b/eth/api_debug.go index 7269fab769..fb8c34431d 100644 --- a/eth/api_debug.go +++ b/eth/api_debug.go @@ -32,17 +32,17 @@ import ( "fmt" "time" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/internal/ethapi" "github.com/ava-labs/coreth/rpc" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" ) // DebugAPI is the collection of Ethereum full node APIs for debugging the diff --git a/eth/api_debug_test.go b/eth/api_debug_test.go index a0fa2eaa5a..26ccd03694 100644 --- a/eth/api_debug_test.go +++ b/eth/api_debug_test.go @@ -33,17 +33,14 @@ import ( "strings" "testing" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/triedb" - "github.com/holiman/uint256" - + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/triedb" "github.com/davecgh/go-spew/spew" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - + "github.com/holiman/uint256" "golang.org/x/exp/slices" ) diff --git a/eth/backend.go b/eth/backend.go index 79dce86db3..f3edb8f727 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -35,16 +35,12 @@ import ( "time" "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/coreth/accounts" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/bloombits" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state/pruner" "github.com/ava-labs/coreth/core/txpool" "github.com/ava-labs/coreth/core/txpool/legacypool" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/eth/ethconfig" "github.com/ava-labs/coreth/eth/filters" "github.com/ava-labs/coreth/eth/gasprice" @@ -54,11 +50,16 @@ import ( "github.com/ava-labs/coreth/miner" "github.com/ava-labs/coreth/node" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/accounts" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" ) // Config contains the configuration options of the ETH protocol. @@ -415,13 +416,13 @@ func (s *Ethereum) precheckPopulateMissingTries() error { if s.config.PopulateMissingTries == nil { // Delete the populate missing tries marker to indicate that the node started with // populate missing tries disabled. - if err := rawdb.DeletePopulateMissingTries(s.chainDb); err != nil { + if err := customrawdb.DeletePopulateMissingTries(s.chainDb); err != nil { return fmt.Errorf("failed to write populate missing tries disabled marker: %w", err) } return nil } - if lastRun, err := rawdb.ReadPopulateMissingTries(s.chainDb); err == nil { + if lastRun, err := customrawdb.ReadPopulateMissingTries(s.chainDb); err == nil { log.Error("Populate missing tries is not meant to be left enabled permanently. Please disable populate missing tries and allow your node to start successfully before running again.") return fmt.Errorf("cannot start chain with populate missing tries enabled on consecutive starts (last=%v)", lastRun) } @@ -438,7 +439,7 @@ func (s *Ethereum) handleOfflinePruning(cacheConfig *core.CacheConfig, gspec *co if !s.config.OfflinePruning { // Delete the offline pruning marker to indicate that the node started with offline pruning disabled. - if err := rawdb.DeleteOfflinePruning(s.chainDb); err != nil { + if err := customrawdb.DeleteOfflinePruning(s.chainDb); err != nil { return fmt.Errorf("failed to write offline pruning disabled marker: %w", err) } return nil @@ -448,7 +449,7 @@ func (s *Ethereum) handleOfflinePruning(cacheConfig *core.CacheConfig, gspec *co // to the last accepted block before pruning begins. // If offline pruning marker is on disk, then we force the node to be started with offline pruning disabled // before allowing another run of offline pruning. - if lastRun, err := rawdb.ReadOfflinePruning(s.chainDb); err == nil { + if lastRun, err := customrawdb.ReadOfflinePruning(s.chainDb); err == nil { log.Error("Offline pruning is not meant to be left enabled permanently. Please disable offline pruning and allow your node to start successfully before running offline pruning again.") return fmt.Errorf("cannot start chain with offline pruning enabled on consecutive starts (last=%v)", lastRun) } diff --git a/eth/bloombits.go b/eth/bloombits.go index ecc0aaf157..775b0c708d 100644 --- a/eth/bloombits.go +++ b/eth/bloombits.go @@ -29,8 +29,8 @@ package eth import ( "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common/bitutil" + "github.com/ava-labs/libevm/common/bitutil" + "github.com/ava-labs/libevm/core/rawdb" ) const ( diff --git a/eth/chain_with_final_block.go b/eth/chain_with_final_block.go index 6e2afba475..0806388cd0 100644 --- a/eth/chain_with_final_block.go +++ b/eth/chain_with_final_block.go @@ -3,7 +3,7 @@ package eth import ( "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" ) const blocksToKeep = 604_800 // Approx. 2 weeks worth of blocks assuming 2s block time diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index af81532567..b1c4ee2854 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -36,7 +36,7 @@ import ( "github.com/ava-labs/coreth/internal/ethapi" "github.com/ava-labs/coreth/miner" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // DefaultFullGPOConfig contains default gasprice oracle settings for full node. diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go new file mode 100644 index 0000000000..71944b8a95 --- /dev/null +++ b/eth/ethconfig/gen_config.go @@ -0,0 +1,280 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package ethconfig + +import ( + "time" + + "github.com/ava-labs/coreth/core" + "github.com/ava-labs/coreth/core/txpool/blobpool" + "github.com/ava-labs/coreth/core/txpool/legacypool" + "github.com/ava-labs/coreth/eth/gasprice" + "github.com/ava-labs/coreth/internal/ethapi" + "github.com/ava-labs/coreth/miner" + "github.com/ava-labs/libevm/common" +) + +// MarshalTOML marshals as TOML. +func (c Config) MarshalTOML() (interface{}, error) { + type Config struct { + Genesis *core.Genesis `toml:",omitempty"` + NetworkId uint64 + Pruning bool + AcceptorQueueLimit int + CommitInterval uint64 + PopulateMissingTries *uint64 + PopulateMissingTriesParallelism int + AllowMissingTries bool + SnapshotDelayInit bool + SnapshotWait bool + SnapshotVerify bool + SkipSnapshotRebuild bool + SkipBcVersionCheck bool `toml:"-"` + TrieCleanCache int + TrieDirtyCache int + TrieDirtyCommitTarget int + TriePrefetcherParallelism int + SnapshotCache int + Preimages bool + AcceptedCacheSize int + Miner miner.Config + TxPool legacypool.Config + BlobPool blobpool.Config + GPO gasprice.Config + EnablePreimageRecording bool + RPCGasCap uint64 `toml:",omitempty"` + RPCEVMTimeout time.Duration + RPCTxFeeCap float64 `toml:",omitempty"` + AllowUnfinalizedQueries bool + HistoricalProofQueryWindow uint64 + AllowUnprotectedTxs bool + AllowUnprotectedTxHashes []common.Hash + OfflinePruning bool + OfflinePruningBloomFilterSize uint64 + OfflinePruningDataDirectory string + SkipUpgradeCheck bool + TransactionHistory uint64 `toml:",omitempty"` + StateHistory uint64 `toml:",omitempty"` + StateScheme string `toml:",omitempty"` + SkipTxIndexing bool + PriceOptionConfig ethapi.PriceOptionConfig + } + var enc Config + enc.Genesis = c.Genesis + enc.NetworkId = c.NetworkId + enc.Pruning = c.Pruning + enc.AcceptorQueueLimit = c.AcceptorQueueLimit + enc.CommitInterval = c.CommitInterval + enc.PopulateMissingTries = c.PopulateMissingTries + enc.PopulateMissingTriesParallelism = c.PopulateMissingTriesParallelism + enc.AllowMissingTries = c.AllowMissingTries + enc.SnapshotDelayInit = c.SnapshotDelayInit + enc.SnapshotWait = c.SnapshotWait + enc.SnapshotVerify = c.SnapshotVerify + enc.SkipSnapshotRebuild = c.SkipSnapshotRebuild + enc.SkipBcVersionCheck = c.SkipBcVersionCheck + enc.TrieCleanCache = c.TrieCleanCache + enc.TrieDirtyCache = c.TrieDirtyCache + enc.TrieDirtyCommitTarget = c.TrieDirtyCommitTarget + enc.TriePrefetcherParallelism = c.TriePrefetcherParallelism + enc.SnapshotCache = c.SnapshotCache + enc.Preimages = c.Preimages + enc.AcceptedCacheSize = c.AcceptedCacheSize + enc.Miner = c.Miner + enc.TxPool = c.TxPool + enc.BlobPool = c.BlobPool + enc.GPO = c.GPO + enc.EnablePreimageRecording = c.EnablePreimageRecording + enc.RPCGasCap = c.RPCGasCap + enc.RPCEVMTimeout = c.RPCEVMTimeout + enc.RPCTxFeeCap = c.RPCTxFeeCap + enc.AllowUnfinalizedQueries = c.AllowUnfinalizedQueries + enc.HistoricalProofQueryWindow = c.HistoricalProofQueryWindow + enc.AllowUnprotectedTxs = c.AllowUnprotectedTxs + enc.AllowUnprotectedTxHashes = c.AllowUnprotectedTxHashes + enc.OfflinePruning = c.OfflinePruning + enc.OfflinePruningBloomFilterSize = c.OfflinePruningBloomFilterSize + enc.OfflinePruningDataDirectory = c.OfflinePruningDataDirectory + enc.SkipUpgradeCheck = c.SkipUpgradeCheck + enc.TransactionHistory = c.TransactionHistory + enc.StateHistory = c.StateHistory + enc.StateScheme = c.StateScheme + enc.SkipTxIndexing = c.SkipTxIndexing + enc.PriceOptionConfig = c.PriceOptionConfig + return &enc, nil +} + +// UnmarshalTOML unmarshals from TOML. +func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { + type Config struct { + Genesis *core.Genesis `toml:",omitempty"` + NetworkId *uint64 + Pruning *bool + AcceptorQueueLimit *int + CommitInterval *uint64 + PopulateMissingTries *uint64 + PopulateMissingTriesParallelism *int + AllowMissingTries *bool + SnapshotDelayInit *bool + SnapshotWait *bool + SnapshotVerify *bool + SkipSnapshotRebuild *bool + SkipBcVersionCheck *bool `toml:"-"` + TrieCleanCache *int + TrieDirtyCache *int + TrieDirtyCommitTarget *int + TriePrefetcherParallelism *int + SnapshotCache *int + Preimages *bool + AcceptedCacheSize *int + Miner *miner.Config + TxPool *legacypool.Config + BlobPool *blobpool.Config + GPO *gasprice.Config + EnablePreimageRecording *bool + RPCGasCap *uint64 `toml:",omitempty"` + RPCEVMTimeout *time.Duration + RPCTxFeeCap *float64 `toml:",omitempty"` + AllowUnfinalizedQueries *bool + HistoricalProofQueryWindow *uint64 + AllowUnprotectedTxs *bool + AllowUnprotectedTxHashes []common.Hash + OfflinePruning *bool + OfflinePruningBloomFilterSize *uint64 + OfflinePruningDataDirectory *string + SkipUpgradeCheck *bool + TransactionHistory *uint64 `toml:",omitempty"` + StateHistory *uint64 `toml:",omitempty"` + StateScheme *string `toml:",omitempty"` + SkipTxIndexing *bool + PriceOptionConfig *ethapi.PriceOptionConfig + } + var dec Config + if err := unmarshal(&dec); err != nil { + return err + } + if dec.Genesis != nil { + c.Genesis = dec.Genesis + } + if dec.NetworkId != nil { + c.NetworkId = *dec.NetworkId + } + if dec.Pruning != nil { + c.Pruning = *dec.Pruning + } + if dec.AcceptorQueueLimit != nil { + c.AcceptorQueueLimit = *dec.AcceptorQueueLimit + } + if dec.CommitInterval != nil { + c.CommitInterval = *dec.CommitInterval + } + if dec.PopulateMissingTries != nil { + c.PopulateMissingTries = dec.PopulateMissingTries + } + if dec.PopulateMissingTriesParallelism != nil { + c.PopulateMissingTriesParallelism = *dec.PopulateMissingTriesParallelism + } + if dec.AllowMissingTries != nil { + c.AllowMissingTries = *dec.AllowMissingTries + } + if dec.SnapshotDelayInit != nil { + c.SnapshotDelayInit = *dec.SnapshotDelayInit + } + if dec.SnapshotWait != nil { + c.SnapshotWait = *dec.SnapshotWait + } + if dec.SnapshotVerify != nil { + c.SnapshotVerify = *dec.SnapshotVerify + } + if dec.SkipSnapshotRebuild != nil { + c.SkipSnapshotRebuild = *dec.SkipSnapshotRebuild + } + if dec.SkipBcVersionCheck != nil { + c.SkipBcVersionCheck = *dec.SkipBcVersionCheck + } + if dec.TrieCleanCache != nil { + c.TrieCleanCache = *dec.TrieCleanCache + } + if dec.TrieDirtyCache != nil { + c.TrieDirtyCache = *dec.TrieDirtyCache + } + if dec.TrieDirtyCommitTarget != nil { + c.TrieDirtyCommitTarget = *dec.TrieDirtyCommitTarget + } + if dec.TriePrefetcherParallelism != nil { + c.TriePrefetcherParallelism = *dec.TriePrefetcherParallelism + } + if dec.SnapshotCache != nil { + c.SnapshotCache = *dec.SnapshotCache + } + if dec.Preimages != nil { + c.Preimages = *dec.Preimages + } + if dec.AcceptedCacheSize != nil { + c.AcceptedCacheSize = *dec.AcceptedCacheSize + } + if dec.Miner != nil { + c.Miner = *dec.Miner + } + if dec.TxPool != nil { + c.TxPool = *dec.TxPool + } + if dec.BlobPool != nil { + c.BlobPool = *dec.BlobPool + } + if dec.GPO != nil { + c.GPO = *dec.GPO + } + if dec.EnablePreimageRecording != nil { + c.EnablePreimageRecording = *dec.EnablePreimageRecording + } + if dec.RPCGasCap != nil { + c.RPCGasCap = *dec.RPCGasCap + } + if dec.RPCEVMTimeout != nil { + c.RPCEVMTimeout = *dec.RPCEVMTimeout + } + if dec.RPCTxFeeCap != nil { + c.RPCTxFeeCap = *dec.RPCTxFeeCap + } + if dec.AllowUnfinalizedQueries != nil { + c.AllowUnfinalizedQueries = *dec.AllowUnfinalizedQueries + } + if dec.HistoricalProofQueryWindow != nil { + c.HistoricalProofQueryWindow = *dec.HistoricalProofQueryWindow + } + if dec.AllowUnprotectedTxs != nil { + c.AllowUnprotectedTxs = *dec.AllowUnprotectedTxs + } + if dec.AllowUnprotectedTxHashes != nil { + c.AllowUnprotectedTxHashes = dec.AllowUnprotectedTxHashes + } + if dec.OfflinePruning != nil { + c.OfflinePruning = *dec.OfflinePruning + } + if dec.OfflinePruningBloomFilterSize != nil { + c.OfflinePruningBloomFilterSize = *dec.OfflinePruningBloomFilterSize + } + if dec.OfflinePruningDataDirectory != nil { + c.OfflinePruningDataDirectory = *dec.OfflinePruningDataDirectory + } + if dec.SkipUpgradeCheck != nil { + c.SkipUpgradeCheck = *dec.SkipUpgradeCheck + } + if dec.TransactionHistory != nil { + c.TransactionHistory = *dec.TransactionHistory + } + if dec.StateHistory != nil { + c.StateHistory = *dec.StateHistory + } + if dec.StateScheme != nil { + c.StateScheme = *dec.StateScheme + } + if dec.SkipTxIndexing != nil { + c.SkipTxIndexing = *dec.SkipTxIndexing + } + if dec.PriceOptionConfig != nil { + c.PriceOptionConfig = *dec.PriceOptionConfig + } + return nil +} diff --git a/eth/filters/api.go b/eth/filters/api.go index fb8178ed63..0aa40e692d 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -35,13 +35,13 @@ import ( "sync" "time" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/coreth/internal/ethapi" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/event" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" ) var ( @@ -333,12 +333,12 @@ func (api *FilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subsc ) if api.sys.backend.IsAllowUnfinalizedQueries() { - logsSub, err = api.events.SubscribeLogs(interfaces.FilterQuery(crit), matchedLogs) + logsSub, err = api.events.SubscribeLogs(ethereum.FilterQuery(crit), matchedLogs) if err != nil { return nil, err } } else { - logsSub, err = api.events.SubscribeAcceptedLogs(interfaces.FilterQuery(crit), matchedLogs) + logsSub, err = api.events.SubscribeAcceptedLogs(ethereum.FilterQuery(crit), matchedLogs) if err != nil { return nil, err } @@ -364,8 +364,8 @@ func (api *FilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subsc } // FilterCriteria represents a request to create a new filter. -// Same as interfaces.FilterQuery but with UnmarshalJSON() method. -type FilterCriteria interfaces.FilterQuery +// Same as [ethereum.FilterQuery] with the method [FilterCriteria.UnmarshalJSON]. +type FilterCriteria ethereum.FilterQuery // NewFilter creates a new filter and returns the filter id. It can be // used to retrieve logs when the state changes. This method cannot be @@ -386,12 +386,12 @@ func (api *FilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { ) if api.sys.backend.IsAllowUnfinalizedQueries() { - logsSub, err = api.events.SubscribeLogs(interfaces.FilterQuery(crit), logs) + logsSub, err = api.events.SubscribeLogs(ethereum.FilterQuery(crit), logs) if err != nil { return "", err } } else { - logsSub, err = api.events.SubscribeAcceptedLogs(interfaces.FilterQuery(crit), logs) + logsSub, err = api.events.SubscribeAcceptedLogs(ethereum.FilterQuery(crit), logs) if err != nil { return "", err } diff --git a/eth/filters/api_test.go b/eth/filters/api_test.go index 72838b4d8c..5bb2d0a6cb 100644 --- a/eth/filters/api_test.go +++ b/eth/filters/api_test.go @@ -22,7 +22,7 @@ import ( "testing" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) func TestUnmarshalJSONNewFilterArgs(t *testing.T) { diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go index 77f0567870..4dc33dd4b9 100644 --- a/eth/filters/bench_test.go +++ b/eth/filters/bench_test.go @@ -33,11 +33,11 @@ import ( "time" "github.com/ava-labs/coreth/core/bloombits" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/bitutil" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/bitutil" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" ) func BenchmarkBloomBits512(b *testing.B) { diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 6b77ee68e1..6239101806 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -33,9 +33,10 @@ import ( "math/big" "github.com/ava-labs/coreth/core/bloombits" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // Filter can be used to retrieve and filter logs. @@ -341,7 +342,7 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) ([]*typ return nil, err } - unfiltered := types.FlattenLogs(logsList) + unfiltered := customtypes.FlattenLogs(logsList) logs := filterLogs(unfiltered, nil, nil, f.addresses, f.topics) if len(logs) == 0 { return nil, nil diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 6a312df2ee..8fba1b687a 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -36,14 +36,14 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/bloombits" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" ) // Config represents the configuration of the filter system. @@ -162,7 +162,7 @@ type subscription struct { id rpc.ID typ Type created time.Time - logsCrit interfaces.FilterQuery + logsCrit ethereum.FilterQuery logs chan []*types.Log txs chan []*types.Transaction headers chan *types.Header @@ -288,7 +288,7 @@ func (es *EventSystem) subscribe(sub *subscription) *Subscription { // SubscribeLogs creates a subscription that will write all logs matching the // given criteria to the given logs channel. Default value for the from and to // block is "latest". If the fromBlock > toBlock an error is returned. -func (es *EventSystem) SubscribeLogs(crit interfaces.FilterQuery, logs chan []*types.Log) (*Subscription, error) { +func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) (*Subscription, error) { if len(crit.Topics) > maxTopics { return nil, errExceedMaxTopics } @@ -327,7 +327,7 @@ func (es *EventSystem) SubscribeLogs(crit interfaces.FilterQuery, logs chan []*t return nil, errInvalidBlockRange } -func (es *EventSystem) SubscribeAcceptedLogs(crit interfaces.FilterQuery, logs chan []*types.Log) (*Subscription, error) { +func (es *EventSystem) SubscribeAcceptedLogs(crit ethereum.FilterQuery, logs chan []*types.Log) (*Subscription, error) { var from, to rpc.BlockNumber if crit.FromBlock == nil { from = rpc.LatestBlockNumber @@ -352,7 +352,7 @@ func (es *EventSystem) SubscribeAcceptedLogs(crit interfaces.FilterQuery, logs c return nil, fmt.Errorf("invalid from and to block combination: from > to") } -func (es *EventSystem) subscribeAcceptedLogs(crit interfaces.FilterQuery, logs chan []*types.Log) *Subscription { +func (es *EventSystem) subscribeAcceptedLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { sub := &subscription{ id: rpc.NewID(), typ: AcceptedLogsSubscription, @@ -369,7 +369,7 @@ func (es *EventSystem) subscribeAcceptedLogs(crit interfaces.FilterQuery, logs c // subscribeMinedPendingLogs creates a subscription that returned mined and // pending logs that match the given criteria. -func (es *EventSystem) subscribeMinedPendingLogs(crit interfaces.FilterQuery, logs chan []*types.Log) *Subscription { +func (es *EventSystem) subscribeMinedPendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { sub := &subscription{ id: rpc.NewID(), typ: MinedAndPendingLogsSubscription, @@ -386,7 +386,7 @@ func (es *EventSystem) subscribeMinedPendingLogs(crit interfaces.FilterQuery, lo // subscribeLogs creates a subscription that will write all logs matching the // given criteria to the given logs channel. -func (es *EventSystem) subscribeLogs(crit interfaces.FilterQuery, logs chan []*types.Log) *Subscription { +func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { sub := &subscription{ id: rpc.NewID(), typ: LogsSubscription, @@ -403,7 +403,7 @@ func (es *EventSystem) subscribeLogs(crit interfaces.FilterQuery, logs chan []*t // subscribePendingLogs creates a subscription that writes contract event logs for // transactions that enter the transaction pool. -func (es *EventSystem) subscribePendingLogs(crit interfaces.FilterQuery, logs chan []*types.Log) *Subscription { +func (es *EventSystem) subscribePendingLogs(crit ethereum.FilterQuery, logs chan []*types.Log) *Subscription { sub := &subscription{ id: rpc.NewID(), typ: PendingLogsSubscription, diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 073049a256..9d11a5b99e 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -40,15 +40,16 @@ import ( "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/bloombits" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/coreth/internal/ethapi" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" "github.com/stretchr/testify/require" ) @@ -97,7 +98,7 @@ func (b *testBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumbe switch blockNr { case rpc.FinalizedBlockNumber: var err error - hash, err = rawdb.ReadAcceptorTip(b.db) + hash, err = customrawdb.ReadAcceptorTip(b.db) if err != nil { return nil, err } @@ -658,7 +659,7 @@ func TestPendingLogsSubscription(t *testing.T) { pendingBlockNumber = big.NewInt(rpc.PendingBlockNumber.Int64()) testCases = []struct { - crit interfaces.FilterQuery + crit ethereum.FilterQuery expected []*types.Log c chan []*types.Log sub *Subscription @@ -666,67 +667,67 @@ func TestPendingLogsSubscription(t *testing.T) { }{ // match all { - interfaces.FilterQuery{FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, + ethereum.FilterQuery{FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, flattenLogs(allLogs), nil, nil, nil, }, // match none due to no matching addresses { - interfaces.FilterQuery{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, + ethereum.FilterQuery{Addresses: []common.Address{{}, notUsedAddress}, Topics: [][]common.Hash{nil}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, nil, nil, nil, nil, }, // match logs based on addresses, ignore topics { - interfaces.FilterQuery{Addresses: []common.Address{firstAddr}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, + ethereum.FilterQuery{Addresses: []common.Address{firstAddr}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, append(flattenLogs(allLogs[:2]), allLogs[5][3]), nil, nil, nil, }, // match none due to no matching topics (match with address) { - interfaces.FilterQuery{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, + ethereum.FilterQuery{Addresses: []common.Address{secondAddr}, Topics: [][]common.Hash{{notUsedTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, nil, nil, nil, nil, }, // match logs based on addresses and topics { - interfaces.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, + ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, append(flattenLogs(allLogs[3:5]), allLogs[5][0]), nil, nil, nil, }, // match logs based on multiple addresses and "or" topics { - interfaces.FilterQuery{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, + ethereum.FilterQuery{Addresses: []common.Address{secondAddr, thirdAddress}, Topics: [][]common.Hash{{firstTopic, secondTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, append(flattenLogs(allLogs[2:5]), allLogs[5][0]), nil, nil, nil, }, // multiple pending logs, should match only 2 topics from the logs in block 5 { - interfaces.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, fourthTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, + ethereum.FilterQuery{Addresses: []common.Address{thirdAddress}, Topics: [][]common.Hash{{firstTopic, fourthTopic}}, FromBlock: pendingBlockNumber, ToBlock: pendingBlockNumber}, []*types.Log{allLogs[5][0], allLogs[5][2]}, nil, nil, nil, }, // match none due to only matching new mined logs { - interfaces.FilterQuery{}, + ethereum.FilterQuery{}, nil, nil, nil, nil, }, // match none due to only matching mined logs within a specific block range { - interfaces.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2)}, + ethereum.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(2)}, nil, nil, nil, nil, }, // match all due to matching mined and pending logs { - interfaces.FilterQuery{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, + ethereum.FilterQuery{FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(rpc.PendingBlockNumber.Int64())}, flattenLogs(allLogs), nil, nil, nil, }, // match none due to matching logs from a specific block number to new mined blocks { - interfaces.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, + ethereum.FilterQuery{FromBlock: big.NewInt(1), ToBlock: big.NewInt(rpc.LatestBlockNumber.Int64())}, nil, nil, nil, nil, }, diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index 4acb7c45c0..708a8bac6c 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -37,14 +37,15 @@ import ( "github.com/ava-labs/coreth/accounts/abi" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/rpc" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/triedb" "github.com/stretchr/testify/require" ) @@ -273,7 +274,7 @@ func TestFilters(t *testing.T) { // Set block 998 as Finalized (-3) // bc.SetFinalized(chain[998].Header()) - err = rawdb.WriteAcceptorTip(db, chain[998].Hash()) + err = customrawdb.WriteAcceptorTip(db, chain[998].Hash()) require.NoError(t, err) for i, tc := range []struct { diff --git a/eth/gasestimator/gasestimator.go b/eth/gasestimator/gasestimator.go index 291e806b84..b97f1b6747 100644 --- a/eth/gasestimator/gasestimator.go +++ b/eth/gasestimator/gasestimator.go @@ -35,12 +35,11 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/log" ) // Options are the contextual parameters to execute the requested call. @@ -128,7 +127,7 @@ func Estimate(ctx context.Context, call *core.Message, opts *Options, gasCap uin return 0, nil, err } if failed { - if result != nil && !errors.Is(result.Err, vmerrs.ErrOutOfGas) { + if result != nil && !errors.Is(result.Err, vm.ErrOutOfGas) { return 0, result.Revert(), result.Err } return 0, nil, fmt.Errorf("gas required exceeds allowance (%d)", hi) diff --git a/eth/gasprice/fee_info_provider.go b/eth/gasprice/fee_info_provider.go index 7c792aa6a8..718d0381a8 100644 --- a/eth/gasprice/fee_info_provider.go +++ b/eth/gasprice/fee_info_provider.go @@ -31,8 +31,9 @@ import ( "math/big" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/rpc" + "github.com/ava-labs/libevm/core/types" lru "github.com/hashicorp/golang-lru" ) @@ -94,8 +95,8 @@ func (f *feeInfoProvider) addHeader(ctx context.Context, header *types.Header) ( } totalGasUsed := new(big.Int).SetUint64(header.GasUsed) - if header.ExtDataGasUsed != nil { - totalGasUsed.Add(totalGasUsed, header.ExtDataGasUsed) + if used := customtypes.GetHeaderExtra(header).ExtDataGasUsed; used != nil { + totalGasUsed.Add(totalGasUsed, used) } minGasUsed := new(big.Int).SetUint64(f.minGasUsed) diff --git a/eth/gasprice/fee_info_provider_test.go b/eth/gasprice/fee_info_provider_test.go index 4ea5db71b1..b851a4430d 100644 --- a/eth/gasprice/fee_info_provider_test.go +++ b/eth/gasprice/fee_info_provider_test.go @@ -10,9 +10,9 @@ import ( "testing" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" ) diff --git a/eth/gasprice/feehistory.go b/eth/gasprice/feehistory.go index d86121c003..a619b8e005 100644 --- a/eth/gasprice/feehistory.go +++ b/eth/gasprice/feehistory.go @@ -33,10 +33,10 @@ import ( "math/big" "slices" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/log" ) var ( diff --git a/eth/gasprice/feehistory_test.go b/eth/gasprice/feehistory_test.go index f8234d1d18..2e2d1cc8c0 100644 --- a/eth/gasprice/feehistory_test.go +++ b/eth/gasprice/feehistory_test.go @@ -33,12 +33,12 @@ import ( "testing" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) func TestFeeHistory(t *testing.T) { diff --git a/eth/gasprice/gasprice.go b/eth/gasprice/gasprice.go index c66db90539..f236715056 100644 --- a/eth/gasprice/gasprice.go +++ b/eth/gasprice/gasprice.go @@ -33,15 +33,15 @@ import ( "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/lru" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" "golang.org/x/exp/slices" ) @@ -230,7 +230,8 @@ func (oracle *Oracle) estimateNextBaseFee(ctx context.Context) (*big.Int, error) // If the block does have a baseFee, calculate the next base fee // based on the current time and add it to the tip to estimate the // total gas price estimate. - return customheader.EstimateNextBaseFee(oracle.backend.ChainConfig(), header, oracle.clock.Unix()) + config := params.GetExtra(oracle.backend.ChainConfig()) + return customheader.EstimateNextBaseFee(config, header, oracle.clock.Unix()) } // SuggestPrice returns an estimated price for legacy transactions. diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 2282884010..5dcc3c02e0 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -34,19 +34,19 @@ import ( "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/event" "github.com/stretchr/testify/require" ) @@ -155,7 +155,8 @@ func newTestBackend(t *testing.T, config *params.ChainConfig, numBlocks int, ext } func (b *testBackend) MinRequiredTip(ctx context.Context, header *types.Header) (*big.Int, error) { - return customheader.EstimateRequiredTip(b.chain.Config(), header) + config := params.GetExtra(b.chain.Config()) + return customheader.EstimateRequiredTip(config, header) } func (b *testBackend) CurrentHeader() *types.Header { diff --git a/eth/state_accessor.go b/eth/state_accessor.go index d5f87ce2ef..494d457b5d 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -33,15 +33,15 @@ import ( "time" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/eth/tracers" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" ) // noopReleaser is returned in case there is no operation expected @@ -284,7 +284,8 @@ func (eth *Ethereum) StateAtNextBlock(ctx context.Context, parent *types.Block, } // Apply upgrades here for the [nextBlock] - err = core.ApplyUpgrades(eth.blockchain.Config(), &parent.Header().Time, nextBlock, statedb) + blockContext := core.NewBlockContext(nextBlock.Number(), nextBlock.Time()) + err = core.ApplyUpgrades(eth.blockchain.Config(), &parent.Header().Time, blockContext, statedb) if err != nil { release() return nil, nil, err diff --git a/eth/tracers/api.go b/eth/tracers/api.go index b8ddc1a3a7..66eb98fa43 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -40,17 +40,17 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers/logger" "github.com/ava-labs/coreth/internal/ethapi" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/eth/tracers/logger" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" ) const ( @@ -959,13 +959,15 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc defer release() vmctx := core.NewEVMBlockContext(block.Header(), api.chainContext(ctx), nil) + // Apply the customization rules if required. if config != nil { originalTime := block.Time() config.BlockOverrides.Apply(&vmctx) // Apply all relevant upgrades from [originalTime] to the block time set in the override. // Should be applied before the state overrides. - err = core.ApplyUpgrades(api.backend.ChainConfig(), &originalTime, &vmctx, statedb) + blockContext := core.NewBlockContext(block.Number(), block.Time()) + err = core.ApplyUpgrades(api.backend.ChainConfig(), &originalTime, blockContext, statedb) if err != nil { return nil, err } @@ -1056,57 +1058,58 @@ func APIs(backend Backend) []rpc.API { // along with a boolean that indicates whether the copy is canonical (equivalent to the original). func overrideConfig(original *params.ChainConfig, override *params.ChainConfig) (*params.ChainConfig, bool) { copy := new(params.ChainConfig) - *copy = *original + *copy = params.Copy(original) canon := true // Apply network upgrades (after Berlin) to the copy. // Note in coreth, ApricotPhase2 is the "equivalent" to Berlin. - if timestamp := override.ApricotPhase2BlockTimestamp; timestamp != nil { - copy.ApricotPhase2BlockTimestamp = timestamp + overrideExtra := params.GetExtra(override) + if timestamp := overrideExtra.ApricotPhase2BlockTimestamp; timestamp != nil { + params.GetExtra(copy).ApricotPhase2BlockTimestamp = timestamp canon = false } - if timestamp := override.ApricotPhase3BlockTimestamp; timestamp != nil { - copy.ApricotPhase3BlockTimestamp = timestamp + if timestamp := overrideExtra.ApricotPhase3BlockTimestamp; timestamp != nil { + params.GetExtra(copy).ApricotPhase3BlockTimestamp = timestamp canon = false } - if timestamp := override.ApricotPhase4BlockTimestamp; timestamp != nil { - copy.ApricotPhase4BlockTimestamp = timestamp + if timestamp := overrideExtra.ApricotPhase4BlockTimestamp; timestamp != nil { + params.GetExtra(copy).ApricotPhase4BlockTimestamp = timestamp canon = false } - if timestamp := override.ApricotPhase5BlockTimestamp; timestamp != nil { - copy.ApricotPhase5BlockTimestamp = timestamp + if timestamp := overrideExtra.ApricotPhase5BlockTimestamp; timestamp != nil { + params.GetExtra(copy).ApricotPhase5BlockTimestamp = timestamp canon = false } - if timestamp := override.ApricotPhasePre6BlockTimestamp; timestamp != nil { - copy.ApricotPhasePre6BlockTimestamp = timestamp + if timestamp := overrideExtra.ApricotPhasePre6BlockTimestamp; timestamp != nil { + params.GetExtra(copy).ApricotPhasePre6BlockTimestamp = timestamp canon = false } - if timestamp := override.ApricotPhase6BlockTimestamp; timestamp != nil { - copy.ApricotPhase6BlockTimestamp = timestamp + if timestamp := overrideExtra.ApricotPhase6BlockTimestamp; timestamp != nil { + params.GetExtra(copy).ApricotPhase6BlockTimestamp = timestamp canon = false } - if timestamp := override.ApricotPhasePost6BlockTimestamp; timestamp != nil { - copy.ApricotPhasePost6BlockTimestamp = timestamp + if timestamp := overrideExtra.ApricotPhasePost6BlockTimestamp; timestamp != nil { + params.GetExtra(copy).ApricotPhasePost6BlockTimestamp = timestamp canon = false } - if timestamp := override.BanffBlockTimestamp; timestamp != nil { - copy.BanffBlockTimestamp = timestamp + if timestamp := overrideExtra.BanffBlockTimestamp; timestamp != nil { + params.GetExtra(copy).BanffBlockTimestamp = timestamp canon = false } - if timestamp := override.CortinaBlockTimestamp; timestamp != nil { - copy.CortinaBlockTimestamp = timestamp + if timestamp := overrideExtra.CortinaBlockTimestamp; timestamp != nil { + params.GetExtra(copy).CortinaBlockTimestamp = timestamp canon = false } - if timestamp := override.DurangoBlockTimestamp; timestamp != nil { - copy.DurangoBlockTimestamp = timestamp + if timestamp := overrideExtra.DurangoBlockTimestamp; timestamp != nil { + params.GetExtra(copy).DurangoBlockTimestamp = timestamp canon = false } - if timestamp := override.EtnaTimestamp; timestamp != nil { - copy.EtnaTimestamp = timestamp + if timestamp := overrideExtra.EtnaTimestamp; timestamp != nil { + params.GetExtra(copy).EtnaTimestamp = timestamp canon = false } - if timestamp := override.FortunaTimestamp; timestamp != nil { - copy.FortunaTimestamp = timestamp + if timestamp := overrideExtra.FortunaTimestamp; timestamp != nil { + params.GetExtra(copy).FortunaTimestamp = timestamp canon = false } if timestamp := override.CancunTime; timestamp != nil { diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index fcaf16a85a..053953d09e 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -40,18 +40,18 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers/logger" "github.com/ava-labs/coreth/internal/ethapi" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/eth/tracers/logger" + "github.com/ava-labs/libevm/ethdb" "golang.org/x/exp/slices" ) @@ -181,7 +181,8 @@ func (b *testBackend) StateAtNextBlock(ctx context.Context, parent, nextBlock *t return nil, nil, err } // Apply upgrades to the parent state - err = core.ApplyUpgrades(b.chainConfig, &parent.Header().Time, nextBlock, statedb) + blockContext := core.NewBlockContext(nextBlock.Number(), nextBlock.Time()) + err = core.ApplyUpgrades(b.chainConfig, &parent.Header().Time, blockContext, statedb) if err != nil { release() return nil, nil, err diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go deleted file mode 100644 index 075a804f18..0000000000 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ /dev/null @@ -1,410 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package tracetest - -import ( - "encoding/json" - "math/big" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/tests" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/rlp" -) - -type callContext struct { - Number math.HexOrDecimal64 `json:"number"` - Difficulty *math.HexOrDecimal256 `json:"difficulty"` - Time math.HexOrDecimal64 `json:"timestamp"` - GasLimit math.HexOrDecimal64 `json:"gasLimit"` - Miner common.Address `json:"miner"` -} - -// callLog is the result of LOG opCode -type callLog struct { - Address common.Address `json:"address"` - Topics []common.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` - Position hexutil.Uint `json:"position"` -} - -// callTrace is the result of a callTracer run. -type callTrace struct { - From common.Address `json:"from"` - Gas *hexutil.Uint64 `json:"gas"` - GasUsed *hexutil.Uint64 `json:"gasUsed"` - To *common.Address `json:"to,omitempty"` - Input hexutil.Bytes `json:"input"` - Output hexutil.Bytes `json:"output,omitempty"` - Error string `json:"error,omitempty"` - RevertReason string `json:"revertReason,omitempty"` - Calls []callTrace `json:"calls,omitempty"` - Logs []callLog `json:"logs,omitempty"` - Value *hexutil.Big `json:"value,omitempty"` - // Gencodec adds overridden fields at the end - Type string `json:"type"` -} - -// callTracerTest defines a single test to check the call tracer against. -type callTracerTest struct { - Genesis *core.Genesis `json:"genesis"` - Context *callContext `json:"context"` - Input string `json:"input"` - TracerConfig json.RawMessage `json:"tracerConfig"` - Result *callTrace `json:"result"` -} - -// Iterates over all the input-output datasets in the tracer test harness and -// runs the JavaScript tracers against them. -func TestCallTracerLegacy(t *testing.T) { - testCallTracer("callTracerLegacy", "call_tracer_legacy", t) -} - -func TestCallTracerNative(t *testing.T) { - testCallTracer("callTracer", "call_tracer", t) -} - -func TestCallTracerNativeWithLog(t *testing.T) { - testCallTracer("callTracer", "call_tracer_withLog", t) -} - -func testCallTracer(tracerName string, dirPath string, t *testing.T) { - isLegacy := strings.HasSuffix(dirPath, "_legacy") - files, err := os.ReadDir(filepath.Join("testdata", dirPath)) - if err != nil { - t.Fatalf("failed to retrieve tracer test suite: %v", err) - } - for _, file := range files { - if !strings.HasSuffix(file.Name(), ".json") { - continue - } - t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) { - t.Parallel() - - var ( - test = new(callTracerTest) - tx = new(types.Transaction) - ) - // Call tracer test found, read if from disk - if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { - t.Fatalf("failed to read testcase: %v", err) - } else if err := json.Unmarshal(blob, test); err != nil { - t.Fatalf("failed to parse testcase: %v", err) - } - if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil { - t.Fatalf("failed to parse testcase input: %v", err) - } - // Configure a blockchain with the given prestate - var ( - signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - context = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - BaseFee: test.Genesis.BaseFee, - } - state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) - ) - state.Close() - - tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig) - if err != nil { - t.Fatalf("failed to create call tracer: %v", err) - } - msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) - if err != nil { - t.Fatalf("failed to prepare transaction for tracing: %v", err) - } - evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) - vmRet, err := core.ApplyMessage(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if err != nil { - t.Fatalf("failed to execute transaction: %v", err) - } - // Retrieve the trace result and compare against the expected. - res, err := tracer.GetResult() - if err != nil { - t.Fatalf("failed to retrieve trace result: %v", err) - } - // The legacy javascript calltracer marshals json in js, which - // is not deterministic (as opposed to the golang json encoder). - if isLegacy { - // This is a tweak to make it deterministic. Can be removed when - // we remove the legacy tracer. - var x callTrace - json.Unmarshal(res, &x) - res, _ = json.Marshal(x) - } - want, err := json.Marshal(test.Result) - if err != nil { - t.Fatalf("failed to marshal test: %v", err) - } - if string(want) != string(res) { - t.Fatalf("trace mismatch\n have: %v\n want: %v\n", string(res), string(want)) - } - // Sanity check: compare top call's gas used against vm result - type simpleResult struct { - GasUsed hexutil.Uint64 - } - var topCall simpleResult - if err := json.Unmarshal(res, &topCall); err != nil { - t.Fatalf("failed to unmarshal top calls gasUsed: %v", err) - } - if uint64(topCall.GasUsed) != vmRet.UsedGas { - t.Fatalf("top call has invalid gasUsed. have: %d want: %d", topCall.GasUsed, vmRet.UsedGas) - } - }) - } -} - -func BenchmarkTracers(b *testing.B) { - files, err := os.ReadDir(filepath.Join("testdata", "call_tracer")) - if err != nil { - b.Fatalf("failed to retrieve tracer test suite: %v", err) - } - for _, file := range files { - if !strings.HasSuffix(file.Name(), ".json") { - continue - } - b.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(b *testing.B) { - blob, err := os.ReadFile(filepath.Join("testdata", "call_tracer", file.Name())) - if err != nil { - b.Fatalf("failed to read testcase: %v", err) - } - test := new(callTracerTest) - if err := json.Unmarshal(blob, test); err != nil { - b.Fatalf("failed to parse testcase: %v", err) - } - benchTracer("callTracer", test, b) - }) - } -} - -func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { - // Configure a blockchain with the given prestate - tx := new(types.Transaction) - if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil { - b.Fatalf("failed to parse testcase input: %v", err) - } - signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - origin, _ := signer.Sender(tx) - txContext := vm.TxContext{ - Origin: origin, - GasPrice: tx.GasPrice(), - } - context := vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - } - msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) - if err != nil { - b.Fatalf("failed to prepare transaction for tracing: %v", err) - } - state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) - defer state.Close() - - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil) - if err != nil { - b.Fatalf("failed to create call tracer: %v", err) - } - evm := vm.NewEVM(context, txContext, state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) - snap := state.StateDB.Snapshot() - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err = st.TransitionDb(); err != nil { - b.Fatalf("failed to execute transaction: %v", err) - } - if _, err = tracer.GetResult(); err != nil { - b.Fatal(err) - } - state.StateDB.RevertToSnapshot(snap) - } -} - -func TestInternals(t *testing.T) { - var ( - config = params.TestLaunchConfig - to = common.HexToAddress("0x00000000000000000000000000000000deadbeef") - origin = common.HexToAddress("0x00000000000000000000000000000000feed") - txContext = vm.TxContext{ - Origin: origin, - GasPrice: big.NewInt(1), - } - context = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: common.Address{}, - BlockNumber: new(big.Int).SetUint64(8000000), - Time: 5, - Difficulty: big.NewInt(0x30000), - GasLimit: uint64(6000000), - } - ) - mkTracer := func(name string, cfg json.RawMessage) tracers.Tracer { - tr, err := tracers.DefaultDirectory.New(name, nil, cfg) - if err != nil { - t.Fatalf("failed to create call tracer: %v", err) - } - return tr - } - - for _, tc := range []struct { - name string - code []byte - tracer tracers.Tracer - want string - }{ - { - // TestZeroValueToNotExitCall tests the calltracer(s) on the following: - // Tx to A, A calls B with zero value. B does not already exist. - // Expected: that enter/exit is invoked and the inner call is shown in the result - name: "ZeroValueToNotExitCall", - code: []byte{ - byte(vm.PUSH1), 0x0, byte(vm.DUP1), byte(vm.DUP1), byte(vm.DUP1), // in and outs zero - byte(vm.DUP1), byte(vm.PUSH1), 0xff, byte(vm.GAS), // value=0,address=0xff, gas=GAS - byte(vm.CALL), - }, - tracer: mkTracer("callTracer", nil), - want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x54d8","to":"0x00000000000000000000000000000000deadbeef","input":"0x","calls":[{"from":"0x00000000000000000000000000000000deadbeef","gas":"0xe01a","gasUsed":"0x0","to":"0x00000000000000000000000000000000000000ff","input":"0x","value":"0x0","type":"CALL"}],"value":"0x0","type":"CALL"}`, - }, - { - name: "Stack depletion in LOG0", - code: []byte{byte(vm.LOG3)}, - tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)), - want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x13880","to":"0x00000000000000000000000000000000deadbeef","input":"0x","error":"stack underflow (0 \u003c=\u003e 5)","value":"0x0","type":"CALL"}`, - }, - { - name: "Mem expansion in LOG0", - code: []byte{ - byte(vm.PUSH1), 0x1, - byte(vm.PUSH1), 0x0, - byte(vm.MSTORE), - byte(vm.PUSH1), 0xff, - byte(vm.PUSH1), 0x0, - byte(vm.LOG0), - }, - tracer: mkTracer("callTracer", json.RawMessage(`{ "withLog": true }`)), - want: `{"from":"0x000000000000000000000000000000000000feed","gas":"0x13880","gasUsed":"0x5b9e","to":"0x00000000000000000000000000000000deadbeef","input":"0x","logs":[{"address":"0x00000000000000000000000000000000deadbeef","topics":[],"data":"0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","position":"0x0"}],"value":"0x0","type":"CALL"}`, - }, - { - // Leads to OOM on the prestate tracer - name: "Prestate-tracer - CREATE2 OOM", - code: []byte{ - byte(vm.PUSH1), 0x1, - byte(vm.PUSH1), 0x0, - byte(vm.MSTORE), - byte(vm.PUSH1), 0x1, - byte(vm.PUSH5), 0xff, 0xff, 0xff, 0xff, 0xff, - byte(vm.PUSH1), 0x1, - byte(vm.PUSH1), 0x0, - byte(vm.CREATE2), - byte(vm.PUSH1), 0xff, - byte(vm.PUSH1), 0x0, - byte(vm.LOG0), - }, - tracer: mkTracer("prestateTracer", nil), - want: `{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x000000000000000000000000000000000000feed":{"balance":"0x1c6bf52647880"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"}}`, - }, - { - // CREATE2 which requires padding memory by prestate tracer - name: "Prestate-tracer - CREATE2 Memory padding", - code: []byte{ - byte(vm.PUSH1), 0x1, - byte(vm.PUSH1), 0x0, - byte(vm.MSTORE), - byte(vm.PUSH1), 0x1, - byte(vm.PUSH1), 0xff, - byte(vm.PUSH1), 0x1, - byte(vm.PUSH1), 0x0, - byte(vm.CREATE2), - byte(vm.PUSH1), 0xff, - byte(vm.PUSH1), 0x0, - byte(vm.LOG0), - }, - tracer: mkTracer("prestateTracer", nil), - want: `{"0x0000000000000000000000000000000000000000":{"balance":"0x0"},"0x000000000000000000000000000000000000feed":{"balance":"0x1c6bf52647880"},"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0"},"0x91ff9a805d36f54e3e272e230f3e3f5c1b330804":{"balance":"0x0"}}`, - }, - } { - t.Run(tc.name, func(t *testing.T) { - state := tests.MakePreState(rawdb.NewMemoryDatabase(), - types.GenesisAlloc{ - to: types.GenesisAccount{ - Code: tc.code, - }, - origin: types.GenesisAccount{ - Balance: big.NewInt(500000000000000), - }, - }, false, rawdb.HashScheme) - defer state.Close() - - evm := vm.NewEVM(context, txContext, state.StateDB, config, vm.Config{Tracer: tc.tracer}) - msg := &core.Message{ - To: &to, - From: origin, - Value: big.NewInt(0), - GasLimit: 80000, - GasPrice: big.NewInt(0), - GasFeeCap: big.NewInt(0), - GasTipCap: big.NewInt(0), - SkipAccountChecks: false, - } - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(msg.GasLimit)) - if _, err := st.TransitionDb(); err != nil { - t.Fatalf("test %v: failed to execute transaction: %v", tc.name, err) - } - // Retrieve the trace result and compare against the expected - res, err := tc.tracer.GetResult() - if err != nil { - t.Fatalf("test %v: failed to retrieve trace result: %v", tc.name, err) - } - if string(res) != tc.want { - t.Errorf("test %v: trace mismatch\n have: %v\n want: %v\n", tc.name, string(res), tc.want) - } - }) - } -} diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go deleted file mode 100644 index b9be17981b..0000000000 --- a/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ /dev/null @@ -1,216 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -package tracetest - -import ( - "encoding/json" - "fmt" - "math/big" - "os" - "path/filepath" - "reflect" - "strings" - "testing" - - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/tests" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rlp" - - // Force-load the native, to trigger registration - "github.com/ava-labs/coreth/eth/tracers" -) - -// flatCallTrace is the result of a callTracerParity run. -type flatCallTrace struct { - Action flatCallTraceAction `json:"action"` - BlockHash common.Hash `json:"-"` - BlockNumber uint64 `json:"-"` - Error string `json:"error,omitempty"` - Result flatCallTraceResult `json:"result,omitempty"` - Subtraces int `json:"subtraces"` - TraceAddress []int `json:"traceAddress"` - TransactionHash common.Hash `json:"-"` - TransactionPosition uint64 `json:"-"` - Type string `json:"type"` - Time string `json:"-"` -} - -type flatCallTraceAction struct { - Author common.Address `json:"author,omitempty"` - RewardType string `json:"rewardType,omitempty"` - SelfDestructed common.Address `json:"address,omitempty"` - Balance hexutil.Big `json:"balance,omitempty"` - CallType string `json:"callType,omitempty"` - CreationMethod string `json:"creationMethod,omitempty"` - From common.Address `json:"from,omitempty"` - Gas hexutil.Uint64 `json:"gas,omitempty"` - Init hexutil.Bytes `json:"init,omitempty"` - Input hexutil.Bytes `json:"input,omitempty"` - RefundAddress common.Address `json:"refundAddress,omitempty"` - To common.Address `json:"to,omitempty"` - Value hexutil.Big `json:"value,omitempty"` -} - -type flatCallTraceResult struct { - Address common.Address `json:"address,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` - GasUsed hexutil.Uint64 `json:"gasUsed,omitempty"` - Output hexutil.Bytes `json:"output,omitempty"` -} - -// flatCallTracerTest defines a single test to check the call tracer against. -type flatCallTracerTest struct { - Genesis core.Genesis `json:"genesis"` - Context callContext `json:"context"` - Input string `json:"input"` - TracerConfig json.RawMessage `json:"tracerConfig"` - Result []flatCallTrace `json:"result"` -} - -func flatCallTracerTestRunner(tracerName string, filename string, dirPath string, t testing.TB) error { - // Call tracer test found, read if from disk - blob, err := os.ReadFile(filepath.Join("testdata", dirPath, filename)) - if err != nil { - return fmt.Errorf("failed to read testcase: %v", err) - } - test := new(flatCallTracerTest) - if err := json.Unmarshal(blob, test); err != nil { - return fmt.Errorf("failed to parse testcase: %v", err) - } - // Configure a blockchain with the given prestate - tx := new(types.Transaction) - if err := rlp.DecodeBytes(common.FromHex(test.Input), tx); err != nil { - return fmt.Errorf("failed to parse testcase input: %v", err) - } - signer := types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - context := vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - } - state := tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) - defer state.Close() - - // Create the tracer, the EVM environment and run it - tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig) - if err != nil { - return fmt.Errorf("failed to create call tracer: %v", err) - } - msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) - if err != nil { - return fmt.Errorf("failed to prepare transaction for tracing: %v", err) - } - evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - - if _, err = st.TransitionDb(); err != nil { - return fmt.Errorf("failed to execute transaction: %v", err) - } - - // Retrieve the trace result and compare against the etalon - res, err := tracer.GetResult() - if err != nil { - return fmt.Errorf("failed to retrieve trace result: %v", err) - } - ret := make([]flatCallTrace, 0) - if err := json.Unmarshal(res, &ret); err != nil { - return fmt.Errorf("failed to unmarshal trace result: %v", err) - } - if !jsonEqualFlat(ret, test.Result) { - t.Logf("tracer name: %s", tracerName) - - // uncomment this for easier debugging - // have, _ := json.MarshalIndent(ret, "", " ") - // want, _ := json.MarshalIndent(test.Result, "", " ") - // t.Logf("trace mismatch: \nhave %+v\nwant %+v", string(have), string(want)) - - // uncomment this for harder debugging <3 meowsbits - // lines := deep.Equal(ret, test.Result) - // for _, l := range lines { - // t.Logf("%s", l) - // t.FailNow() - // } - - t.Fatalf("trace mismatch: \nhave %+v\nwant %+v", ret, test.Result) - } - return nil -} - -// Iterates over all the input-output datasets in the tracer parity test harness and -// runs the Native tracer against them. -func TestFlatCallTracerNative(t *testing.T) { - testFlatCallTracer("flatCallTracer", "call_tracer_flat", t) -} - -func testFlatCallTracer(tracerName string, dirPath string, t *testing.T) { - files, err := os.ReadDir(filepath.Join("testdata", dirPath)) - if err != nil { - t.Fatalf("failed to retrieve tracer test suite: %v", err) - } - for _, file := range files { - if !strings.HasSuffix(file.Name(), ".json") { - continue - } - t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) { - t.Parallel() - - err := flatCallTracerTestRunner(tracerName, file.Name(), dirPath, t) - if err != nil { - t.Fatal(err) - } - }) - } -} - -// jsonEqual is similar to reflect.DeepEqual, but does a 'bounce' via json prior to -// comparison -func jsonEqualFlat(x, y interface{}) bool { - xTrace := new([]flatCallTrace) - yTrace := new([]flatCallTrace) - if xj, err := json.Marshal(x); err == nil { - json.Unmarshal(xj, xTrace) - } else { - return false - } - if yj, err := json.Marshal(y); err == nil { - json.Unmarshal(yj, yTrace) - } else { - return false - } - return reflect.DeepEqual(xTrace, yTrace) -} - -func BenchmarkFlatCallTracer(b *testing.B) { - files, err := filepath.Glob("testdata/call_tracer_flat/*.json") - if err != nil { - b.Fatalf("failed to read testdata: %v", err) - } - - for _, file := range files { - filename := strings.TrimPrefix(file, "testdata/call_tracer_flat/") - b.Run(camel(strings.TrimSuffix(filename, ".json")), func(b *testing.B) { - for n := 0; n < b.N; n++ { - err := flatCallTracerTestRunner("flatCallTracer", filename, "call_tracer_flat", b) - if err != nil { - b.Fatal(err) - } - } - }) - } -} diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go deleted file mode 100644 index fd4231b002..0000000000 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ /dev/null @@ -1,155 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package tracetest - -import ( - "encoding/json" - "math/big" - "os" - "path/filepath" - "strings" - "testing" - - "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ava-labs/coreth/tests" - "github.com/ethereum/go-ethereum/common" -) - -// prestateTrace is the result of a prestateTrace run. -type prestateTrace = map[common.Address]*account - -type account struct { - Balance string `json:"balance"` - Code string `json:"code"` - Nonce uint64 `json:"nonce"` - Storage map[common.Hash]common.Hash `json:"storage"` -} - -// testcase defines a single test to check the stateDiff tracer against. -type testcase struct { - Genesis *core.Genesis `json:"genesis"` - Context *callContext `json:"context"` - Input string `json:"input"` - TracerConfig json.RawMessage `json:"tracerConfig"` - Result interface{} `json:"result"` -} - -func TestPrestateTracerLegacy(t *testing.T) { - testPrestateDiffTracer("prestateTracerLegacy", "prestate_tracer_legacy", t) -} - -func TestPrestateTracer(t *testing.T) { - testPrestateDiffTracer("prestateTracer", "prestate_tracer", t) -} - -func TestPrestateWithDiffModeTracer(t *testing.T) { - testPrestateDiffTracer("prestateTracer", "prestate_tracer_with_diff_mode", t) -} - -func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { - files, err := os.ReadDir(filepath.Join("testdata", dirPath)) - if err != nil { - t.Fatalf("failed to retrieve tracer test suite: %v", err) - } - for _, file := range files { - if !strings.HasSuffix(file.Name(), ".json") { - continue - } - t.Run(camel(strings.TrimSuffix(file.Name(), ".json")), func(t *testing.T) { - t.Parallel() - - var ( - test = new(testcase) - tx = new(types.Transaction) - ) - // Call tracer test found, read if from disk - if blob, err := os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { - t.Fatalf("failed to read testcase: %v", err) - } else if err := json.Unmarshal(blob, test); err != nil { - t.Fatalf("failed to parse testcase: %v", err) - } - if err := tx.UnmarshalBinary(common.FromHex(test.Input)); err != nil { - t.Fatalf("failed to parse testcase input: %v", err) - } - // Configure a blockchain with the given prestate - var ( - signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) - context = vm.BlockContext{ - CanTransfer: core.CanTransfer, - Transfer: core.Transfer, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - BaseFee: test.Genesis.BaseFee, - } - state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) - ) - defer state.Close() - - tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), test.TracerConfig) - if err != nil { - t.Fatalf("failed to create call tracer: %v", err) - } - msg, err := core.TransactionToMessage(tx, signer, context.BaseFee) - if err != nil { - t.Fatalf("failed to prepare transaction for tracing: %v", err) - } - evm := vm.NewEVM(context, core.NewEVMTxContext(msg), state.StateDB, test.Genesis.Config, vm.Config{Tracer: tracer}) - st := core.NewStateTransition(evm, msg, new(core.GasPool).AddGas(tx.Gas())) - if _, err = st.TransitionDb(); err != nil { - t.Fatalf("failed to execute transaction: %v", err) - } - // Retrieve the trace result and compare against the expected - res, err := tracer.GetResult() - if err != nil { - t.Fatalf("failed to retrieve trace result: %v", err) - } - // The legacy javascript calltracer marshals json in js, which - // is not deterministic (as opposed to the golang json encoder). - if strings.HasSuffix(dirPath, "_legacy") { - // This is a tweak to make it deterministic. Can be removed when - // we remove the legacy tracer. - var x prestateTrace - json.Unmarshal(res, &x) - res, _ = json.Marshal(x) - } - want, err := json.Marshal(test.Result) - if err != nil { - t.Fatalf("failed to marshal test: %v", err) - } - if string(want) != string(res) { - t.Fatalf("trace mismatch\n have: %v\n want: %v\n", string(res), string(want)) - } - }) - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer/create.json deleted file mode 100644 index df0b2872b4..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/create.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "context": { - "difficulty": "3755480783", - "gasLimit": "5401723", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "number": "2294702", - "timestamp": "1513676146" - }, - "genesis": { - "alloc": { - "0x13e4acefe6a6700604929946e70e6443e4e73447": { - "balance": "0xcf3e0938579f000", - "code": "0x", - "nonce": "9", - "storage": {} - }, - "0x7dc9c9730689ff0b0fd506c67db815f12d90a448": { - "balance": "0x0", - "code": "0x", - "nonce": "0", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3757315409", - "extraData": "0x566961425443", - "gasLimit": "5406414", - "hash": "0xae107f592eebdd9ff8d6ba00363676096e6afb0e1007a7d3d0af88173077378d", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "mixHash": "0xc927aa05a38bc3de864e95c33b3ae559d3f39c4ccd51cef6f113f9c50ba0caf1", - "nonce": "0x93363bbd2c95f410", - "number": "2294701", - "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c", - "timestamp": "1513676127", - "totalDifficulty": "7160808139332585" - }, - "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f", - "result": { - "from": "0x13e4acefe6a6700604929946e70e6443e4e73447", - "gas": "0x897be", - "gasUsed": "0x897be", - "input": "0x606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a11", - "output": "0x606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029", - "to": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448", - "type": "CREATE", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json deleted file mode 100644 index 975616064a..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/deep_calls.json +++ /dev/null @@ -1,409 +0,0 @@ -{ - "context": { - "difficulty": "117066904", - "gasLimit": "4712384", - "miner": "0x1977c248e1014cc103929dd7f154199c916e39ec", - "number": "25001", - "timestamp": "1479891545" - }, - "genesis": { - "alloc": { - "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a600035046302d05d3f811461008a5780630accce061461009c5780631ab9075a146100c757806331ed274614610102578063645a3b7214610133578063772fdae314610155578063a7f4377914610180578063ae5f80801461019e578063c9bded21146101ea578063f905c15a14610231575b61023a610002565b61023c600054600160a060020a031681565b61023a600435602435604435606435608435600254600160a060020a03166000141561024657610002565b61023a600435600254600160a060020a03166000148015906100f8575060025433600160a060020a03908116911614155b156102f457610002565b61023a60043560243560443560643560843560a43560c435600254600160a060020a03166000141561031657610002565b61023a600435602435600254600160a060020a0316600014156103d057610002565b61023a600435602435604435606435608435600254600160a060020a03166000141561046157610002565b61023a60025433600160a060020a0390811691161461051657610002565b61023a6004356024356044356060828152600160a060020a0382169060ff8516907fa6c2f0913db6f79ff0a4365762c61718973b3413d6e40382e704782a9a5099f690602090a3505050565b61023a600435602435600160a060020a038116606090815260ff8316907fee6348a7ec70f74e3d6cba55a53e9f9110d180d7698e9117fc466ae29a43e34790602090a25050565b61023c60035481565b005b6060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061029d57610002565b60408051858152602081018390528151600160a060020a03858116939087169260ff8a16927f5a690ecd0cb15c1c1fd6b6f8a32df0d4f56cb41a54fea7e94020f013595de796929181900390910190a45050505050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061036d57610002565b6040805186815260208101869052808201859052606081018490529051600160a060020a03831691889160ff8b16917fd65d9ddafbad8824e2bbd6f56cc9f4ac27ba60737035c10a321ea2f681c94d47919081900360800190a450505050505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061042757610002565b60408051828152905183917fa9c6cbc4bd352a6940479f6d802a1001550581858b310d7f68f7bea51218cda6919081900360200190a25050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104b857610002565b80600160a060020a031684600160a060020a03168660ff167f69bdaf789251e1d3a0151259c0c715315496a7404bce9fd0b714674685c2cab78686604051808381526020018281526020019250505060405180910390a45050505050565b600254600160a060020a0316ff", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0x2cccf5e0538493c235d1c5ef6580f77d99e91396": { - "balance": "0x0", - "code": "0x606060405236156100775760e060020a600035046302d05d3f811461007f57806313bc6d4b146100915780633688a877146100b95780635188f9961461012f5780637eadc976146101545780638ad79680146101d3578063a43e04d814610238578063a7f437791461025e578063e16c7d981461027c575b61029f610002565b6102a1600054600160a060020a031681565b6102be600435600160a060020a03811660009081526002602052604090205460ff165b919050565b6102d26004356040805160208181018352600080835284815260038252835190849020805460026001821615610100026000190190911604601f8101849004840283018401909552848252929390929183018282801561037d5780601f106103525761010080835404028352916020019161037d565b61029f6004356024356000805433600160a060020a039081169116146104a957610002565b61034060043560008181526001602090815260408083205481517ff905c15a0000000000000000000000000000000000000000000000000000000081529151600160a060020a03909116928392839263f905c15a92600483810193919291829003018189876161da5a03f1156100025750506040515195945050505050565b60408051602060248035600481810135601f810185900485028601850190965285855261029f9581359591946044949293909201918190840183828082843750949650505050505050600054600160a060020a0390811633909116146104f657610002565b61029f6004355b600080548190600160a060020a0390811633909116146105a457610002565b61029f60005433600160a060020a0390811691161461072957610002565b6102a1600435600081815260016020526040902054600160a060020a03166100b4565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505090506100b4565b506000828152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a038581168086526002909352818520805460ff191690941790935580517f1ab9075a0000000000000000000000000000000000000000000000000000000081523090931660048401525184939192631ab9075a926024828101939192829003018183876161da5a03f11561000257505060408051602081018690528082019290925243606083015260808083526003908301527f414444000000000000000000000000000000000000000000000000000000000060a0830152517f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d39181900360c00190a15b505050565b600083815260016020526040902054600160a060020a03838116911614156104d0576104a4565b600083815260016020526040812054600160a060020a031614610389576103898361023f565b600082815260036020908152604082208054845182855293839020919360026001831615610100026000190190921691909104601f90810184900483019391929186019083901061056a57805160ff19168380011785555b5061059a9291505b808211156105a05760008155600101610556565b8280016001018555821561054e579182015b8281111561054e57825182600050559160200191906001019061057c565b50505050565b5090565b600083815260016020526040812054600160a060020a031614156105c757610002565b50506000818152600160205260408082205481517fa7f437790000000000000000000000000000000000000000000000000000000081529151600160a060020a0391909116928392839263a7f4377992600483810193919291829003018183876161da5a03f11561000257505050600160005060008460001916815260200190815260200160002060006101000a815490600160a060020a0302191690556002600050600083600160a060020a0316815260200190815260200160002060006101000a81549060ff02191690557f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d383834360405180806020018560001916815260200184600160a060020a03168152602001838152602001828103825260038152602001807f44454c000000000000000000000000000000000000000000000000000000000081526020015060200194505050505060405180910390a1505050565b600054600160a060020a0316ff", - "nonce": "1", - "storage": { - "0x0684ac65a9fa32414dda56996f4183597d695987fdb82b145d722743891a6fe8": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "0x1cd76f78169a420d99346e3501dd3e541622c38a226f9b63e01cfebc69879dc7": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "0x8e54a4494fe5da016bfc01363f4f6cdc91013bb5434bd2a4a3359f13a23afa2f": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf", - "0x94edf7f600ba56655fd65fca1f1424334ce369326c1dc3e53151dcd1ad06bc13": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xbbee47108b275f55f98482c6800f6372165e88b0330d3f5dae6419df4734366c": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "0xd38c0c4e84de118cfdcc775130155d83b8bbaaf23dc7f3c83a626b10473213bd": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xfb3aa5c655c2ec9d40609401f88d505d1da61afaa550e36ef5da0509ada257ba": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113" - } - }, - "0x3e9286eafa2db8101246c2131c09b49080d00690": { - "balance": "0x0", - "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063056d4470146100e957806316c66cc61461010c5780631ab9075a146101935780633ae1005c146101ce57806358541662146101fe5780635ed61af014610231578063644e3b791461025457806384dbac3b146102db578063949ae479146102fd5780639859387b14610321578063a7f4377914610340578063ab03fc261461035e578063e8161b7814610385578063e964d4e114610395578063f905c15a146103a5578063f92eb774146103ae575b6103be610002565b6103c0600054600160a060020a031681565b6103be6004356002546000908190600160a060020a031681141561040357610002565b6103dd60043560006108365b6040805160025460e360020a631c2d8fb30282527f636f6e747261637464620000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435600254600160a060020a03166000148015906101c4575060025433600160a060020a03908116911614155b1561088d57610002565b6103be600435602435604435606435600254600090819081908190600160a060020a03168114156108af57610002565b6103c0600435602435604435606435608435600254600090819081908190600160a060020a03168114156110e857610002565b6103be6004356002546000908190600160a060020a03168114156115ec57610002565b6103c06004356000611b635b6040805160025460e360020a631c2d8fb30282527f6d61726b6574646200000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435602435600254600160a060020a031660001415611bb557610002565b6103be600435602435600254600090600160a060020a0316811415611d2e57610002565b6103be600435600254600160a060020a031660001415611fc657610002565b6103be60025433600160a060020a0390811691161461207e57610002565b6103be600435602435604435600254600090600160a060020a031681141561208c57610002565b6103dd60043560006124b8610260565b6103c0600435600061250a610118565b6103f160035481565b6103f16004356000612561610260565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061046557610002565b8291506104e55b6040805160025460e360020a631c2d8fb30282527f63706f6f6c00000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f115610002575050604051519150505b90565b600160a060020a031663b2206e6d83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fb2206e6d0000000000000000000000000000000000000000000000000000000082526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f11561000257505060405151915061059b90506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f115610002575050506107355b6040805160025460e360020a631c2d8fb30282527f6c6f676d6772000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b50826120ee5b6040805160025460e360020a631c2d8fb30282527f6163636f756e7463746c0000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316630accce06600684600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150866040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050505050565b600160a060020a03166316c66cc6836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150505b919050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061091157610002565b87935061091c610260565b600160a060020a031663bdbdb08685600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fbdbdb0860000000000000000000000000000000000000000000000000000000082526004820152602481018a905290516044808301935060209282900301816000876161da5a03f1156100025750506040515193506109ca90506106ba565b600160a060020a03166381982a7a8885876040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610a3661046c565b600160a060020a03166308636bdb85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517f08636bdb000000000000000000000000000000000000000000000000000000008252600482015260248101889052604481019290925251606482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919450600160a060020a03871692506314baa1b6916024828101926000929190829003018183876161da5a03f11561000257505050610b3561046c565b600160a060020a0316630a3b6ede85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038d16602482015290516044808301935060209282900301816000876161da5a03f115610002575050604051519150610bd590506106ba565b600160a060020a031663d5b205ce87838b6040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610c41610118565b600160a060020a031663988db79c888a6040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050610ca5610260565b600160a060020a031663f4f2821b896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610d6f5b6040805160025460e360020a631c2d8fb30282527f747261646564620000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316635f539d69896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610dc2610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928e9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610ec5610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928d9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610fc8610639565b600160a060020a031663645a3b7285600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151905061101e610260565b600160a060020a031663f92eb77488600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f115610002575050505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061114a57610002565b604051600254600160a060020a0316908a908a908a908a908a90611579806125b38339018087600160a060020a0316815260200186600160a060020a03168152602001856000191681526020018481526020018381526020018281526020019650505050505050604051809103906000f092506111c5610118565b600160a060020a031663b9858a288a856040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611229610260565b600160a060020a0316635188f99689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611288610260565b600160a060020a031663bdbdb08689896040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515192506112e590506106ba565b600160a060020a03166346d88e7d8a858a6040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506000604051808303816000876161da5a03f115610002575050506113516106ba565b600160a060020a03166381982a7a8a84866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050506113bd61046c565b600160a060020a0316632b58469689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f1156100025750505061141c61046c565b600160a060020a03166308636bdb8984866040518460e060020a028152600401808460001916815260200183815260200182600160a060020a0316815260200193505050506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919350600160a060020a03861692506314baa1b6916024828101926000929190829003018183876161da5a03f115610002575050506114d3610639565b6040805160e160020a630566670302815260016004820152602481018b9052600160a060020a0386811660448301528c811660648301526000608483018190529251931692630accce069260a480840193919291829003018183876161da5a03f11561000257505050611544610639565b600160a060020a031663645a3b728961155b610260565b600160a060020a031663f92eb7748c6040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448084019360009350829003018183876161da5a03f1156100025750939a9950505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061164e57610002565b82915061165961046c565b600160a060020a0316630a3b6ede83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f1156100025750506040515191506116f990506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f1156100025750505061179b6106ba565b600160a060020a031663d653078983600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517ff1ff78a0000000000000000000000000000000000000000000000000000000008252915191929163f1ff78a09160048181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f1156100025750505061189f610260565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506118f2610118565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050611945610639565b600160a060020a0316630accce06600484600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da44689181870191602091908190038801816000876161da5a03f115610002575050506040518051906020015060006040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050611a48610639565b600160a060020a031663645a3b7283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611a9e610260565b600160a060020a031663f92eb77486600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b600160a060020a03166381738c59836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611c1757610002565b611c1f610260565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060405151159050611c7457610002565b611c7c610260565b600160a060020a0316632243118a836040518260e060020a02815260040180826000191681526020019150506000604051808303816000876161da5a03f11561000257505050611cca610639565b600160a060020a031663ae5f8080600184846040518460e060020a028152600401808481526020018360001916815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611d9057610002565b5081611d9a610260565b600160a060020a031663581d5d6084846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505050611df5610639565b600160a060020a0316630accce06600283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630566670302825260048201949094526024810193909352600160a060020a038816604484015260006064840181905260848401819052905160a4808501949293509091829003018183876161da5a03f11561000257505050611eab610639565b600160a060020a031663645a3b7282600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611f01610260565b600160a060020a031663f92eb77485600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061202857610002565b612030610118565b600160a060020a0316639859387b826040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505050565b600254600160a060020a0316ff5b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f11561000257505060405151151590506106b457610002565b600160a060020a031663d65307898383600160a060020a031663f1ff78a06040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fd6530789000000000000000000000000000000000000000000000000000000008252600160a060020a039485166004830152602482015292891660448401525160648381019360009350829003018183876161da5a03f115610002575050506121a5610118565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506121f8610cf4565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505061224b610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d028252915191928a9290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f1156100025750505080600160a060020a031663ea71b02d6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a031660001490506124b25761239f610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fea71b02d000000000000000000000000000000000000000000000000000000008252915191928a92909163ea71b02d91600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f115610002575050505b50505050565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663213fe2b7836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663f92eb774836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610888905056606060405260405160c08061157983396101206040819052825160805160a051935160e0516101005160008054600160a060020a03199081163317909155600180546005805484168817905560048a90556006869055600b8590556008849055909116861760a060020a60ff02191690554360038190556002558686526101408390526101608190529396929594919390929091600160a060020a033016917f76885d242fb71c6f74a7e717416e42eff4d96faf54f6de75c6a0a6bbd8890c6b91a230600160a060020a03167fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff600b600050546040518082815260200191505060405180910390a250505050505061145e8061011b6000396000f3606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "16", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0x70c9217d814985faef62b124420f8dfbddd96433": { - "balance": "0x4ef436dcbda6cd4a", - "code": "0x", - "nonce": "1634", - "storage": {} - }, - "0x7986bad81f4cbd9317f5a46861437dae58d69113": { - "balance": "0x0", - "code": "0x6060604052361561008d5760e060020a600035046302d05d3f811461009557806316c66cc6146100a75780631ab9075a146100d7578063213fe2b7146101125780639859387b1461013f578063988db79c1461015e578063a7f4377914610180578063b9858a281461019e578063c8e40fbf146101c0578063f4f2821b146101e8578063f905c15a14610209575b610212610002565b610214600054600160a060020a031681565b600160a060020a0360043581811660009081526005602052604081205461023193168114610257575060016101e3565b610212600435600254600160a060020a0316600014801590610108575060025433600160a060020a03908116911614155b1561025f57610002565b610214600435600160a060020a03811660009081526004602052604081205460ff16151561027557610002565b610212600435600254600160a060020a03166000141561029b57610002565b610212600435602435600254600160a060020a03166000141561050457610002565b61021260025433600160a060020a0390811691161461056757610002565b610212600435602435600254600160a060020a03166000141561057557610002565b610231600435600160a060020a03811660009081526004602052604090205460ff165b919050565b610212600435600254600090600160a060020a031681141561072057610002565b61024560035481565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060006101e3565b60028054600160a060020a031916821790555b50565b50600160a060020a038181166000908152600460205260409020546101009004166101e3565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506102fe57610002565b600160a060020a03811660009081526004602052604090205460ff161515610272576040516104028061092e833901809050604051809103906000f06004600050600083600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600083600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555050565b600160a060020a03821660009081526004602052604090205460ff1615156104725760405161040280610d30833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a03811660009081526006602052604090208054600160a060020a031916831790555b5050565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506103b957610002565b600254600160a060020a0316ff5b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506105d857610002565b600160a060020a03821660009081526004602052604090205460ff1615156106915760405161040280611132833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a031660009081526005602052604090208054600160a060020a0319169091179055565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f115610002575050604051511515905061078357610002565b50600160a060020a0381811660009081526005602090815260408083205490931680835260049091529190205460ff161561080f576040600081812054825160e260020a632e72bafd028152600160a060020a03868116600483015293516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260056020526040812054909116146108545760406000908120600160a060020a0384169091528054600160a060020a03191690555b50600160a060020a0381811660009081526006602090815260408083205490931680835260049091529190205460ff16156108e657600160a060020a038181166000908152604080518183205460e260020a632e72bafd028252868516600483015291516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260066020526040812054909116146105005760406000908120600160a060020a0384169091528054600160a060020a0319169055505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056", - "nonce": "7", - "storage": { - "0xffc4df2d4f3d2cffad590bed6296406ab7926ca9e74784f74a95191fa069a174": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433" - } - }, - "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f": { - "balance": "0x0", - "code": "0x606060405236156100ae5760e060020a600035046302d05d3f81146100b65780631ab9075a146100c85780632b68bb2d146101035780634cc927d7146101c557806351a34eb81461028e57806356ccb6f0146103545780635928d37f1461041d578063599efa6b146104e9578063759297bb146105b2578063771d50e11461067e578063a7f4377914610740578063f905c15a1461075e578063f92eb77414610767578063febf661214610836575b610902610002565b610904600054600160a060020a031681565b610902600435600254600160a060020a03166000148015906100f9575060025433600160a060020a03908116911614155b1561092057610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061094257610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610a0d57610002565b61090260043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ae957610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610bbc57610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610c9657610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610de057610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ebb57610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f9e57610002565b61090260025433600160a060020a0390811691161461106957610002565b61090e60035481565b61090e60043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750506040805180517ff92eb774000000000000000000000000000000000000000000000000000000008252600482018790529151919350600160a060020a038416925063f92eb774916024828101926020929190829003018188876161da5a03f11561000257505060405151949350505050565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061107757610002565b005b6060908152602090f35b60408051918252519081900360200190f35b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5ed61af000000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152925190959286169350635ed61af092602483810193919291829003018183876161da5a03f115610002575050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fab03fc2600000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015260248301899052808816604484015292519095928616935063ab03fc2692606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f949ae47900000000000000000000000000000000000000000000000000000000825233600160a060020a0390811660048401526024830188905292519095928616935063949ae47992604483810193919291829003018183876161da5a03f11561000257505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f46d88e7d000000000000000000000000000000000000000000000000000000008252600160a060020a0380891660048401523381166024840152604483018890529251909592861693506346d88e7d92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5315cdde00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a16602484015260448301889052925190959286169350635315cdde92606483810193919291829003018183876161da5a03f115610002575050604080517f5928d37f00000000000000000000000000000000000000000000000000000000815233600160a060020a03908116600483015287166024820152604481018690529051635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fe68e401c00000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015280891660248401526044830188905292519095928616935063e68e401c92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5152f381000000000000000000000000000000000000000000000000000000008252600160a060020a03808a1660048401528089166024840152604483018890523381166064840152925190959286169350635152f38192608483810193919291829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f056d447000000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015292519095928616935063056d447092602483810193919291829003018183876161da5a03f115610002575050505050565b600254600160a060020a0316ff5b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f3ae1005c00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a166024840152808916604484015260648301889052925190959286169350633ae1005c92608483810193919291829003018183876161da5a03f11561000257505050505050505056", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": { - "balance": "0x0", - "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000006195", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5842545553440000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000" - } - }, - "0xcf00ffd997ad14939736f026006498e3f099baaf": { - "balance": "0x0", - "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063031e7f5d146100e95780631ab9075a1461010b5780632243118a1461014657806327aad68a1461016557806338a699a4146101da5780635188f996146101f8578063581d5d601461021e57806381738c5914610246578063977da54014610269578063a07421ce14610288578063a7f43779146102be578063bdbdb086146102dc578063e1c7111914610303578063f4f2821b14610325578063f905c15a1461034a578063f92eb77414610353575b610387610002565b610389600054600160a060020a031681565b610387600435602435600254600160a060020a0316600014156103a857610002565b610387600435600254600160a060020a031660001480159061013c575060025433600160a060020a03908116911614155b1561042957610002565b610387600435600254600160a060020a03166000141561044b57610002565b6102ac60043560008181526004602081815260408320547f524d81d3000000000000000000000000000000000000000000000000000000006060908152610100909104600160a060020a031692839263524d81d3926064928188876161da5a03f1156100025750506040515192506103819050565b61039c60043560008181526004602052604090205460ff165b919050565b6103876004356024356002546000908190600160a060020a031681141561079457610002565b61038760043560243560025460009081908190600160a060020a031681141561080457610002565b61038960043560008181526004602052604081205460ff1615156109e357610002565b610387600435600254600160a060020a0316600014156109fb57610002565b600435600090815260096020526040902054670de0b6b3a764000090810360243502045b60408051918252519081900360200190f35b61038760025433600160a060020a03908116911614610a9257610002565b600435600090815260086020526040902054670de0b6b3a7640000602435909102046102ac565b610387600435602435600254600160a060020a031660001415610aa057610002565b61038760043560025460009081908190600160a060020a0316811415610b3657610002565b6102ac60035481565b6102ac600435600081815260076020908152604080832054600690925290912054670de0b6b3a76400000204805b50919050565b005b600160a060020a03166060908152602090f35b15156060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506103fe57610002565b60008281526004602052604090205460ff16151561041b57610002565b600860205260406000205550565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104a157610002565b604080516000838152600460205291909120805460ff1916600117905561040280610de2833901809050604051809103906000f0600460005060008360001916815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555066470de4df8200006008600050600083600019168152602001908152602001600020600050819055506703782dace9d9000060096000506000836000191681526020019081526020016000206000508190555050565b600460005060008560001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151821415905061060057838152600660209081526040808320839055600790915281208190555b81600160a060020a0316630a3b0a4f846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050600160a060020a038316808252600560209081526040808420879055805160e160020a6364a81ff102815290518694670de0b6b3a7640000949363c9503fe29360048181019492939183900301908290876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008660001916815260200190815260200160002060008282825054019250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000866000191681526020019081526020016000206000828282505401925050819055505b50505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f11561000257505060405151151590506107e957610002565b8381526004602052604081205460ff16151561056657610002565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f115610002575050604051511515905061085957610002565b849250670de0b6b3a764000083600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575060408051805160e160020a6364a81ff102825291519189028590049650600481810192602092909190829003018188876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b9391600481810192602092909190829003018189876161da5a03f115610002575050506040518051906020015002049050806006600050600085600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750604080518051855260208681528286208054989098039097557f2e94420f00000000000000000000000000000000000000000000000000000000815290518896600483810193919291829003018187876161da5a03f115610002575050604080515183526020939093525020805490910190555050505050565b60409020546101009004600160a060020a03166101f3565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610a5157610002565b60008181526004602052604090205460ff161515610a6e57610002565b6040600020805474ffffffffffffffffffffffffffffffffffffffffff1916905550565b600254600160a060020a0316ff5b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610af657610002565b60008281526004602052604090205460ff161515610b1357610002565b670de0b6b3a7640000811115610b2857610002565b600960205260406000205550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f1156100025750506040515115159050610b8b57610002565b600160a060020a038416815260056020908152604080832054808452600490925282205490935060ff161515610bc057610002565b600460005060008460001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663b9caebf4856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506005600050600085600160a060020a0316815260200190815260200160002060005060009055839050600082600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519190911115905061078e57670de0b6b3a764000081600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008560001916815260200190815260200160002060008282825054039250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000856000191681526020019081526020016000206000828282505403925050819055505050505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056", - "nonce": "3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x3571d73f14f31a1463bd0a2f92f7fde1653d4e1ead7aedf4b0a5df02f16092ab": "0x0000000000000000000000000000000000000000000007d634e4c55188be0000", - "0x4e64fe2d1b72d95a0a31945cc6e4f4e524ac5ad56d6bd44a85ec7bc9cc0462c0": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000" - } - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "117124093", - "extraData": "0xd5830105008650617269747986312e31322e31826d61", - "gasLimit": "4707788", - "hash": "0xad325e4c49145fb7a4058a68ac741cc8607a71114e23fc88083c7e881dd653e7", - "miner": "0x00714b9ac97fd6bd9325a059a70c9b9fa94ce050", - "mixHash": "0x0af918f65cb4af04b608fc1f14a849707696986a0e7049e97ef3981808bcc65f", - "nonce": "0x38dee147326a8d40", - "number": "25000", - "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b", - "timestamp": "1479891517", - "totalDifficulty": "1895410389427" - }, - "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065", - "result": { - "calls": [ - { - "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "gas": "0x31217", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e7472616374617069000000000000000000000000000000000000000000", - "output": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x2a68d", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x23ac9", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e7472616374646200000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x23366", - "gasUsed": "0x273", - "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x7986bad81f4cbd9317f5a46861437dae58d69113", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x29f35", - "gasUsed": "0xf8d", - "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x28a9e", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x21d79", - "gasUsed": "0x24d", - "input": "0x13bc6d4b000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x2165b", - "gasUsed": "0x334", - "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000", - "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1a8e8", - "gasUsed": "0x24d", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1a2c6", - "gasUsed": "0x3cb", - "input": "0xc9503fe2", - "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x19b72", - "gasUsed": "0x3cb", - "input": "0xc9503fe2", - "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x19428", - "gasUsed": "0x305", - "input": "0x6f265b93", - "output": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x18d45", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1734e", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x20ee1", - "gasUsed": "0x5374", - "input": "0x581d5d60000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1b6c1", - "gasUsed": "0x334", - "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1af69", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "gas": "0x143a5", - "gasUsed": "0x24d", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1a91d", - "gasUsed": "0x12fa", - "input": "0x0accce0600000000000000000000000000000000000000000000000000000000000000025842545553440000000000000000000000000000000000000000000000000000000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x19177", - "gasUsed": "0x334", - "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x18a22", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x18341", - "gasUsed": "0x334", - "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000", - "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x17bec", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1764e", - "gasUsed": "0x45c", - "input": "0xf92eb7745842545553440000000000000000000000000000000000000000000000000000", - "output": "0x00000000000000000000000000000000000000000000002816d180e30c390000", - "to": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "gas": "0x108ba", - "gasUsed": "0x24d", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x16e62", - "gasUsed": "0xebb", - "input": "0x645a3b72584254555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002816d180e30c390000", - "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x283b9", - "gasUsed": "0xc51c", - "input": "0x949ae479000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "gas": "0x30b4a", - "gasUsed": "0xedb7", - "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x70c9217d814985faef62b124420f8dfbddd96433", - "gas": "0x3d090", - "gasUsed": "0x1810b", - "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json deleted file mode 100644 index 6a2cda7dc9..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/delegatecall.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "context": { - "difficulty": "31927752", - "gasLimit": "4707788", - "miner": "0x5659922ce141eedbc2733678f9806c77b4eebee8", - "number": "11495", - "timestamp": "1479735917" - }, - "genesis": { - "alloc": { - "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a60003504630a0313a981146100875780630a3b0a4f146101095780630cd40fea1461021257806329092d0e1461021f5780634cd06a5f146103295780635dbe47e8146103395780637a9e5410146103d9578063825db5f7146103e6578063a820b44d146103f3578063efa52fb31461047a575b610002565b34610002576104fc600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a26333556e849091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f415610002575050604051519150505b919050565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f21ce24d4000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926321ce24d49260448082019391829003018186803b156100025760325a03f415610002575050505b50565b3461000257610512600181565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f89489a87000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926389489a879260448082019391829003018186803b156100025760325a03f4156100025750505061020f565b3461000257610528600435610403565b34610002576104fc600435604080516000602091820181905282517f7d65837a00000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152925190927342b02b5deeb78f34cd5ac896473b63e6c99a71a292637d65837a92604480840193829003018186803b156100025760325a03f4156100025750506040515191506101049050565b3461000257610512600c81565b3461000257610512600081565b3461000257610528600061055660005b600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263685a1f3c9091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b346100025761053a600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263f775b6b59091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b604080519115158252519081900360200190f35b005b6040805160ff9092168252519081900360200190f35b60408051918252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b90509056", - "nonce": "1", - "storage": { - "0x4d140b25abf3c71052885c66f73ce07cff141c1afabffdaf5cba04d625b7ebcc": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - }, - "0x269296dddce321a6bcbaa2f0181127593d732cba": { - "balance": "0x0", - "code": "0x606060405236156101275760e060020a60003504630cd40fea811461012c578063173825d9146101395780631849cb5a146101c7578063285791371461030f5780632a58b3301461033f5780632cb0d48a146103565780632f54bf6e1461036a578063332b9f061461039d5780633ca8b002146103c55780633df4ddf4146103d557806341c0e1b5146103f457806347799da81461040557806362a51eee1461042457806366907d13146104575780637065cb48146104825780637a9e541014610496578063825db5f7146104a3578063949d225d146104b0578063a51687df146104c7578063b4da4e37146104e6578063b4e6850b146104ff578063bd7474ca14610541578063e75623d814610541578063e9938e1114610555578063f5d241d314610643575b610002565b3461000257610682600181565b34610002576106986004356106ff335b60006001600a9054906101000a9004600160a060020a0316600160a060020a0316635dbe47e8836000604051602001526040518260e060020a0281526004018082600160a060020a03168152602001915050602060405180830381600087803b156100025760325a03f1156100025750506040515191506103989050565b3461000257604080516101008082018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a0360043581168752600586529589902089519788018a528054808816808a52605060020a91829004600160a060020a0316978a01889052600183015463ffffffff8082169d8c018e905264010000000082048116988c01899052604060020a90910416958a018690526002830154948a01859052600390920154808916938a01849052049096169690970186905293969495949293604080516001605060020a03998a16815297891660208901529590971686860152600160a060020a03909316606086015263ffffffff9182166080860152811660a08501521660c083015260e08201929092529051908190036101000190f35b346100025761069a60043560018054600091829160ff60f060020a909104161515141561063d5761072833610376565b34610002576106ae6004546001605060020a031681565b34610002576106986004356108b333610149565b346100025761069a6004355b600160a060020a03811660009081526002602052604090205460ff1615156001145b919050565b34610002576106986001805460ff60f060020a9091041615151415610913576108ed33610376565b346100025761069a600435610149565b34610002576106ae6003546001605060020a03605060020a9091041681565b346100025761069861091533610149565b34610002576106ae6003546001605060020a0360a060020a9091041681565b346100025761069a60043560243560018054600091829160ff60f060020a909104161515141561095e5761092633610376565b34610002576106986004356001805460ff60f060020a909104161515141561072557610a8b33610376565b3461000257610698600435610aa533610149565b3461000257610682600c81565b3461000257610682600081565b34610002576106ae6003546001605060020a031681565b34610002576106ca600154600160a060020a03605060020a9091041681565b346100025761069a60015460ff60f060020a9091041681565b346100025761069a60043560243560443560643560843560a43560c43560018054600091829160ff60f060020a9091041615151415610b5857610ad233610376565b3461000257610698600435610bd633610149565b34610002576106e6600435604080516101008181018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a03808b168752600586529589902089519788018a5280548088168952600160a060020a03605060020a918290041696890196909652600181015463ffffffff8082169b8a019b909b5264010000000081048b1695890195909552604060020a90940490981691860182905260028301549086015260039091015480841696850196909652940416918101919091525b50919050565b346100025761069a60043560243560443560643560843560a43560018054600091829160ff60f060020a9091041615151415610c8e57610bfb33610376565b6040805160ff9092168252519081900360200190f35b005b604080519115158252519081900360200190f35b604080516001605060020a039092168252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b6040805163ffffffff9092168252519081900360200190f35b1561012757600160a060020a0381166000908152600260205260409020805460ff191690555b50565b1561063d57506001605060020a0380831660009081526005602052604090208054909116151561075b576000915061063d565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610817905b8051600354600090819060016001605060020a0390911611610c995760038054605060020a60f060020a0319169055610ddf565b600380546001605060020a031981166000196001605060020a03928316011782558416600090815260056020526040812080547fffff000000000000000000000000000000000000000000000000000000000000168155600181810180546bffffffffffffffffffffffff191690556002820192909255909101805473ffffffffffffffffffffffffffffffffffffffff19169055915061063d565b1561012757600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a8302179055610725565b1561091357600480546001605060020a031981166001605060020a039091166001011790555b565b156101275733600160a060020a0316ff5b1561095e57506001605060020a03808416600090815260056020526040902080549091161515610965576000915061095e565b600191505b5092915050565b60038101546001605060020a0384811691161415610986576001915061095e565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610a12906107e3565b61095983825b80546003546001605060020a0391821691600091161515610de55760038054605060020a60a060020a031916605060020a84021760a060020a69ffffffffffffffffffff02191660a060020a84021781558301805473ffffffffffffffffffffffffffffffffffffffff19169055610ddf565b1561072557600480546001605060020a0319168217905550565b1561012757600160a060020a0381166000908152600260205260409020805460ff19166001179055610725565b15610b5857506001605060020a038088166000908152600560205260409020805490911615610b645760009150610b58565b6004546001605060020a0390811690891610610b3057600480546001605060020a03191660018a011790555b6003805460016001605060020a03821681016001605060020a03199092169190911790915591505b50979650505050505050565b80546001605060020a0319168817605060020a60f060020a031916605060020a880217815560018101805463ffffffff1916871767ffffffff0000000019166401000000008702176bffffffff00000000000000001916604060020a860217905560028101839055610b048982610a18565b156101275760018054605060020a60f060020a031916605060020a8302179055610725565b15610c8e57506001605060020a03808816600090815260056020526040902080549091161515610c2e5760009150610c8e565b8054605060020a60f060020a031916605060020a88021781556001808201805463ffffffff1916881767ffffffff0000000019166401000000008802176bffffffff00000000000000001916604060020a87021790556002820184905591505b509695505050505050565b6003546001605060020a03848116605060020a909204161415610d095760e084015160038054605060020a928302605060020a60a060020a031990911617808255919091046001605060020a031660009081526005602052604090200180546001605060020a0319169055610ddf565b6003546001605060020a0384811660a060020a909204161415610d825760c08401516003805460a060020a92830260a060020a69ffffffffffffffffffff021990911617808255919091046001605060020a03166000908152600560205260409020018054605060020a60a060020a0319169055610ddf565b505060c082015160e08301516001605060020a0380831660009081526005602052604080822060039081018054605060020a60a060020a031916605060020a8702179055928416825290200180546001605060020a031916831790555b50505050565b6001605060020a0384161515610e6457600380546001605060020a03605060020a9182900481166000908152600560205260409020830180546001605060020a0319908116871790915583548785018054918590049093168402605060020a60a060020a03199182161790911690915582549185029116179055610ddf565b506001605060020a038381166000908152600560205260409020600390810180549185018054605060020a60a060020a0319908116605060020a94859004909516808502959095176001605060020a0319168817909155815416918402919091179055801515610ef4576003805460a060020a69ffffffffffffffffffff02191660a060020a8402179055610ddf565b6003808401546001605060020a03605060020a9091041660009081526005602052604090200180546001605060020a031916831790555050505056", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000113204f5d64c28326fd7bd05fd4ea855302d7f2ff00000000000000000000" - } - }, - "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2": { - "balance": "0x0", - "code": "0x6504032353da7150606060405236156100695760e060020a60003504631bf7509d811461006e57806321ce24d41461008157806333556e84146100ec578063685a1f3c146101035780637d65837a1461011757806389489a8714610140578063f775b6b5146101fc575b610007565b61023460043560006100fd82600061010d565b610246600435602435600160a060020a03811660009081526020839052604081205415156102cb57826001016000508054806001018281815481835581811511610278576000838152602090206102789181019083015b808211156102d057600081556001016100d8565b610248600435602435600182015481105b92915050565b6102346004356024355b60018101906100fd565b610248600435602435600160a060020a03811660009081526020839052604090205415156100fd565b61024660043560243580600160a060020a031632600160a060020a03161415156101f857600160a060020a038116600090815260208390526040902054156101f857600160a060020a038116600090815260208390526040902054600183018054909160001901908110156100075760009182526020808320909101805473ffffffffffffffffffffffffffffffffffffffff19169055600160a060020a038316825283905260408120556002820180546000190190555b5050565b61025c60043560243560008260010160005082815481101561000757600091825260209091200154600160a060020a03169392505050565b60408051918252519081900360200190f35b005b604080519115158252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b50505060009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a0385168352908590526040909120819055600284018054600101905590505b505050565b509056", - "nonce": "1", - "storage": {} - }, - "0xa529806c67cc6486d4d62024471772f47f6fd672": { - "balance": "0x67820e39ac8fe9800", - "code": "0x", - "nonce": "68", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "31912170", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712388", - "hash": "0x0855914bdc581bccdc62591fd438498386ffb59ea4d5361ed5c3702e26e2c72f", - "miner": "0x334391aa808257952a462d1475562ee2106a6c90", - "mixHash": "0x64bb70b8ca883cadb8fbbda2c70a861612407864089ed87b98e5de20acceada6", - "nonce": "0x684129f283aaef18", - "number": "11494", - "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10", - "timestamp": "1479735912", - "totalDifficulty": "90744064339" - }, - "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115", - "result": { - "calls": [ - { - "calls": [ - { - "from": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff", - "gas": "0x2bf459", - "gasUsed": "0x2aa", - "input": "0x7d65837a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2", - "type": "DELEGATECALL", - "value": "0x0" - } - ], - "from": "0x269296dddce321a6bcbaa2f0181127593d732cba", - "gas": "0x2cae73", - "gasUsed": "0xa9d", - "input": "0x5dbe47e8000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xa529806c67cc6486d4d62024471772f47f6fd672", - "gas": "0x2dc6c0", - "gasUsed": "0xbd55", - "input": "0x7065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e", - "to": "0x269296dddce321a6bcbaa2f0181127593d732cba", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json deleted file mode 100644 index bb16a4a430..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_create_oog_outer_throw.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "context": { - "difficulty": "3451177886", - "gasLimit": "4709286", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2290744", - "timestamp": "1513616439" - }, - "genesis": { - "alloc": { - "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a": { - "balance": "0x0", - "code": "0x606060405263ffffffff60e060020a6000350416633b91f50681146100505780635bb47808146100715780635f51fca01461008c578063bc7647a9146100ad578063f1bd0d7a146100c8575b610000565b346100005761006f600160a060020a03600435811690602435166100e9565b005b346100005761006f600160a060020a0360043516610152565b005b346100005761006f600160a060020a036004358116906024351661019c565b005b346100005761006f600160a060020a03600435166101fa565b005b346100005761006f600160a060020a0360043581169060243516610db8565b005b600160a060020a038083166000908152602081905260408120549091908116903316811461011657610000565b839150600160a060020a038316151561012d573392505b6101378284610e2e565b6101418284610db8565b61014a826101fa565b5b5b50505050565b600154600160a060020a03908116903316811461016e57610000565b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0384161790555b5b5050565b600254600160a060020a0390811690331681146101b857610000565b600160a060020a038381166000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790555b5b505050565b6040805160e260020a631a481fc102815260016024820181905260026044830152606482015262093a8060848201819052600060a4830181905260c06004840152601e60c48401527f736574456e7469747953746174757328616464726573732c75696e743829000060e484015292519091600160a060020a038516916369207f049161010480820192879290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526000602482018190526001604483015260606004830152602360648301527f626567696e506f6c6c28616464726573732c75696e7436342c626f6f6c2c626f60848301527f6f6c29000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f61646453746f636b28616464726573732c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f697373756553746f636b2875696e74382c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602160648301527f6772616e7453746f636b2875696e74382c75696e743235362c61646472657373608483015260f860020a60290260a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f115610000575050604080517f010555b8000000000000000000000000000000000000000000000000000000008152600160a060020a03338116602483015260006044830181905260606004840152603c60648401527f6772616e7456657374656453746f636b2875696e74382c75696e743235362c6160848401527f6464726573732c75696e7436342c75696e7436342c75696e743634290000000060a48401529251908716935063010555b89260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601260c48201527f626567696e53616c65286164647265737329000000000000000000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601a60648301527f7472616e7366657253616c6546756e64732875696e743235362900000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152602d60c48201527f7365744163636f756e74696e6753657474696e67732875696e743235362c756960e48201527f6e7436342c75696e7432353629000000000000000000000000000000000000006101048201529051600160a060020a03861692506369207f04916101248082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152603460648301527f637265617465526563757272696e6752657761726428616464726573732c756960848301527f6e743235362c75696e7436342c737472696e672900000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601b60648301527f72656d6f7665526563757272696e675265776172642875696e7429000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602360648301527f697373756552657761726428616464726573732c75696e743235362c7374726960848301527f6e6729000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f61737369676e53746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f72656d6f766553746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260026024808301919091526003604483015260006064830181905267ffffffffffffffff8616608484015260ff871660a484015260c0600484015260c48301919091527f7365744164647265737342796c617728737472696e672c616464726573732c6260e48301527f6f6f6c29000000000000000000000000000000000000000000000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152602160c48301527f73657453746174757342796c617728737472696e672c75696e74382c626f6f6c60e483015260f860020a6029026101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152603860c48301527f736574566f74696e6742796c617728737472696e672c75696e743235362c756960e48301527f6e743235362c626f6f6c2c75696e7436342c75696e74382900000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f115610000575050505b505050565b604080517f225553a4000000000000000000000000000000000000000000000000000000008152600160a060020a0383811660048301526002602483015291519184169163225553a49160448082019260009290919082900301818387803b156100005760325a03f115610000575050505b5050565b600082604051611fd280610f488339600160a060020a03909216910190815260405190819003602001906000f0801561000057905082600160a060020a03166308b027418260016040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b156100005760325a03f115610000575050604080517fa14e3ee300000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152600160a060020a0386811660448401529251928716935063a14e3ee39260648084019382900301818387803b156100005760325a03f115610000575050505b5050505600606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029a165627a7a723058200e78a5f7e0f91739035d0fbf5eca02f79377210b722f63431f29a22e2880b3bd0029", - "nonce": "789", - "storage": { - "0xfe9ec0542a1c009be8b1f3acf43af97100ffff42eb736850fb038fa1151ad4d9": "0x000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8" - } - }, - "0x5cb4a6b902fcb21588c86c3517e797b07cdaadb9": { - "balance": "0x0", - "code": "0x", - "nonce": "0", - "storage": {} - }, - "0xe4a13bc304682a903e9472f469c33801dd18d9e8": { - "balance": "0x33c763c929f62c4f", - "code": "0x", - "nonce": "14", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3451177886", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4713874", - "hash": "0x5d52a672417cd1269bf4f7095e25dcbf837747bba908cd5ef809dc1bd06144b5", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x01a12845ed546b94a038a7a03e8df8d7952024ed41ccb3db7a7ade4abc290ce1", - "nonce": "0x28c446f1cb9748c1", - "number": "2290743", - "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708", - "timestamp": "1513616414", - "totalDifficulty": "7146523769022564" - }, - "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281", - "result": { - "calls": [ - { - "error": "contract creation code storage out of gas", - "from": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a", - "gas": "0x39ff0", - "gasUsed": "0x39ff0", - "input": "0x606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182", - "type": "CREATE", - "value": "0x0" - } - ], - "error": "invalid jump destination", - "from": "0xe4a13bc304682a903e9472f469c33801dd18d9e8", - "gas": "0x493e0", - "gasUsed": "0x493e0", - "input": "0x3b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8", - "to": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json deleted file mode 100644 index 9b45b52fe9..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_instafail.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "genesis": { - "difficulty": "117067574", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712380", - "hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486", - "miner": "0x0c062b329265c965deef1eede55183b3acb8f611", - "mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d", - "nonce": "0x2b469722b8e28c45", - "number": "24973", - "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369", - "timestamp": "1479891145", - "totalDifficulty": "1892250259406", - "alloc": { - "0x6c06b16512b332e6cd8293a2974872674716ce18": { - "balance": "0x0", - "nonce": "1", - "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056", - "storage": {} - }, - "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": { - "balance": "0x229ebbb36c3e0f20", - "nonce": "3", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 3, - "homesteadBlock": 0, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "byzantiumBlock": 1700000, - "constantinopleBlock": 4230000, - "petersburgBlock": 4939394, - "istanbulBlock": 6485846, - "muirGlacierBlock": 7117117, - "ethash": {} - } - }, - "context": { - "number": "24974", - "difficulty": "117067574", - "timestamp": "1479891162", - "gasLimit": "4712388", - "miner": "0xc822ef32e6d26e170b70cf761e204c1806265914" - }, - "input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745", - "result": { - "type": "CALL", - "from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", - "to": "0x6c06b16512b332e6cd8293a2974872674716ce18", - "value": "0x0", - "gas": "0x1f97e", - "gasUsed": "0x72de", - "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json deleted file mode 100644 index e54129d4c2..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_revert_reason.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "genesis": { - "baseFeePerGas": "1000000000", - "difficulty": "1", - "extraData": "0x00000000000000000000000000000000000000000000000000000000000000003623191d4ccfbbdf09e8ebf6382a1f8257417bc10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "11500000", - "hash": "0x2af138b8a06e65b8dd0999df70b9e87609e9fc91ea201f08b1cc4f25ef01fcf6", - "miner": "0x0000000000000000000000000000000000000000", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0x0000000000000000", - "number": "0", - "stateRoot": "0xa775801d572e9b79585eb131d18d79f8a0f71895455ab9a5b656911428e11708", - "timestamp": "0", - "totalDifficulty": "1", - "alloc": { - "0x3623191d4ccfbbdf09e8ebf6382a1f8257417bc1": { - "balance": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7" - }, - "0xd15abca351f79181dedfb6d019e382db90f3628a": { - "balance": "0x0" - } - }, - "config": { - "chainId": 1337, - "homesteadBlock": 0, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "apricotPhase1BlockTimestamp": 0, - "apricotPhase2BlockTimestamp": 0, - "apricotPhase3BlockTimestamp": 0 - } - }, - "context": { - "number": "1", - "difficulty": "2", - "timestamp": "1665537018", - "gasLimit": "11511229", - "miner": "0x0000000000000000000000000000000000000000" - }, - "input": "0x02f9029d82053980849502f90085010c388d00832dc6c08080b90241608060405234801561001057600080fd5b50600060405161001f906100a2565b604051809103906000f08015801561003b573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c04062266040518163ffffffff1660e01b815260040160006040518083038186803b15801561008457600080fd5b505afa158015610098573d6000803e3d6000fd5b50505050506100af565b610145806100fc83390190565b603f806100bd6000396000f3fe6080604052600080fdfea264697066735822122077f7dbd3450d6e817079cf3fe27107de5768bb3163a402b94e2206b468eb025664736f6c63430008070033608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033c001a07566181071cabaf58b70fc41557eb813bfc7a24f5c58554e7fed0bf7c031f169a0420af50b5fe791a4d839e181a676db5250b415dfb35cb85d544db7a1475ae2cc", - "result": { - "from": "0x3623191d4ccfbbdf09e8ebf6382a1f8257417bc1", - "gas": "0x2dc6c0", - "gasUsed": "0x25590", - "input": "0x608060405234801561001057600080fd5b50600060405161001f906100a2565b604051809103906000f08015801561003b573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff1663c04062266040518163ffffffff1660e01b815260040160006040518083038186803b15801561008457600080fd5b505afa158015610098573d6000803e3d6000fd5b50505050506100af565b610145806100fc83390190565b603f806100bd6000396000f3fe6080604052600080fdfea264697066735822122077f7dbd3450d6e817079cf3fe27107de5768bb3163a402b94e2206b468eb025664736f6c63430008070033608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033", - "output": "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000012546869732063616c6c6564206661696c65640000000000000000000000000000", - "error": "execution reverted", - "revertReason": "This called failed", - "calls": [ - { - "from": "0xdebfb4b387033eac57af7b3de5116dd60056803b", - "gas": "0x2ba851", - "gasUsed": "0xe557", - "to": "0xd15abca351f79181dedfb6d019e382db90f3628a", - "input": "0x608060405234801561001057600080fd5b50610125806100206000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033", - "output": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063c040622614602d575b600080fd5b60336035565b005b60036002116076576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401606d906097565b60405180910390fd5b565b6000608360128360b5565b9150608c8260c6565b602082019050919050565b6000602082019050818103600083015260ae816078565b9050919050565b600082825260208201905092915050565b7f546869732063616c6c6564206661696c6564000000000000000000000000000060008201525056fea264697066735822122033f8d92e29d467e5ea08d0024eab0b36b86b8cdb3542c6e89dbaabeb8ffaa42064736f6c63430008070033", - "value": "0x0", - "type": "CREATE" - }, - { - "from": "0xdebfb4b387033eac57af7b3de5116dd60056803b", - "gas": "0x2ac548", - "gasUsed": "0x1b2", - "to": "0xd15abca351f79181dedfb6d019e382db90f3628a", - "input": "0xc0406226", - "output": "0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000012546869732063616c6c6564206661696c65640000000000000000000000000000", - "error": "execution reverted", - "revertReason": "This called failed", - "type": "STATICCALL" - } - ], - "value": "0x0", - "type": "CREATE" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json deleted file mode 100644 index a023ed6d9b..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "context": { - "difficulty": "3956606365", - "gasLimit": "5413248", - "miner": "0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d", - "number": "2295104", - "timestamp": "1513681256" - }, - "genesis": { - "alloc": { - "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76": { - "balance": "0x0", - "code": "0x60606040526004361061015e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680625b4487146101a257806311df9995146101cb578063278ecde11461022057806330adce0e146102435780633197cbb61461026c5780634bb278f3146102955780636103d70b146102aa57806363a599a4146102bf5780636a2d1cb8146102d457806375f12b21146102fd57806378e979251461032a578063801db9cc1461035357806386d1a69f1461037c5780638da5cb5b146103915780638ef26a71146103e65780639890220b1461040f5780639b39caef14610424578063b85dfb801461044d578063be9a6555146104a1578063ccb07cef146104b6578063d06c91e4146104e3578063d669e1d414610538578063df40503c14610561578063e2982c2114610576578063f02e030d146105c3578063f2fde38b146105d8578063f3283fba14610611575b600060149054906101000a900460ff1615151561017a57600080fd5b60075442108061018b575060085442115b15151561019757600080fd5b6101a03361064a565b005b34156101ad57600080fd5b6101b5610925565b6040518082815260200191505060405180910390f35b34156101d657600080fd5b6101de61092b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022b57600080fd5b6102416004808035906020019091905050610951565b005b341561024e57600080fd5b610256610c48565b6040518082815260200191505060405180910390f35b341561027757600080fd5b61027f610c4e565b6040518082815260200191505060405180910390f35b34156102a057600080fd5b6102a8610c54565b005b34156102b557600080fd5b6102bd610f3e565b005b34156102ca57600080fd5b6102d261105d565b005b34156102df57600080fd5b6102e76110d5565b6040518082815260200191505060405180910390f35b341561030857600080fd5b6103106110e1565b604051808215151515815260200191505060405180910390f35b341561033557600080fd5b61033d6110f4565b6040518082815260200191505060405180910390f35b341561035e57600080fd5b6103666110fa565b6040518082815260200191505060405180910390f35b341561038757600080fd5b61038f611104565b005b341561039c57600080fd5b6103a4611196565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f157600080fd5b6103f96111bb565b6040518082815260200191505060405180910390f35b341561041a57600080fd5b6104226111c1565b005b341561042f57600080fd5b610437611296565b6040518082815260200191505060405180910390f35b341561045857600080fd5b610484600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061129c565b604051808381526020018281526020019250505060405180910390f35b34156104ac57600080fd5b6104b46112c0565b005b34156104c157600080fd5b6104c9611341565b604051808215151515815260200191505060405180910390f35b34156104ee57600080fd5b6104f6611354565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561054357600080fd5b61054b61137a565b6040518082815260200191505060405180910390f35b341561056c57600080fd5b610574611385565b005b341561058157600080fd5b6105ad600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506116c3565b6040518082815260200191505060405180910390f35b34156105ce57600080fd5b6105d66116db565b005b34156105e357600080fd5b61060f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611829565b005b341561061c57600080fd5b610648600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118fe565b005b600080670de0b6b3a7640000341015151561066457600080fd5b61069b610696670de0b6b3a7640000610688610258346119d990919063ffffffff16565b611a0c90919063ffffffff16565b611a27565b9150660221b262dd80006106ba60065484611a7e90919063ffffffff16565b111515156106c757600080fd5b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156107d557600080fd5b6102c65a03f115156107e657600080fd5b5050506040518051905050610808828260010154611a7e90919063ffffffff16565b8160010181905550610827348260000154611a7e90919063ffffffff16565b816000018190555061084434600554611a7e90919063ffffffff16565b60058190555061085f82600654611a7e90919063ffffffff16565b6006819055503373ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c836040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e8583600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060085442108061096b5750651b48eb57e00060065410155b15151561097757600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154821415156109c757600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515610ac857600080fd5b6102c65a03f11515610ad957600080fd5b5050506040518051905050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68836000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610b7d57600080fd5b6102c65a03f11515610b8e57600080fd5b505050604051805190501515610ba357600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506000811115610c4457610c433382611a9c565b5b5050565b60055481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb157600080fd5b600854421015610cd357660221b262dd8000600654141515610cd257600080fd5b5b651b48eb57e000600654108015610cf057506213c6806008540142105b151515610cfc57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610d7557600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610e3a57600080fd5b6102c65a03f11515610e4b57600080fd5b5050506040518051905090506000811115610f2057600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610ef957600080fd5b6102c65a03f11515610f0a57600080fd5b505050604051805190501515610f1f57600080fd5b5b6001600960006101000a81548160ff02191690831515021790555050565b600080339150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114151515610f9657600080fd5b803073ffffffffffffffffffffffffffffffffffffffff163110151515610fbc57600080fd5b610fd181600254611b5090919063ffffffff16565b6002819055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561105957fe5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110b857600080fd5b6001600060146101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b600060149054906101000a900460ff1681565b60075481565b651b48eb57e00081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561115f57600080fd5b600060149054906101000a900460ff16151561117a57600080fd5b60008060146101000a81548160ff021916908315150217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561121c57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561129457600080fd5b565b61025881565b600a6020528060005260406000206000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561131b57600080fd5b600060075414151561132c57600080fd5b4260078190555062278d004201600881905550565b600960009054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b660221b262dd800081565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113e557600080fd5b600654660221b262dd800003925061142b670de0b6b3a764000061141c610258670de0b6b3a76400006119d990919063ffffffff16565b81151561142557fe5b04611a27565b915081831115151561143c57600080fd5b600a60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561158c57600080fd5b6102c65a03f1151561159d57600080fd5b50505060405180519050506115bf838260010154611a7e90919063ffffffff16565b81600101819055506115dc83600654611a7e90919063ffffffff16565b6006819055503073ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c846040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60016020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561173657600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b151561181357600080fd5b6102c65a03f1151561182457600080fd5b505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415156118fb57806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561195957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561199557600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080828402905060008414806119fa57508284828115156119f757fe5b04145b1515611a0257fe5b8091505092915050565b6000808284811515611a1a57fe5b0490508091505092915050565b6000611a416202a300600754611a7e90919063ffffffff16565b421015611a7557611a6e611a5f600584611a0c90919063ffffffff16565b83611a7e90919063ffffffff16565b9050611a79565b8190505b919050565b6000808284019050838110151515611a9257fe5b8091505092915050565b611aee81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611a7e90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b4681600254611a7e90919063ffffffff16565b6002819055505050565b6000828211151515611b5e57fe5b8183039050929150505600a165627a7a72305820ec0d82a406896ccf20989b3d6e650abe4dc104e400837f1f58e67ef499493ae90029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008d69d00910d0b2afb2a99ed6c16c8129fa8e1751", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000e819f024b41358d2c08e3a868a5c5dd0566078d4", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000000000000000000000000000000000005a388981", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000005a3b38e6" - } - }, - "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826": { - "balance": "0x2a2dd979a35cf000", - "code": "0x", - "nonce": "0", - "storage": {} - }, - "0xe819f024b41358d2c08e3a868a5c5dd0566078d4": { - "balance": "0x0", - "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c681461027257806370a08231146102ad5780638da5cb5b146102fa57806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e14610437578063f2fde38b146104a3575b600080fd5b34156100ca57600080fd5b6100d26104dc565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610515565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba61069c565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106a2565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610952565b6040518082815260200191505060405180910390f35b341561027d57600080fd5b6102936004808035906020019091905050610957565b604051808215151515815260200191505060405180910390f35b34156102b857600080fd5b6102e4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610abe565b6040518082815260200191505060405180910390f35b341561030557600080fd5b61030d610b07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561035a57600080fd5b610362610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b66565b604051808215151515815260200191505060405180910390f35b341561044257600080fd5b61048d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d01565b6040518082815260200191505060405180910390f35b34156104ae57600080fd5b6104da600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d88565b005b6040805190810160405280600b81526020017f416c6c436f6465436f696e00000000000000000000000000000000000000000081525081565b6000808214806105a157506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ac57600080fd5b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905061077683600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061080b83600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108618382610e7d90919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b600681565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109b557600080fd5b610a0782600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610a5f82600054610e7d90919063ffffffff16565b60008190555060003373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600481526020017f414c4c430000000000000000000000000000000000000000000000000000000081525081565b6000610bba82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c4f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610e5c5780600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000808284019050838110151515610e7357fe5b8091505092915050565b6000828211151515610e8b57fe5b8183039050929150505600a165627a7a7230582059f3ea3df0b054e9ab711f37969684ba83fe38f255ffe2c8d850d951121c51100029", - "nonce": "1", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3956606365", - "extraData": "0x566961425443", - "gasLimit": "5418523", - "hash": "0x6f37eb930a25da673ea1bb80fd9e32ddac19cdf7cd4bb2eac62cc13598624077", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "mixHash": "0x10971cde68c587c750c23b8589ae868ce82c2c646636b97e7d9856470c5297c7", - "nonce": "0x810f923ff4b450a1", - "number": "2295103", - "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e", - "timestamp": "1513681246", - "totalDifficulty": "7162347056825919" - }, - "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea", - "result": { - "calls": [ - { - "error": "invalid opcode: INVALID", - "from": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76", - "gas": "0x75fe3", - "gasUsed": "0x75fe3", - "input": "0xa9059cbb000000000000000000000000d4fcab9f0a6dc0493af47c864f6f17a8a5e2e82600000000000000000000000000000000000000000000000000000000000002f4", - "to": "0xe819f024b41358d2c08e3a868a5c5dd0566078d4", - "type": "CALL", - "value": "0x0" - } - ], - "error": "execution reverted", - "from": "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826", - "gas": "0x7dfa6", - "gasUsed": "0x7c1c8", - "input": "0x", - "to": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76", - "type": "CALL", - "value": "0xe92596fd6290000" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.md b/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.md deleted file mode 100644 index 2700578bd0..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/inner_throw_outer_revert.md +++ /dev/null @@ -1,19 +0,0 @@ -This test tests out the trace generated by the deployment of this contract: - -```solidity -contract Revertor { - function run() public pure { - require(2 > 3, "This called failed"); - } -} - -contract Contract { - constructor() { - Revertor r = new Revertor(); - r.run(); - } -} -``` - -The trace should show a revert, with the revert reason for both the top-call as well -as the inner call. diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json deleted file mode 100644 index 333bdd038c..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/oog.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "context": { - "difficulty": "3699098917", - "gasLimit": "5258985", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "number": "2294631", - "timestamp": "1513675366" - }, - "genesis": { - "alloc": { - "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": { - "balance": "0x0", - "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029", - "nonce": "1", - "storage": { - "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0" - } - }, - "0x94194bc2aaf494501d7880b61274a169f6502a54": { - "balance": "0xea8c39a876d19888d", - "code": "0x", - "nonce": "265", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3699098917", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "5263953", - "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", - "nonce": "0xd1bdb150f6fd170e", - "number": "2294630", - "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" - }, - "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956", - "result": { - "error": "out of gas", - "from": "0x94194bc2aaf494501d7880b61274a169f6502a54", - "gas": "0xca1d", - "gasUsed": "0xca1d", - "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000", - "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json deleted file mode 100644 index 3207a298a9..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/revert.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "context": { - "difficulty": "3665057456", - "gasLimit": "5232723", - "miner": "0xf4d8e706cfb25c0decbbdd4d2e2cc10c66376a3f", - "number": "2294501", - "timestamp": "1513673601" - }, - "genesis": { - "alloc": { - "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9": { - "balance": "0x2a3fc32bcc019283", - "code": "0x", - "nonce": "10", - "storage": {} - }, - "0xabbcd5b340c80b5f1c0545c04c987b87310296ae": { - "balance": "0x0", - "code": "0x606060405236156100755763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d0335ab811461007a578063548db174146100ab5780637f649783146100fc578063b092145e1461014d578063c3f44c0a14610186578063c47cf5de14610203575b600080fd5b341561008557600080fd5b610099600160a060020a0360043516610270565b60405190815260200160405180910390f35b34156100b657600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061028f95505050505050565b005b341561010757600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061029e95505050505050565b005b341561015857600080fd5b610172600160a060020a03600435811690602435166102ad565b604051901515815260200160405180910390f35b341561019157600080fd5b6100fa6004803560ff1690602480359160443591606435600160a060020a0316919060a49060843590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965050509235600160a060020a031692506102cd915050565b005b341561020e57600080fd5b61025460046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061056a95505050505050565b604051600160a060020a03909116815260200160405180910390f35b600160a060020a0381166000908152602081905260409020545b919050565b61029a816000610594565b5b50565b61029a816001610594565b5b50565b600160209081526000928352604080842090915290825290205460ff1681565b60008080600160a060020a038416158061030d5750600160a060020a038085166000908152600160209081526040808320339094168352929052205460ff165b151561031857600080fd5b6103218561056a565b600160a060020a038116600090815260208190526040808220549295507f19000000000000000000000000000000000000000000000000000000000000009230918891908b908b90517fff000000000000000000000000000000000000000000000000000000000000008089168252871660018201526c01000000000000000000000000600160a060020a038088168202600284015286811682026016840152602a8301869052841602604a820152605e810182805190602001908083835b6020831061040057805182525b601f1990920191602091820191016103e0565b6001836020036101000a0380198251168184511617909252505050919091019850604097505050505050505051809103902091506001828a8a8a6040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f1151561049957600080fd5b5050602060405103519050600160a060020a03838116908216146104bc57600080fd5b600160a060020a0380841660009081526020819052604090819020805460010190559087169086905180828051906020019080838360005b8381101561050d5780820151818401525b6020016104f4565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b5091505060006040518083038160008661646e5a03f1915050151561055e57600080fd5b5b505050505050505050565b600060248251101561057e5750600061028a565b600160a060020a0360248301511690505b919050565b60005b825181101561060157600160a060020a033316600090815260016020526040812083918584815181106105c657fe5b90602001906020020151600160a060020a031681526020810191909152604001600020805460ff19169115159190911790555b600101610597565b5b5050505600a165627a7a723058200027e8b695e9d2dea9f3629519022a69f3a1d23055ce86406e686ea54f31ee9c0029", - "nonce": "1", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3672229776", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "5227619", - "hash": "0xa07b3d6c6bf63f5f981016db9f2d1d93033833f2c17e8bf7209e85f1faf08076", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x806e151ce2817be922e93e8d5921fa0f0d0fd213d6b2b9a3fa17458e74a163d0", - "nonce": "0xbc5d43adc2c30c7d", - "number": "2294500", - "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d", - "timestamp": "1513673552", - "totalDifficulty": "7160066586979149" - }, - "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a", - "result": { - "error": "execution reverted", - "from": "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9", - "gas": "0x2dc6c0", - "gasUsed": "0x719b", - "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000", - "to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json deleted file mode 100644 index f02e5c6863..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/revert_reason.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "context": { - "difficulty": "2", - "gasLimit": "8000000", - "miner": "0x0000000000000000000000000000000000000000", - "number": "3212651", - "timestamp": "1597246515" - }, - "genesis": { - "alloc": { - "0xf58833cf0c791881b494eb79d461e08a1f043f52": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063609ff1bd11610078578063609ff1bd146101af5780639e7b8d61146101cd578063a3ec138d14610211578063e2ba53f0146102ae576100a5565b80630121b93f146100aa578063013cf08b146100d85780632e4176cf146101215780635c19a95c1461016b575b600080fd5b6100d6600480360360208110156100c057600080fd5b81019080803590602001909291905050506102cc565b005b610104600480360360208110156100ee57600080fd5b8101908080359060200190929190505050610469565b604051808381526020018281526020019250505060405180910390f35b61012961049a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ad6004803603602081101561018157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104bf565b005b6101b76108db565b6040518082815260200191505060405180910390f35b61020f600480360360208110156101e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610952565b005b6102536004803603602081101561022757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b53565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b6102b6610bb0565b6040518082815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f486173206e6f20726967687420746f20766f746500000000000000000000000081525060200191505060405180910390fd5b8060010160009054906101000a900460ff161561040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f416c726561647920766f7465642e00000000000000000000000000000000000081525060200191505060405180910390fd5b60018160010160006101000a81548160ff02191690831515021790555081816002018190555080600001546002838154811061044757fe5b9060005260206000209060020201600101600082825401925050819055505050565b6002818154811061047657fe5b90600052602060002090600202016000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff1615610587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f596f7520616c726561647920766f7465642e000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e000081525060200191505060405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107cc57600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f466f756e64206c6f6f7020696e2064656c65676174696f6e2e0000000000000081525060200191505060405180910390fd5b61062a565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156108bf578160000154600282600201548154811061089c57fe5b9060005260206000209060020201600101600082825401925050819055506108d6565b816000015481600001600082825401925050819055505b505050565b6000806000905060008090505b60028054905081101561094d57816002828154811061090357fe5b9060005260206000209060020201600101541115610940576002818154811061092857fe5b90600052602060002090600202016001015491508092505b80806001019150506108e8565b505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180610bde6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f54686520766f74657220616c726561647920766f7465642e000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414610b0957600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610bbc6108db565b81548110610bc657fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea26469706673582212201d282819f8f06fed792100d60a8b08809b081a34a1ecd225e83a4b41122165ed64736f6c63430006060033", - "nonce": "1", - "storage": { - "0x6200beec95762de01ce05f2a0e58ce3299dbb53c68c9f3254a242121223cdf58": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1": { - "balance": "0x57af9d6b3df812900", - "code": "0x", - "nonce": "6", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "IstanbulBlock": 1561651, - "chainId": 5, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294", - "result": { - "error": "execution reverted", - "from": "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", - "gas": "0x2dc6c0", - "gasUsed": "0x5940", - "input": "0x5c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", - "to": "0xf58833cf0c791881b494eb79d461e08a1f043f52", - "type": "CALL", - "value": "0x0", - "output": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000", - "revertReason": "Self-delegation is disallowed." - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json deleted file mode 100644 index 620df1d614..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/selfdestruct.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x61deadff", - "nonce": "1", - "storage": {} - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "result": { - "calls": [ - { - "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "gas": "0x0", - "gasUsed": "0x0", - "input": "0x", - "to": "0x000000000000000000000000000000000000dead", - "type": "SELFDESTRUCT", - "value": "0x4d87094125a369d9bd5" - } - ], - "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb", - "gas": "0x15f90", - "gasUsed": "0x6fcb", - "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json deleted file mode 100644 index 6c7d01de1f..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/simple.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "result": { - "calls": [ - { - "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "gas": "0x6d05", - "gasUsed": "0x0", - "input": "0x", - "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "type": "CALL", - "value": "0x6f05b59d3b20000" - } - ], - "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb", - "gas": "0x15f90", - "gasUsed": "0x9751", - "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json b/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json deleted file mode 100644 index affb4ab033..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/simple_onlytop.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "tracerConfig": { - "onlyTopCall": true - }, - "result": { - "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb", - "gas": "0x15f90", - "gasUsed": "0x9751", - "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json deleted file mode 100644 index 499b449a6e..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer/throw.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "context": { - "difficulty": "117009631", - "gasLimit": "4712388", - "miner": "0x294e5d6c39a36ce38af1dca70c1060f78dee8070", - "number": "25009", - "timestamp": "1479891666" - }, - "genesis": { - "alloc": { - "0x70c9217d814985faef62b124420f8dfbddd96433": { - "balance": "0x4ecd70668f5d854a", - "code": "0x", - "nonce": "1638", - "storage": {} - }, - "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": { - "balance": "0x0", - "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000061a9", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433" - } - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "117066792", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712388", - "hash": "0xe23e8d4562a1045b70cbc99fefb20c101a8f0fc8559a80d65fea8896e2f1d46e", - "miner": "0x71842f946b98800fe6feb49f0ae4e253259031c9", - "mixHash": "0x0aada9d6e93dd4db0d09c0488dc0a048fca2ccdc1f3fc7b83ba2a8d393a3a4ff", - "nonce": "0x70849d5838dee2e9", - "number": "25008", - "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b", - "timestamp": "1479891641", - "totalDifficulty": "1896347038589" - }, - "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750", - "result": { - "error": "invalid jump destination", - "from": "0x70c9217d814985faef62b124420f8dfbddd96433", - "gas": "0x3d090", - "gasUsed": "0x3d090", - "input": "0x51a34eb8000000000000000000000000000000000000000000000027fad02094277c0000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json deleted file mode 100644 index 617f52a14e..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/big_slow.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "genesis": { - "difficulty": "50486697699375", - "extraData": "0xd783010406844765746887676f312e362e32856c696e7578", - "gasLimit": "4788482", - "hash": "0xf6bbc5bbe34d5c93fd5b4712cd498d1026b8b0f586efefe7fe30231ed6b8a1a5", - "miner": "0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1", - "mixHash": "0xabca93555584c0463ee5c212251dd002bb3a93a157e06614276f93de53d4fdb8", - "nonce": "0xa64136fcb9c2d4ca", - "number": "1719576", - "stateRoot": "0xab5eec2177a92d633e282936af66c46e24cfa8f2fdc2b8155f33885f483d06f3", - "timestamp": "1466150166", - "totalDifficulty": "28295412423546970038", - "alloc": { - "0xf8bda96b67036ee48107f2a0695ea673479dda56": { - "balance": "0x1529e844f9ecdeec", - "nonce": "33", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 1, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 3000000, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 1150000, - "byzantiumBlock": 8772000, - "constantinopleBlock": 9573000, - "petersburgBlock": 10500839, - "istanbulBlock": 10500839 - } - }, - "context": { - "number": "1719577", - "difficulty": "50486697732143", - "timestamp": "1466150178", - "gasLimit": "4788484", - "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226" - }, - "input": "0xf874218504a817c800832318608080a35b620186a05a131560135760016020526000565b600080601f600039601f565b6000f31ba0575fa000a1f06659a7b6d3c7877601519a4997f04293f0dfa0eee6d8cd840c77a04c52ce50719ee2ff7a0c5753f4ee69c0340666f582dbb5148845a354ca726e4a", - "result": [ - { - "action": { - "from": "0xf8bda96b67036ee48107f2a0695ea673479dda56", - "gas": "0x231860", - "init": "0x5b620186a05a131560135760016020526000565b600080601f600039601f565b6000f3", - "value": "0x0" - }, - "blockNumber": 1719577, - "result": { - "address": "0xb2e6a2546c45889427757171ab05b8b438525b42", - "code": "0x", - "gasUsed": "0x219202" - }, - "subtraces": 0, - "traceAddress": [], - "type": "create" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json deleted file mode 100644 index c796804a4b..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_fail_hide.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "genesis": { - "difficulty": "4671584", - "extraData": "0xd683010b05846765746886676f312e3133856c696e7578", - "gasLimit": "9435026", - "hash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "mixHash": "0x3a44525624571c31344ba57780f7664098fe7cbeafe532bcdee76a23fc474ba0", - "nonce": "0x6dca647c00c72bbf", - "number": "1555278", - "stateRoot": "0x5f56d8323ee384b0c8d1de49d63e150e17283eea813483698362bc0ec9e0242a", - "timestamp": "1590795319", - "totalDifficulty": "2242614315030", - "alloc": { - "0x0000000000000000000000000000000000000004": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x62436e941792f02a5fb1", - "nonce": "265356", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555279", - "difficulty": "4669303", - "timestamp": "1590795340", - "gasLimit": "9444238", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf86f83040c8c843b9aca0083019f7880809b60206000600060006013600462030d40f26002556000516000550081a2a086ad228c89ad9664287b12a5602a635a803506904f4ce39795990ac4f945cd57a025b30ea8042d773f6c5b13d7cc1b3979f9f10ee674410b6a2112ce840d0302dc", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x19f78", - "init": "0x60206000600060006013600462030d40f260025560005160005500" - }, - "result": { - "gasUsed": "0xf3bc", - "code": "0x", - "address": "0x5f8a7e007172ba80afbff1b15f800eb0b260f224" - }, - "traceAddress": [], - "subtraces": 0, - "transactionPosition": 74, - "transactionHash": "0x5ef60b27ac971c22a7d484e546e50093ca62300c8986d165154e47773764b6a4", - "blockNumber": 1555279, - "blockHash": "0xd6c98d1b87dfa92a210d99bad2873adaf0c9e51fe43addc63fd9cca03a5c6f46", - "time": "209.346µs" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json deleted file mode 100644 index fb29e49660..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_oog.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "genesis": { - "difficulty": "4671584", - "extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578", - "gasLimit": "9425823", - "hash": "0x27dd7d052dbc8a29cc5b9487e1e41d842e7a643fcaea4964caa22b834964acaf", - "miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3", - "mixHash": "0xb4a050624f5d147fdf02857cbfd55da3ddc1451743acc5c163861584589c3034", - "nonce": "0x3c255875b17e0573", - "number": "1555277", - "stateRoot": "0x6290d79215a2eebc25d5e456b35876c6d78ffc1ea47bdd70e375ebb3cf325620", - "timestamp": "1590795308", - "totalDifficulty": "2242609643446", - "alloc": { - "0x0000000000000000000000000000000000000001": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x624329308610ab365fb1", - "nonce": "265194", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555278", - "difficulty": "4671584", - "timestamp": "1590795319", - "gasLimit": "9435026", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf8ee83040bea843b9aca008301a7588080b8997f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549606052602060806080600060006001610bb7f260025560a060020a6080510660005560005432146001550081a1a05b9a162d84bfe84faa7c176e21c26c0083645d4dd0d566547b7be2c2da0b4259a05b37ff12a4c27634cb0da6008d9b69726d415ff4694f9bc38c7806eb1fb60ae9", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x1a758", - "init": "0x7f18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c600052601c6020527f73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f6040527feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549606052602060806080600060006001610bb7f260025560a060020a60805106600055600054321460015500" - }, - "result": { - "gasUsed": "0xf3e9", - "code": "0x", - "address": "0x568c19ecb14b87e4aec29b4d2d700a3ad3fd0613" - }, - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 141, - "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1", - "blockNumber": 1555278, - "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b", - "time": "300.9µs" - }, - { - "type": "call", - "action": { - "from": "0x568c19ecb14b87e4aec29b4d2d700a3ad3fd0613", - "to": "0x0000000000000000000000000000000000000001", - "value": "0x0", - "gas": "0xbb7", - "input": "0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549", - "callType": "callcode" - }, - "error": "out of gas", - "traceAddress": [ - 0 - ], - "subtraces": 0, - "transactionPosition": 141, - "transactionHash": "0x1592cbda0d928b8d18eed98857942b91ade32d088e55b8bf63418917cb0231f1", - "blockNumber": 1555278, - "blockHash": "0x755bd54de4b2f5a7a589a10d69888b4ead48a6311d5d69f2f69ca85ec35fbe0b" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json deleted file mode 100644 index 3c1e370f91..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/callcode_precompiled_throw.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "genesis": { - "difficulty": "4683014", - "extraData": "0x537465762d63676574682d76312e31312e34", - "gasLimit": "9435044", - "hash": "0x3452ca5005cb73cd60dfa488a7b124251168e564491f80eb66765e79d78cfd95", - "miner": "0x415aa6292d1db797a467b22139704956c030e62f", - "mixHash": "0x6037612618507ae70c74a72bc2580253662971db959cfbc06d3f8527d4d01575", - "nonce": "0x314fc90dee5e39a2", - "number": "1555274", - "stateRoot": "0x795751f3f96a5de1fd3944ddd78cbfe4ef10491e1086be47609869a30929d0e5", - "timestamp": "1590795228", - "totalDifficulty": "2242595605834", - "alloc": { - "0x0000000000000000000000000000000000000009": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x6242e3ccf48e66425fb1", - "nonce": "264981", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555275", - "difficulty": "4683014", - "timestamp": "1590795244", - "gasLimit": "9444256", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf87a83040b15843b9aca008301a0348080a636600060003760406103e8366000600060095af26001556103e851600255610408516003550081a1a0dd883fbbb489b640dadc8c1bf151767155228d0a1321f687f070f35f14374b05a02dd0ccb16a8de39bc8ee61381bbbbb54f0ab18422afd7b03c6163da1f5023934", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x1a034", - "init": "0x36600060003760406103e8366000600060095af26001556103e8516002556104085160035500" - }, - "error": "out of gas", - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 117, - "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9", - "blockNumber": 1555275, - "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd", - "time": "332.877µs" - }, - { - "type": "call", - "action": { - "from": "0x8832ef498070145c3a5b30f47fbca71fd7b1de9f", - "to": "0x0000000000000000000000000000000000000009", - "value": "0x0", - "gas": "0xc897", - "input": "0x", - "callType": "callcode" - }, - "error": "invalid input length", - "traceAddress": [ - 0 - ], - "subtraces": 0, - "transactionPosition": 117, - "transactionHash": "0x7fe4dec901e1a62c1a1d96b8267bb9ff9dc1f75def43aa45b998743455eff8f9", - "blockNumber": 1555275, - "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json deleted file mode 100644 index 11bc4eae02..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/create.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "context": { - "difficulty": "3755480783", - "gasLimit": "5401723", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "number": "2294702", - "timestamp": "1513676146" - }, - "genesis": { - "alloc": { - "0x13e4acefe6a6700604929946e70e6443e4e73447": { - "balance": "0xcf3e0938579f000", - "code": "0x", - "nonce": "9", - "storage": {} - }, - "0x7dc9c9730689ff0b0fd506c67db815f12d90a448": { - "balance": "0x0", - "code": "0x", - "nonce": "0", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3757315409", - "extraData": "0x566961425443", - "gasLimit": "5406414", - "hash": "0xae107f592eebdd9ff8d6ba00363676096e6afb0e1007a7d3d0af88173077378d", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "mixHash": "0xc927aa05a38bc3de864e95c33b3ae559d3f39c4ccd51cef6f113f9c50ba0caf1", - "nonce": "0x93363bbd2c95f410", - "number": "2294701", - "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c", - "timestamp": "1513676127", - "totalDifficulty": "7160808139332585" - }, - "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f", - "result": [ - { - "action": { - "from": "0x13e4acefe6a6700604929946e70e6443e4e73447", - "gas": "0x897be", - "init": "0x606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a11", - "value": "0x0" - }, - "blockNumber": 2294702, - "result": { - "address": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448", - "code": "0x606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029", - "gasUsed": "0x897be" - }, - "subtraces": 0, - "traceAddress": [], - "type": "create" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json deleted file mode 100644 index 375a163614..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/deep_calls.json +++ /dev/null @@ -1,635 +0,0 @@ -{ - "context": { - "difficulty": "117066904", - "gasLimit": "4712384", - "miner": "0x1977c248e1014cc103929dd7f154199c916e39ec", - "number": "25001", - "timestamp": "1479891545" - }, - "genesis": { - "alloc": { - "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a600035046302d05d3f811461008a5780630accce061461009c5780631ab9075a146100c757806331ed274614610102578063645a3b7214610133578063772fdae314610155578063a7f4377914610180578063ae5f80801461019e578063c9bded21146101ea578063f905c15a14610231575b61023a610002565b61023c600054600160a060020a031681565b61023a600435602435604435606435608435600254600160a060020a03166000141561024657610002565b61023a600435600254600160a060020a03166000148015906100f8575060025433600160a060020a03908116911614155b156102f457610002565b61023a60043560243560443560643560843560a43560c435600254600160a060020a03166000141561031657610002565b61023a600435602435600254600160a060020a0316600014156103d057610002565b61023a600435602435604435606435608435600254600160a060020a03166000141561046157610002565b61023a60025433600160a060020a0390811691161461051657610002565b61023a6004356024356044356060828152600160a060020a0382169060ff8516907fa6c2f0913db6f79ff0a4365762c61718973b3413d6e40382e704782a9a5099f690602090a3505050565b61023a600435602435600160a060020a038116606090815260ff8316907fee6348a7ec70f74e3d6cba55a53e9f9110d180d7698e9117fc466ae29a43e34790602090a25050565b61023c60035481565b005b6060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061029d57610002565b60408051858152602081018390528151600160a060020a03858116939087169260ff8a16927f5a690ecd0cb15c1c1fd6b6f8a32df0d4f56cb41a54fea7e94020f013595de796929181900390910190a45050505050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061036d57610002565b6040805186815260208101869052808201859052606081018490529051600160a060020a03831691889160ff8b16917fd65d9ddafbad8824e2bbd6f56cc9f4ac27ba60737035c10a321ea2f681c94d47919081900360800190a450505050505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061042757610002565b60408051828152905183917fa9c6cbc4bd352a6940479f6d802a1001550581858b310d7f68f7bea51218cda6919081900360200190a25050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104b857610002565b80600160a060020a031684600160a060020a03168660ff167f69bdaf789251e1d3a0151259c0c715315496a7404bce9fd0b714674685c2cab78686604051808381526020018281526020019250505060405180910390a45050505050565b600254600160a060020a0316ff", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0x2cccf5e0538493c235d1c5ef6580f77d99e91396": { - "balance": "0x0", - "code": "0x606060405236156100775760e060020a600035046302d05d3f811461007f57806313bc6d4b146100915780633688a877146100b95780635188f9961461012f5780637eadc976146101545780638ad79680146101d3578063a43e04d814610238578063a7f437791461025e578063e16c7d981461027c575b61029f610002565b6102a1600054600160a060020a031681565b6102be600435600160a060020a03811660009081526002602052604090205460ff165b919050565b6102d26004356040805160208181018352600080835284815260038252835190849020805460026001821615610100026000190190911604601f8101849004840283018401909552848252929390929183018282801561037d5780601f106103525761010080835404028352916020019161037d565b61029f6004356024356000805433600160a060020a039081169116146104a957610002565b61034060043560008181526001602090815260408083205481517ff905c15a0000000000000000000000000000000000000000000000000000000081529151600160a060020a03909116928392839263f905c15a92600483810193919291829003018189876161da5a03f1156100025750506040515195945050505050565b60408051602060248035600481810135601f810185900485028601850190965285855261029f9581359591946044949293909201918190840183828082843750949650505050505050600054600160a060020a0390811633909116146104f657610002565b61029f6004355b600080548190600160a060020a0390811633909116146105a457610002565b61029f60005433600160a060020a0390811691161461072957610002565b6102a1600435600081815260016020526040902054600160a060020a03166100b4565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505090506100b4565b506000828152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a038581168086526002909352818520805460ff191690941790935580517f1ab9075a0000000000000000000000000000000000000000000000000000000081523090931660048401525184939192631ab9075a926024828101939192829003018183876161da5a03f11561000257505060408051602081018690528082019290925243606083015260808083526003908301527f414444000000000000000000000000000000000000000000000000000000000060a0830152517f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d39181900360c00190a15b505050565b600083815260016020526040902054600160a060020a03838116911614156104d0576104a4565b600083815260016020526040812054600160a060020a031614610389576103898361023f565b600082815260036020908152604082208054845182855293839020919360026001831615610100026000190190921691909104601f90810184900483019391929186019083901061056a57805160ff19168380011785555b5061059a9291505b808211156105a05760008155600101610556565b8280016001018555821561054e579182015b8281111561054e57825182600050559160200191906001019061057c565b50505050565b5090565b600083815260016020526040812054600160a060020a031614156105c757610002565b50506000818152600160205260408082205481517fa7f437790000000000000000000000000000000000000000000000000000000081529151600160a060020a0391909116928392839263a7f4377992600483810193919291829003018183876161da5a03f11561000257505050600160005060008460001916815260200190815260200160002060006101000a815490600160a060020a0302191690556002600050600083600160a060020a0316815260200190815260200160002060006101000a81549060ff02191690557f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d383834360405180806020018560001916815260200184600160a060020a03168152602001838152602001828103825260038152602001807f44454c000000000000000000000000000000000000000000000000000000000081526020015060200194505050505060405180910390a1505050565b600054600160a060020a0316ff", - "nonce": "1", - "storage": { - "0x0684ac65a9fa32414dda56996f4183597d695987fdb82b145d722743891a6fe8": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "0x1cd76f78169a420d99346e3501dd3e541622c38a226f9b63e01cfebc69879dc7": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "0x8e54a4494fe5da016bfc01363f4f6cdc91013bb5434bd2a4a3359f13a23afa2f": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf", - "0x94edf7f600ba56655fd65fca1f1424334ce369326c1dc3e53151dcd1ad06bc13": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xbbee47108b275f55f98482c6800f6372165e88b0330d3f5dae6419df4734366c": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "0xd38c0c4e84de118cfdcc775130155d83b8bbaaf23dc7f3c83a626b10473213bd": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xfb3aa5c655c2ec9d40609401f88d505d1da61afaa550e36ef5da0509ada257ba": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113" - } - }, - "0x3e9286eafa2db8101246c2131c09b49080d00690": { - "balance": "0x0", - "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063056d4470146100e957806316c66cc61461010c5780631ab9075a146101935780633ae1005c146101ce57806358541662146101fe5780635ed61af014610231578063644e3b791461025457806384dbac3b146102db578063949ae479146102fd5780639859387b14610321578063a7f4377914610340578063ab03fc261461035e578063e8161b7814610385578063e964d4e114610395578063f905c15a146103a5578063f92eb774146103ae575b6103be610002565b6103c0600054600160a060020a031681565b6103be6004356002546000908190600160a060020a031681141561040357610002565b6103dd60043560006108365b6040805160025460e360020a631c2d8fb30282527f636f6e747261637464620000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435600254600160a060020a03166000148015906101c4575060025433600160a060020a03908116911614155b1561088d57610002565b6103be600435602435604435606435600254600090819081908190600160a060020a03168114156108af57610002565b6103c0600435602435604435606435608435600254600090819081908190600160a060020a03168114156110e857610002565b6103be6004356002546000908190600160a060020a03168114156115ec57610002565b6103c06004356000611b635b6040805160025460e360020a631c2d8fb30282527f6d61726b6574646200000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435602435600254600160a060020a031660001415611bb557610002565b6103be600435602435600254600090600160a060020a0316811415611d2e57610002565b6103be600435600254600160a060020a031660001415611fc657610002565b6103be60025433600160a060020a0390811691161461207e57610002565b6103be600435602435604435600254600090600160a060020a031681141561208c57610002565b6103dd60043560006124b8610260565b6103c0600435600061250a610118565b6103f160035481565b6103f16004356000612561610260565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061046557610002565b8291506104e55b6040805160025460e360020a631c2d8fb30282527f63706f6f6c00000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f115610002575050604051519150505b90565b600160a060020a031663b2206e6d83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fb2206e6d0000000000000000000000000000000000000000000000000000000082526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f11561000257505060405151915061059b90506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f115610002575050506107355b6040805160025460e360020a631c2d8fb30282527f6c6f676d6772000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b50826120ee5b6040805160025460e360020a631c2d8fb30282527f6163636f756e7463746c0000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316630accce06600684600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150866040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050505050565b600160a060020a03166316c66cc6836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150505b919050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061091157610002565b87935061091c610260565b600160a060020a031663bdbdb08685600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fbdbdb0860000000000000000000000000000000000000000000000000000000082526004820152602481018a905290516044808301935060209282900301816000876161da5a03f1156100025750506040515193506109ca90506106ba565b600160a060020a03166381982a7a8885876040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610a3661046c565b600160a060020a03166308636bdb85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517f08636bdb000000000000000000000000000000000000000000000000000000008252600482015260248101889052604481019290925251606482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919450600160a060020a03871692506314baa1b6916024828101926000929190829003018183876161da5a03f11561000257505050610b3561046c565b600160a060020a0316630a3b6ede85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038d16602482015290516044808301935060209282900301816000876161da5a03f115610002575050604051519150610bd590506106ba565b600160a060020a031663d5b205ce87838b6040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610c41610118565b600160a060020a031663988db79c888a6040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050610ca5610260565b600160a060020a031663f4f2821b896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610d6f5b6040805160025460e360020a631c2d8fb30282527f747261646564620000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316635f539d69896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610dc2610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928e9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610ec5610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928d9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610fc8610639565b600160a060020a031663645a3b7285600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151905061101e610260565b600160a060020a031663f92eb77488600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f115610002575050505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061114a57610002565b604051600254600160a060020a0316908a908a908a908a908a90611579806125b38339018087600160a060020a0316815260200186600160a060020a03168152602001856000191681526020018481526020018381526020018281526020019650505050505050604051809103906000f092506111c5610118565b600160a060020a031663b9858a288a856040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611229610260565b600160a060020a0316635188f99689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611288610260565b600160a060020a031663bdbdb08689896040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515192506112e590506106ba565b600160a060020a03166346d88e7d8a858a6040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506000604051808303816000876161da5a03f115610002575050506113516106ba565b600160a060020a03166381982a7a8a84866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050506113bd61046c565b600160a060020a0316632b58469689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f1156100025750505061141c61046c565b600160a060020a03166308636bdb8984866040518460e060020a028152600401808460001916815260200183815260200182600160a060020a0316815260200193505050506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919350600160a060020a03861692506314baa1b6916024828101926000929190829003018183876161da5a03f115610002575050506114d3610639565b6040805160e160020a630566670302815260016004820152602481018b9052600160a060020a0386811660448301528c811660648301526000608483018190529251931692630accce069260a480840193919291829003018183876161da5a03f11561000257505050611544610639565b600160a060020a031663645a3b728961155b610260565b600160a060020a031663f92eb7748c6040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448084019360009350829003018183876161da5a03f1156100025750939a9950505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061164e57610002565b82915061165961046c565b600160a060020a0316630a3b6ede83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f1156100025750506040515191506116f990506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f1156100025750505061179b6106ba565b600160a060020a031663d653078983600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517ff1ff78a0000000000000000000000000000000000000000000000000000000008252915191929163f1ff78a09160048181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f1156100025750505061189f610260565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506118f2610118565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050611945610639565b600160a060020a0316630accce06600484600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da44689181870191602091908190038801816000876161da5a03f115610002575050506040518051906020015060006040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050611a48610639565b600160a060020a031663645a3b7283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611a9e610260565b600160a060020a031663f92eb77486600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b600160a060020a03166381738c59836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611c1757610002565b611c1f610260565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060405151159050611c7457610002565b611c7c610260565b600160a060020a0316632243118a836040518260e060020a02815260040180826000191681526020019150506000604051808303816000876161da5a03f11561000257505050611cca610639565b600160a060020a031663ae5f8080600184846040518460e060020a028152600401808481526020018360001916815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611d9057610002565b5081611d9a610260565b600160a060020a031663581d5d6084846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505050611df5610639565b600160a060020a0316630accce06600283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630566670302825260048201949094526024810193909352600160a060020a038816604484015260006064840181905260848401819052905160a4808501949293509091829003018183876161da5a03f11561000257505050611eab610639565b600160a060020a031663645a3b7282600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611f01610260565b600160a060020a031663f92eb77485600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061202857610002565b612030610118565b600160a060020a0316639859387b826040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505050565b600254600160a060020a0316ff5b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f11561000257505060405151151590506106b457610002565b600160a060020a031663d65307898383600160a060020a031663f1ff78a06040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fd6530789000000000000000000000000000000000000000000000000000000008252600160a060020a039485166004830152602482015292891660448401525160648381019360009350829003018183876161da5a03f115610002575050506121a5610118565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506121f8610cf4565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505061224b610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d028252915191928a9290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f1156100025750505080600160a060020a031663ea71b02d6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a031660001490506124b25761239f610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fea71b02d000000000000000000000000000000000000000000000000000000008252915191928a92909163ea71b02d91600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f115610002575050505b50505050565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663213fe2b7836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663f92eb774836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610888905056606060405260405160c08061157983396101206040819052825160805160a051935160e0516101005160008054600160a060020a03199081163317909155600180546005805484168817905560048a90556006869055600b8590556008849055909116861760a060020a60ff02191690554360038190556002558686526101408390526101608190529396929594919390929091600160a060020a033016917f76885d242fb71c6f74a7e717416e42eff4d96faf54f6de75c6a0a6bbd8890c6b91a230600160a060020a03167fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff600b600050546040518082815260200191505060405180910390a250505050505061145e8061011b6000396000f3606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "16", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0x70c9217d814985faef62b124420f8dfbddd96433": { - "balance": "0x4ef436dcbda6cd4a", - "code": "0x", - "nonce": "1634", - "storage": {} - }, - "0x7986bad81f4cbd9317f5a46861437dae58d69113": { - "balance": "0x0", - "code": "0x6060604052361561008d5760e060020a600035046302d05d3f811461009557806316c66cc6146100a75780631ab9075a146100d7578063213fe2b7146101125780639859387b1461013f578063988db79c1461015e578063a7f4377914610180578063b9858a281461019e578063c8e40fbf146101c0578063f4f2821b146101e8578063f905c15a14610209575b610212610002565b610214600054600160a060020a031681565b600160a060020a0360043581811660009081526005602052604081205461023193168114610257575060016101e3565b610212600435600254600160a060020a0316600014801590610108575060025433600160a060020a03908116911614155b1561025f57610002565b610214600435600160a060020a03811660009081526004602052604081205460ff16151561027557610002565b610212600435600254600160a060020a03166000141561029b57610002565b610212600435602435600254600160a060020a03166000141561050457610002565b61021260025433600160a060020a0390811691161461056757610002565b610212600435602435600254600160a060020a03166000141561057557610002565b610231600435600160a060020a03811660009081526004602052604090205460ff165b919050565b610212600435600254600090600160a060020a031681141561072057610002565b61024560035481565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060006101e3565b60028054600160a060020a031916821790555b50565b50600160a060020a038181166000908152600460205260409020546101009004166101e3565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506102fe57610002565b600160a060020a03811660009081526004602052604090205460ff161515610272576040516104028061092e833901809050604051809103906000f06004600050600083600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600083600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555050565b600160a060020a03821660009081526004602052604090205460ff1615156104725760405161040280610d30833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a03811660009081526006602052604090208054600160a060020a031916831790555b5050565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506103b957610002565b600254600160a060020a0316ff5b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506105d857610002565b600160a060020a03821660009081526004602052604090205460ff1615156106915760405161040280611132833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a031660009081526005602052604090208054600160a060020a0319169091179055565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f115610002575050604051511515905061078357610002565b50600160a060020a0381811660009081526005602090815260408083205490931680835260049091529190205460ff161561080f576040600081812054825160e260020a632e72bafd028152600160a060020a03868116600483015293516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260056020526040812054909116146108545760406000908120600160a060020a0384169091528054600160a060020a03191690555b50600160a060020a0381811660009081526006602090815260408083205490931680835260049091529190205460ff16156108e657600160a060020a038181166000908152604080518183205460e260020a632e72bafd028252868516600483015291516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260066020526040812054909116146105005760406000908120600160a060020a0384169091528054600160a060020a0319169055505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056", - "nonce": "7", - "storage": { - "0xffc4df2d4f3d2cffad590bed6296406ab7926ca9e74784f74a95191fa069a174": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433" - } - }, - "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f": { - "balance": "0x0", - "code": "0x606060405236156100ae5760e060020a600035046302d05d3f81146100b65780631ab9075a146100c85780632b68bb2d146101035780634cc927d7146101c557806351a34eb81461028e57806356ccb6f0146103545780635928d37f1461041d578063599efa6b146104e9578063759297bb146105b2578063771d50e11461067e578063a7f4377914610740578063f905c15a1461075e578063f92eb77414610767578063febf661214610836575b610902610002565b610904600054600160a060020a031681565b610902600435600254600160a060020a03166000148015906100f9575060025433600160a060020a03908116911614155b1561092057610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061094257610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610a0d57610002565b61090260043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ae957610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610bbc57610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610c9657610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610de057610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ebb57610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f9e57610002565b61090260025433600160a060020a0390811691161461106957610002565b61090e60035481565b61090e60043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750506040805180517ff92eb774000000000000000000000000000000000000000000000000000000008252600482018790529151919350600160a060020a038416925063f92eb774916024828101926020929190829003018188876161da5a03f11561000257505060405151949350505050565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061107757610002565b005b6060908152602090f35b60408051918252519081900360200190f35b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5ed61af000000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152925190959286169350635ed61af092602483810193919291829003018183876161da5a03f115610002575050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fab03fc2600000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015260248301899052808816604484015292519095928616935063ab03fc2692606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f949ae47900000000000000000000000000000000000000000000000000000000825233600160a060020a0390811660048401526024830188905292519095928616935063949ae47992604483810193919291829003018183876161da5a03f11561000257505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f46d88e7d000000000000000000000000000000000000000000000000000000008252600160a060020a0380891660048401523381166024840152604483018890529251909592861693506346d88e7d92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5315cdde00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a16602484015260448301889052925190959286169350635315cdde92606483810193919291829003018183876161da5a03f115610002575050604080517f5928d37f00000000000000000000000000000000000000000000000000000000815233600160a060020a03908116600483015287166024820152604481018690529051635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fe68e401c00000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015280891660248401526044830188905292519095928616935063e68e401c92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5152f381000000000000000000000000000000000000000000000000000000008252600160a060020a03808a1660048401528089166024840152604483018890523381166064840152925190959286169350635152f38192608483810193919291829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f056d447000000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015292519095928616935063056d447092602483810193919291829003018183876161da5a03f115610002575050505050565b600254600160a060020a0316ff5b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f3ae1005c00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a166024840152808916604484015260648301889052925190959286169350633ae1005c92608483810193919291829003018183876161da5a03f11561000257505050505050505056", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": { - "balance": "0x0", - "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000006195", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5842545553440000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000" - } - }, - "0xcf00ffd997ad14939736f026006498e3f099baaf": { - "balance": "0x0", - "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063031e7f5d146100e95780631ab9075a1461010b5780632243118a1461014657806327aad68a1461016557806338a699a4146101da5780635188f996146101f8578063581d5d601461021e57806381738c5914610246578063977da54014610269578063a07421ce14610288578063a7f43779146102be578063bdbdb086146102dc578063e1c7111914610303578063f4f2821b14610325578063f905c15a1461034a578063f92eb77414610353575b610387610002565b610389600054600160a060020a031681565b610387600435602435600254600160a060020a0316600014156103a857610002565b610387600435600254600160a060020a031660001480159061013c575060025433600160a060020a03908116911614155b1561042957610002565b610387600435600254600160a060020a03166000141561044b57610002565b6102ac60043560008181526004602081815260408320547f524d81d3000000000000000000000000000000000000000000000000000000006060908152610100909104600160a060020a031692839263524d81d3926064928188876161da5a03f1156100025750506040515192506103819050565b61039c60043560008181526004602052604090205460ff165b919050565b6103876004356024356002546000908190600160a060020a031681141561079457610002565b61038760043560243560025460009081908190600160a060020a031681141561080457610002565b61038960043560008181526004602052604081205460ff1615156109e357610002565b610387600435600254600160a060020a0316600014156109fb57610002565b600435600090815260096020526040902054670de0b6b3a764000090810360243502045b60408051918252519081900360200190f35b61038760025433600160a060020a03908116911614610a9257610002565b600435600090815260086020526040902054670de0b6b3a7640000602435909102046102ac565b610387600435602435600254600160a060020a031660001415610aa057610002565b61038760043560025460009081908190600160a060020a0316811415610b3657610002565b6102ac60035481565b6102ac600435600081815260076020908152604080832054600690925290912054670de0b6b3a76400000204805b50919050565b005b600160a060020a03166060908152602090f35b15156060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506103fe57610002565b60008281526004602052604090205460ff16151561041b57610002565b600860205260406000205550565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104a157610002565b604080516000838152600460205291909120805460ff1916600117905561040280610de2833901809050604051809103906000f0600460005060008360001916815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555066470de4df8200006008600050600083600019168152602001908152602001600020600050819055506703782dace9d9000060096000506000836000191681526020019081526020016000206000508190555050565b600460005060008560001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151821415905061060057838152600660209081526040808320839055600790915281208190555b81600160a060020a0316630a3b0a4f846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050600160a060020a038316808252600560209081526040808420879055805160e160020a6364a81ff102815290518694670de0b6b3a7640000949363c9503fe29360048181019492939183900301908290876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008660001916815260200190815260200160002060008282825054019250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000866000191681526020019081526020016000206000828282505401925050819055505b50505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f11561000257505060405151151590506107e957610002565b8381526004602052604081205460ff16151561056657610002565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f115610002575050604051511515905061085957610002565b849250670de0b6b3a764000083600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575060408051805160e160020a6364a81ff102825291519189028590049650600481810192602092909190829003018188876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b9391600481810192602092909190829003018189876161da5a03f115610002575050506040518051906020015002049050806006600050600085600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750604080518051855260208681528286208054989098039097557f2e94420f00000000000000000000000000000000000000000000000000000000815290518896600483810193919291829003018187876161da5a03f115610002575050604080515183526020939093525020805490910190555050505050565b60409020546101009004600160a060020a03166101f3565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610a5157610002565b60008181526004602052604090205460ff161515610a6e57610002565b6040600020805474ffffffffffffffffffffffffffffffffffffffffff1916905550565b600254600160a060020a0316ff5b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610af657610002565b60008281526004602052604090205460ff161515610b1357610002565b670de0b6b3a7640000811115610b2857610002565b600960205260406000205550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f1156100025750506040515115159050610b8b57610002565b600160a060020a038416815260056020908152604080832054808452600490925282205490935060ff161515610bc057610002565b600460005060008460001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663b9caebf4856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506005600050600085600160a060020a0316815260200190815260200160002060005060009055839050600082600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519190911115905061078e57670de0b6b3a764000081600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008560001916815260200190815260200160002060008282825054039250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000856000191681526020019081526020016000206000828282505403925050819055505050505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056", - "nonce": "3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x3571d73f14f31a1463bd0a2f92f7fde1653d4e1ead7aedf4b0a5df02f16092ab": "0x0000000000000000000000000000000000000000000007d634e4c55188be0000", - "0x4e64fe2d1b72d95a0a31945cc6e4f4e524ac5ad56d6bd44a85ec7bc9cc0462c0": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000" - } - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "117124093", - "extraData": "0xd5830105008650617269747986312e31322e31826d61", - "gasLimit": "4707788", - "hash": "0xad325e4c49145fb7a4058a68ac741cc8607a71114e23fc88083c7e881dd653e7", - "miner": "0x00714b9ac97fd6bd9325a059a70c9b9fa94ce050", - "mixHash": "0x0af918f65cb4af04b608fc1f14a849707696986a0e7049e97ef3981808bcc65f", - "nonce": "0x38dee147326a8d40", - "number": "25000", - "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b", - "timestamp": "1479891517", - "totalDifficulty": "1895410389427" - }, - "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065", - "result": [ - { - "action": { - "callType": "call", - "from": "0x70c9217d814985faef62b124420f8dfbddd96433", - "gas": "0x3d090", - "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 25001, - "result": { - "gasUsed": "0x1810b", - "output": "0x" - }, - "subtraces": 2, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "gas": "0x31217", - "input": "0xe16c7d98636f6e7472616374617069000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f" - }, - "subtraces": 0, - "traceAddress": [0], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "gas": "0x30b4a", - "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0xedb7", - "output": "0x" - }, - "subtraces": 4, - "traceAddress": [1], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x2a68d", - "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690" - }, - "subtraces": 0, - "traceAddress": [1, 0], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x29f35", - "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b", - "to": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0xf8d", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 2, - "traceAddress": [1, 1], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x23ac9", - "input": "0xe16c7d98636f6e7472616374646200000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113" - }, - "subtraces": 0, - "traceAddress": [1, 1, 0], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x23366", - "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b", - "to": "0x7986bad81f4cbd9317f5a46861437dae58d69113", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x273", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [1, 1, 1], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x28a9e", - "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690" - }, - "subtraces": 0, - "traceAddress": [1, 2], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x283b9", - "input": "0x949ae479000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0xc51c", - "output": "0x" - }, - "subtraces": 12, - "traceAddress": [1, 3], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x21d79", - "input": "0x13bc6d4b000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x24d", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [1, 3, 0], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x2165b", - "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf" - }, - "subtraces": 0, - "traceAddress": [1, 3, 1], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x20ee1", - "input": "0x581d5d60000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000", - "to": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x5374", - "output": "0x" - }, - "subtraces": 6, - "traceAddress": [1, 3, 2], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1a8e8", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x24d", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [1, 3, 2, 0], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1a2c6", - "input": "0xc9503fe2", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x3cb", - "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 2, 1], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x19b72", - "input": "0xc9503fe2", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x3cb", - "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 2, 2], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x19428", - "input": "0x6f265b93", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x305", - "output": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 2, 3], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x18d45", - "input": "0x2e94420f", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x229", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 2, 4], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1734e", - "input": "0x2e94420f", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x229", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 2, 5], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1b6c1", - "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38" - }, - "subtraces": 0, - "traceAddress": [1, 3, 3], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1af69", - "input": "0x2e94420f", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x229", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 4], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1a91d", - "input": "0x0accce0600000000000000000000000000000000000000000000000000000000000000025842545553440000000000000000000000000000000000000000000000000000000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x12fa", - "output": "0x" - }, - "subtraces": 1, - "traceAddress": [1, 3, 5], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "gas": "0x143a5", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x24d", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [1, 3, 5, 0], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x19177", - "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38" - }, - "subtraces": 0, - "traceAddress": [1, 3, 6], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x18a22", - "input": "0x2e94420f", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x229", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 7], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x18341", - "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x334", - "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf" - }, - "subtraces": 0, - "traceAddress": [1, 3, 8], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x17bec", - "input": "0x2e94420f", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x229", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 9], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1764e", - "input": "0xf92eb7745842545553440000000000000000000000000000000000000000000000000000", - "to": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x45c", - "output": "0x00000000000000000000000000000000000000000000002816d180e30c390000" - }, - "subtraces": 0, - "traceAddress": [1, 3, 10], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x16e62", - "input": "0x645a3b72584254555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002816d180e30c390000", - "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0xebb", - "output": "0x" - }, - "subtraces": 1, - "traceAddress": [1, 3, 11], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "gas": "0x108ba", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x24d", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [1, 3, 11, 0], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json deleted file mode 100644 index e5a37cbfdd..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "context": { - "difficulty": "31927752", - "gasLimit": "4707788", - "miner": "0x5659922ce141eedbc2733678f9806c77b4eebee8", - "number": "11495", - "timestamp": "1479735917" - }, - "genesis": { - "alloc": { - "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a60003504630a0313a981146100875780630a3b0a4f146101095780630cd40fea1461021257806329092d0e1461021f5780634cd06a5f146103295780635dbe47e8146103395780637a9e5410146103d9578063825db5f7146103e6578063a820b44d146103f3578063efa52fb31461047a575b610002565b34610002576104fc600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a26333556e849091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f415610002575050604051519150505b919050565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f21ce24d4000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926321ce24d49260448082019391829003018186803b156100025760325a03f415610002575050505b50565b3461000257610512600181565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f89489a87000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926389489a879260448082019391829003018186803b156100025760325a03f4156100025750505061020f565b3461000257610528600435610403565b34610002576104fc600435604080516000602091820181905282517f7d65837a00000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152925190927342b02b5deeb78f34cd5ac896473b63e6c99a71a292637d65837a92604480840193829003018186803b156100025760325a03f4156100025750506040515191506101049050565b3461000257610512600c81565b3461000257610512600081565b3461000257610528600061055660005b600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263685a1f3c9091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b346100025761053a600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263f775b6b59091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b604080519115158252519081900360200190f35b005b6040805160ff9092168252519081900360200190f35b60408051918252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b90509056", - "nonce": "1", - "storage": { - "0x4d140b25abf3c71052885c66f73ce07cff141c1afabffdaf5cba04d625b7ebcc": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - }, - "0x269296dddce321a6bcbaa2f0181127593d732cba": { - "balance": "0x0", - "code": "0x606060405236156101275760e060020a60003504630cd40fea811461012c578063173825d9146101395780631849cb5a146101c7578063285791371461030f5780632a58b3301461033f5780632cb0d48a146103565780632f54bf6e1461036a578063332b9f061461039d5780633ca8b002146103c55780633df4ddf4146103d557806341c0e1b5146103f457806347799da81461040557806362a51eee1461042457806366907d13146104575780637065cb48146104825780637a9e541014610496578063825db5f7146104a3578063949d225d146104b0578063a51687df146104c7578063b4da4e37146104e6578063b4e6850b146104ff578063bd7474ca14610541578063e75623d814610541578063e9938e1114610555578063f5d241d314610643575b610002565b3461000257610682600181565b34610002576106986004356106ff335b60006001600a9054906101000a9004600160a060020a0316600160a060020a0316635dbe47e8836000604051602001526040518260e060020a0281526004018082600160a060020a03168152602001915050602060405180830381600087803b156100025760325a03f1156100025750506040515191506103989050565b3461000257604080516101008082018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a0360043581168752600586529589902089519788018a528054808816808a52605060020a91829004600160a060020a0316978a01889052600183015463ffffffff8082169d8c018e905264010000000082048116988c01899052604060020a90910416958a018690526002830154948a01859052600390920154808916938a01849052049096169690970186905293969495949293604080516001605060020a03998a16815297891660208901529590971686860152600160a060020a03909316606086015263ffffffff9182166080860152811660a08501521660c083015260e08201929092529051908190036101000190f35b346100025761069a60043560018054600091829160ff60f060020a909104161515141561063d5761072833610376565b34610002576106ae6004546001605060020a031681565b34610002576106986004356108b333610149565b346100025761069a6004355b600160a060020a03811660009081526002602052604090205460ff1615156001145b919050565b34610002576106986001805460ff60f060020a9091041615151415610913576108ed33610376565b346100025761069a600435610149565b34610002576106ae6003546001605060020a03605060020a9091041681565b346100025761069861091533610149565b34610002576106ae6003546001605060020a0360a060020a9091041681565b346100025761069a60043560243560018054600091829160ff60f060020a909104161515141561095e5761092633610376565b34610002576106986004356001805460ff60f060020a909104161515141561072557610a8b33610376565b3461000257610698600435610aa533610149565b3461000257610682600c81565b3461000257610682600081565b34610002576106ae6003546001605060020a031681565b34610002576106ca600154600160a060020a03605060020a9091041681565b346100025761069a60015460ff60f060020a9091041681565b346100025761069a60043560243560443560643560843560a43560c43560018054600091829160ff60f060020a9091041615151415610b5857610ad233610376565b3461000257610698600435610bd633610149565b34610002576106e6600435604080516101008181018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a03808b168752600586529589902089519788018a5280548088168952600160a060020a03605060020a918290041696890196909652600181015463ffffffff8082169b8a019b909b5264010000000081048b1695890195909552604060020a90940490981691860182905260028301549086015260039091015480841696850196909652940416918101919091525b50919050565b346100025761069a60043560243560443560643560843560a43560018054600091829160ff60f060020a9091041615151415610c8e57610bfb33610376565b6040805160ff9092168252519081900360200190f35b005b604080519115158252519081900360200190f35b604080516001605060020a039092168252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b6040805163ffffffff9092168252519081900360200190f35b1561012757600160a060020a0381166000908152600260205260409020805460ff191690555b50565b1561063d57506001605060020a0380831660009081526005602052604090208054909116151561075b576000915061063d565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610817905b8051600354600090819060016001605060020a0390911611610c995760038054605060020a60f060020a0319169055610ddf565b600380546001605060020a031981166000196001605060020a03928316011782558416600090815260056020526040812080547fffff000000000000000000000000000000000000000000000000000000000000168155600181810180546bffffffffffffffffffffffff191690556002820192909255909101805473ffffffffffffffffffffffffffffffffffffffff19169055915061063d565b1561012757600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a8302179055610725565b1561091357600480546001605060020a031981166001605060020a039091166001011790555b565b156101275733600160a060020a0316ff5b1561095e57506001605060020a03808416600090815260056020526040902080549091161515610965576000915061095e565b600191505b5092915050565b60038101546001605060020a0384811691161415610986576001915061095e565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610a12906107e3565b61095983825b80546003546001605060020a0391821691600091161515610de55760038054605060020a60a060020a031916605060020a84021760a060020a69ffffffffffffffffffff02191660a060020a84021781558301805473ffffffffffffffffffffffffffffffffffffffff19169055610ddf565b1561072557600480546001605060020a0319168217905550565b1561012757600160a060020a0381166000908152600260205260409020805460ff19166001179055610725565b15610b5857506001605060020a038088166000908152600560205260409020805490911615610b645760009150610b58565b6004546001605060020a0390811690891610610b3057600480546001605060020a03191660018a011790555b6003805460016001605060020a03821681016001605060020a03199092169190911790915591505b50979650505050505050565b80546001605060020a0319168817605060020a60f060020a031916605060020a880217815560018101805463ffffffff1916871767ffffffff0000000019166401000000008702176bffffffff00000000000000001916604060020a860217905560028101839055610b048982610a18565b156101275760018054605060020a60f060020a031916605060020a8302179055610725565b15610c8e57506001605060020a03808816600090815260056020526040902080549091161515610c2e5760009150610c8e565b8054605060020a60f060020a031916605060020a88021781556001808201805463ffffffff1916881767ffffffff0000000019166401000000008802176bffffffff00000000000000001916604060020a87021790556002820184905591505b509695505050505050565b6003546001605060020a03848116605060020a909204161415610d095760e084015160038054605060020a928302605060020a60a060020a031990911617808255919091046001605060020a031660009081526005602052604090200180546001605060020a0319169055610ddf565b6003546001605060020a0384811660a060020a909204161415610d825760c08401516003805460a060020a92830260a060020a69ffffffffffffffffffff021990911617808255919091046001605060020a03166000908152600560205260409020018054605060020a60a060020a0319169055610ddf565b505060c082015160e08301516001605060020a0380831660009081526005602052604080822060039081018054605060020a60a060020a031916605060020a8702179055928416825290200180546001605060020a031916831790555b50505050565b6001605060020a0384161515610e6457600380546001605060020a03605060020a9182900481166000908152600560205260409020830180546001605060020a0319908116871790915583548785018054918590049093168402605060020a60a060020a03199182161790911690915582549185029116179055610ddf565b506001605060020a038381166000908152600560205260409020600390810180549185018054605060020a60a060020a0319908116605060020a94859004909516808502959095176001605060020a0319168817909155815416918402919091179055801515610ef4576003805460a060020a69ffffffffffffffffffff02191660a060020a8402179055610ddf565b6003808401546001605060020a03605060020a9091041660009081526005602052604090200180546001605060020a031916831790555050505056", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000113204f5d64c28326fd7bd05fd4ea855302d7f2ff00000000000000000000" - } - }, - "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2": { - "balance": "0x0", - "code": "0x6504032353da7150606060405236156100695760e060020a60003504631bf7509d811461006e57806321ce24d41461008157806333556e84146100ec578063685a1f3c146101035780637d65837a1461011757806389489a8714610140578063f775b6b5146101fc575b610007565b61023460043560006100fd82600061010d565b610246600435602435600160a060020a03811660009081526020839052604081205415156102cb57826001016000508054806001018281815481835581811511610278576000838152602090206102789181019083015b808211156102d057600081556001016100d8565b610248600435602435600182015481105b92915050565b6102346004356024355b60018101906100fd565b610248600435602435600160a060020a03811660009081526020839052604090205415156100fd565b61024660043560243580600160a060020a031632600160a060020a03161415156101f857600160a060020a038116600090815260208390526040902054156101f857600160a060020a038116600090815260208390526040902054600183018054909160001901908110156100075760009182526020808320909101805473ffffffffffffffffffffffffffffffffffffffff19169055600160a060020a038316825283905260408120556002820180546000190190555b5050565b61025c60043560243560008260010160005082815481101561000757600091825260209091200154600160a060020a03169392505050565b60408051918252519081900360200190f35b005b604080519115158252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b50505060009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a0385168352908590526040909120819055600284018054600101905590505b505050565b509056", - "nonce": "1", - "storage": {} - }, - "0xa529806c67cc6486d4d62024471772f47f6fd672": { - "balance": "0x67820e39ac8fe9800", - "code": "0x", - "nonce": "68", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "31912170", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712388", - "hash": "0x0855914bdc581bccdc62591fd438498386ffb59ea4d5361ed5c3702e26e2c72f", - "miner": "0x334391aa808257952a462d1475562ee2106a6c90", - "mixHash": "0x64bb70b8ca883cadb8fbbda2c70a861612407864089ed87b98e5de20acceada6", - "nonce": "0x684129f283aaef18", - "number": "11494", - "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10", - "timestamp": "1479735912", - "totalDifficulty": "90744064339" - }, - "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115", - "result": [ - { - "action": { - "callType": "call", - "from": "0xa529806c67cc6486d4d62024471772f47f6fd672", - "gas": "0x2dc6c0", - "input": "0x7065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e", - "to": "0x269296dddce321a6bcbaa2f0181127593d732cba", - "value": "0x0" - }, - "blockNumber": 11495, - "result": { - "gasUsed": "0xbd55", - "output": "0x" - }, - "subtraces": 1, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x269296dddce321a6bcbaa2f0181127593d732cba", - "gas": "0x2cae73", - "input": "0x5dbe47e8000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672", - "to": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0xa9d", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 1, - "traceAddress": [0], - "type": "call" - }, - { - "action": { - "callType": "delegatecall", - "from": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff", - "gas": "0x2bf459", - "input": "0x7d65837a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672", - "to": "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2", - "value": "0x0" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x2aa", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [0, 0], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json deleted file mode 100644 index 177912420a..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/delegatecall_parent_value.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "genesis": { - "number": "566098", - "hash": "0xba134562590a59291892395a29c5088899c2c64d720135dad88f7f076cf55f5f", - "nonce": "0x4b281be9594e3eb3", - "mixHash": "0xdb4ec386166d9c0dc9ba147755ecbb87af9f0a22563cbda02c799efa4e29db6e", - "stateRoot": "0xfc01993ad96a8fb8790a093cea4f505f8db1b0e1143c5f57bb1d173db0baa9e3", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "difficulty": "1926740", - "totalDifficulty": "482216286599", - "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", - "gasLimit": "19388354", - "timestamp": "1577558314", - "alloc": { - "0x6ab9dd83108698b9ca8d03af3c7eb91c0e54c3fc": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0xcbd5b9b25d1c38c2aad", - "nonce": "134969", - "code": "0x", - "storage": {} - }, - "0x91765918420bcb5ad22ee0997abed04056705798": { - "balance": "0x0", - "nonce": "1", - "code": "0x366000803760206000366000736ab9dd83108698b9ca8d03af3c7eb91c0e54c3fc60325a03f41560015760206000f3", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "566099", - "difficulty": "1927680", - "timestamp": "1577558317", - "gasLimit": "19369422", - "miner": "0x774c398d763161f55b66a646f17edda4addad2ca" - }, - "input": "0xf87983020f3985746a52880083015f909491765918420bcb5ad22ee0997abed04056705798888ac7230489e80000884e45375a4741394181a1a04b7260723fd02830754916b3bdf1537b6a851a7ae27c7e9296cfe1fc8275ec08a049d32158988eb717d61b4503b27c7583037c067daba1eb56f4bdfafc1b0045f6", - "result": [ - { - "action": { - "callType": "call", - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "gas": "0x15f90", - "input": "0x4e45375a47413941", - "to": "0x91765918420bcb5ad22ee0997abed04056705798", - "value": "0x8ac7230489e80000" - }, - "blockHash": "0xb05cc5c8f11df2b5d53ced342ee79e2805785f04c2f40add4539f27bd349f74e", - "blockNumber": 566099, - "result": { - "gasUsed": "0x5721", - "output": "0x4e45375a47413941000000000000000000000000000000000000000000000000" - }, - "subtraces": 1, - "traceAddress": [], - "transactionHash": "0x6e26dffe2f66186f03a2c36a16a4cd9724d07622c83746f1e35f988515713d4b", - "transactionPosition": 10, - "type": "call" - }, - { - "action": { - "callType": "delegatecall", - "from": "0x91765918420bcb5ad22ee0997abed04056705798", - "gas": "0x10463", - "input": "0x4e45375a47413941", - "to": "0x6ab9dd83108698b9ca8d03af3c7eb91c0e54c3fc", - "value": "0x8ac7230489e80000" - }, - "blockHash": "0xb05cc5c8f11df2b5d53ced342ee79e2805785f04c2f40add4539f27bd349f74e", - "blockNumber": 566099, - "result": { - "gasUsed": "0x0", - "output": "0x" - }, - "subtraces": 0, - "traceAddress": [ - 0 - ], - "transactionHash": "0x6e26dffe2f66186f03a2c36a16a4cd9724d07622c83746f1e35f988515713d4b", - "transactionPosition": 10, - "type": "call" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json deleted file mode 100644 index d977dbe30d..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/gas.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "genesis": { - "difficulty": "4683014", - "extraData": "0x537465762d63676574682d76312e31312e34", - "gasLimit": "9435044", - "hash": "0x3452ca5005cb73cd60dfa488a7b124251168e564491f80eb66765e79d78cfd95", - "miner": "0x415aa6292d1db797a467b22139704956c030e62f", - "mixHash": "0x6037612618507ae70c74a72bc2580253662971db959cfbc06d3f8527d4d01575", - "nonce": "0x314fc90dee5e39a2", - "number": "1555274", - "stateRoot": "0x795751f3f96a5de1fd3944ddd78cbfe4ef10491e1086be47609869a30929d0e5", - "timestamp": "1590795228", - "totalDifficulty": "2242595605834", - "alloc": { - "0x0000000000000000000000000000000000000001": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x6242e3ccf48e66425fb1", - "nonce": "264882", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555275", - "difficulty": "4683014", - "timestamp": "1590795244", - "gasLimit": "9444256", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf9011583040ab2843b9aca008301a9c88080b8c0601b565b6000555b005b630badf00d6003565b63c001f00d6003565b7319e7e376e7c213b7e7e7e46cc70a5dd086daff2a7f22ae6da6b482f9b1b19b0b897c3fd43884180a1c5ee361e1107a1bc635649dda600052601b603f537f16433dce375ce6dc8151d3f0a22728bc4a1d9fd6ed39dfd18b4609331937367f6040527f306964c0cf5d74f04129fdc60b54d35b596dde1bf89ad92cb4123318f4c0e40060605260206080607f60006000600161fffff2156007576080511460125760095681a1a07682fc43dbe1fb13c6474f5e70e121c826dd996168d8bb1d8ca7a63470127b46a00a25b308ba417b7770899e8f98a3f0c14aa9bf7db0edacfe4e78d00dbbd3c31e", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x1a9c8", - "init": "0x601b565b6000555b005b630badf00d6003565b63c001f00d6003565b7319e7e376e7c213b7e7e7e46cc70a5dd086daff2a7f22ae6da6b482f9b1b19b0b897c3fd43884180a1c5ee361e1107a1bc635649dda600052601b603f537f16433dce375ce6dc8151d3f0a22728bc4a1d9fd6ed39dfd18b4609331937367f6040527f306964c0cf5d74f04129fdc60b54d35b596dde1bf89ad92cb4123318f4c0e40060605260206080607f60006000600161fffff21560075760805114601257600956" - }, - "result": { - "gasUsed": "0x137e5", - "code": "0x", - "address": "0x1a05d76017ca02010533a470e05e8925a0380d8f" - }, - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 18, - "transactionHash": "0xc1c42a325856d513523aec464811923b2e2926f54015c7ba37877064cf889803", - "blockNumber": 1555275, - "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd", - "time": "453.925µs" - }, - { - "type": "call", - "action": { - "from": "0x1a05d76017ca02010533a470e05e8925a0380d8f", - "to": "0x0000000000000000000000000000000000000001", - "value": "0x0", - "gas": "0xc8c6", - "input": "0x22ae6da6b482f9b1b19b0b897c3fd43884180a1c5ee361e1107a1bc635649dda000000000000000000000000000000000000000000000000000000000000001b16433dce375ce6dc8151d3f0a22728bc4a1d9fd6ed39dfd18b4609331937367f306964c0cf5d74f04129fdc60b54d35b596dde1bf89ad92cb4123318f4c0e4", - "callType": "callcode" - }, - "result": { - "gasUsed": "0xbb8", - "output": "0x00000000000000000000000019e7e376e7c213b7e7e7e46cc70a5dd086daff2a" - }, - "traceAddress": [0], - "subtraces": 0, - "transactionPosition": 18, - "transactionHash": "0xc1c42a325856d513523aec464811923b2e2926f54015c7ba37877064cf889803", - "blockNumber": 1555275, - "blockHash": "0x80945caaff2fc67253cbb0217d2e5a307afde943929e97d8b36e58b88cbb02fd" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json deleted file mode 100644 index 0f28c07a9b..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/include_precompiled.json +++ /dev/null @@ -1,832 +0,0 @@ -{ - "genesis": { - "number": "559197", - "hash": "0x0742a2bfab0452e2c634f3685b7e49ceb065c7000609b2b73f086e01fd1dfb58", - "nonce": "0x3060ad521440e1c2", - "mixHash": "0x59e7d4ae6cc3c38d23dac3f869b21984c7ba8f38070f4116a4941d9c403b6299", - "stateRoot": "0x68418fb5cf4afa9b807dc079e8cdde0e148ac2c8afb378e675465b5bed1fbd02", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "difficulty": "1813945", - "totalDifficulty": "469107641961", - "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", - "gasLimit": "6321166", - "timestamp": "1577471202", - "alloc": { - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0xc5e6fdae52af83f7e28", - "nonce": "77947", - "code": "0x", - "storage": {} - }, - "0x774c398d763161f55b66a646f17edda4addad2ca": { - "balance": "0xf09ef316eff819ee488", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc": { - "balance": "0x0", - "nonce": "1", - "code": "0x60006121df537c01000000000000000000000000000000000000000000000000000000006000350463b041b2858114156100d257600435604052780100000000000000000000000000000000000000000000000060606060599059016000905260038152604051816020015260008160400152809050205404606052606051151561008f57600060a052602060a0f35b604051601c604459905901600090520163e0e9a17b601c82035260605160048201526020610100602483600030602d5a03f1506101005190501460c052602060c0f35b632cce81aa81141561019957600435610120526001610120511280156100f85780610143565b78010000000000000000000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540461012051135b905015610157576000610180526020610180f35b601c604459905901600090520163e0e9a17b601c82035261012051600482015260206101c0602483600030602d5a03f1506101c05190506101a05260206101a0f35b63e0e9a17b8114156102e957600435610120526604000000000002546101e0526007610200525b610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540413156102da575b6102005160050a610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e051816020015260008160400152809050205404031215610269576000610200511361026c565b60005b1561028157600161020051036102005261020b565b7c01000000000000000000000000000000000000000000000000000000006102005160200260020a606060605990590160009052600381526101e05181602001526001816040015280905020540204546101e0526101c0565b6101e051610280526020610280f35b63cef887b08114156103e757365990590160009052366004823760043560208201016102c0526024356102e052506060601c61014c5990590160009052016390fa337d601c8203526102c0516020601f602083035101046020026020018360048401526020820360648401528060c8840152808401935050506102e051602482015233604482015281600401599059016000905260648160648460006004601cf161039057fe5b60648101925060c882015180808582606487015160006004600a8705601201f16103b657fe5b5080840193505080830360206103a08284600030602d5a03f1506103a0519050905090509050610300526020610300f35b6390fa337d81141561065f57365990590160009052366004823760043560208201016102c0526024356102e0526044356103e052505a610400526020601c608c599059016000905201632b861629601c8203526102c0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161048a57fe5b602481019250604882015180808582602487015160006004600a8705601201f16104b057fe5b5080840193505080830360206104408284600030602d5a03f15061044051905090509050905061042052610420511561065e576102c05160208103516020599059016000905260208183856000600287604801f150805190509050905061046052602059905901600090526020816020610460600060026068f1508051905060005b6020811215610552578181601f031a816105400153600181019050610532565b5050610540516101e0526102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020555a61058052700100000000000000000000000000000000660400000000000154046105a0526104006105a0516103ff02056105c0526104006105a05161040102056105e0526105c0513a12156105f6576105c05161060052610615565b6105e0513a131561060e576105e05161060052610614565b3a610600525b5b6105805161040051036106005160020202610620526106205170010000000000000000000000000000000061060051021766040000000000015561042051610640526020610640f35b5b63d467ae0381141561073257600435604052602435610660526106605134121515610725576000341315610718576c01000000000000000000000000606060605990590160009052600381526040518160200152600381604001528090502054046103e0526000600060006000346103e051611388f115156106dd57fe5b601c60405990590160009052013481526103e0517f15e746bf513b8a58e4265cc1162d7fc445da5c9b1928d7cfcde2582735d4677f602083a2505b60016106a05260206106a0f35b60006106c05260206106c0f35b63ea4971ee811415610851576004356101e0526024356102e0526044356103e052601c606459905901600090520163d467ae03601c8203526101e05160048201526604000000000001546fffffffffffffffffffffffffffffffff16602482015260206106e060448334306123555a03f1506106e051905015156107bd576000610700526020610700f35b606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166102e0511215610844576102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020556001610760526020610760f35b6000610780526020610780f35b6387def0818114156108a3576004356101e0526c01000000000000000000000000606060605990590160009052600381526101e0518160200152600381604001528090502054046107a05260206107a0f35b630aece23c8114156108f4576004356101e052606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166107e05260206107e0f35b63fa14df6b811415610926576604000000000001546fffffffffffffffffffffffffffffffff16610820526020610820f35b63b8c48f8c811415610b1b576004356101e0526024356108405260443561086052600066040000000000035414151561096a576000610880526020610880f3610976565b60016604000000000003555b6101e051660400000000000255606060605990590160009052600381526101e05181602001526000816040015280905020546108a0526108a0610840518060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a600783015350506108a051606060605990590160009052600381526101e0518160200152600081604001528090502055606060605990590160009052600381526101e051816020015260008160400152809050205461094052601061094001610860518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061094051606060605990590160009052600381526101e051816020015260008160400152809050205560016109e05260206109e0f35b632b86162981141561179457365990590160009052366004823760043560208201016102c0525060483560005b6020811215610b68578181601f031a81610a600153600181019050610b48565b5050610a6051610a00526102c05160208103516020599059016000905260208183856000600287604801f1508051905090509050610a8052602059905901600090526020816020610a80600060026068f1508051905060005b6020811215610be1578181601f031a81610b600153600181019050610bc1565b5050610b60516101e05270010000000000000000000000000000000070010000000000000000000000000000000060606060599059016000905260038152610a005181602001526000816040015280905020540204610b8052610b80511515610c8b57601c602059905901600090520161272e6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610bc0526020610bc0f35b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204610be0526000610be051141515610d2e57601c60205990590160009052016127386101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610c20526020610c20f35b608c35610c40526301000000610c405160031a0262010000610c405160021a02610100610c405160011a02610c405160001a010101610c60526301000000610c605104610ca05262ffffff610c605116610cc0526003610ca051036101000a610cc05102610c805260006101e0511315610db057610c80516101e05112610db3565b60005b1561174d57780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a00518160200152600081604001528090502054046001016101205260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610d405250610d405160081a610d405160091a61010002610d4051600a1a6201000002610d4051600b1a630100000002010101610d005260006107e0610120510614158015610e7e5780610e8b565b6001660400000000000054145b905015610f0257610d0051610c6051141515610eae576000610d00511415610eb1565b60005b15610efd57601c602059905901600090520161271a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610da0526020610da0f35b6111b4565b6301000000610d005104610de05262ffffff610d005116610e00526003610de051036101000a610e005102610dc05260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610e605250610e605160041a610e605160051a61010002610e605160061a6201000002610e605160071a630100000002010101610e2052601c604459905901600090520163e0e9a17b601c8203526107e0610120510360048201526020610ec0602483600030602d5a03f150610ec0519050610ea05260806080599059016000905260038152610ea05181602001526002816040015260008160600152809050206002810154610f205250610f205160041a610f205160051a61010002610f205160061a6201000002610f205160071a630100000002010101610ee052610ee051610e20510362049d408112156110595762049d4090505b6249d40081131561106b576249d40090505b62127500610dc0518202047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156110ba577bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90505b600860076000835b80156110d9576002810490506001820191506110c2565b5080905001046000600382131515611103578160030360080260020a62ffffff841602905061111a565b6003820360080260020a8304905062ffffff811690505b6280000081161561113357610100810490506001820191505b6301000000820281179050905090509050610f6052610f6051610c6051141515611164576000610f60511415611167565b60005b156111b357601c60205990590160009052016127246101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000611040526020611040f35b5b6101e0516101e0516101e05166040000000000005455606060605990590160009052600381526101e0518160200152600081604001528090502054611060526008611060016604000000000000548060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061106051606060605990590160009052600381526101e0518160200152600081604001528090502055600166040000000000005401660400000000000055606060605990590160009052600381526101e0518160200152600081604001528090502054611100526111006001780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205404018060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061110051606060605990590160009052600381526101e051816020015260008160400152809050205560006111c05278010000000000000000000000000000000000000000000000006801000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205402046111e0526111c06111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350506001611260525b6008611260511215611515576112605160050a611280526001611280517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540407141561148757611260516004026111c0016111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a60038301535050611505565b611260516004026111c0017c01000000000000000000000000000000000000000000000000000000006112605160200260020a60606060599059016000905260038152610a00518160200152600181604001528090502054020480601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350505b60016112605101611260526113ec565b6111c051606060605990590160009052600381526101e05181602001526001816040015280905020555050608060805990590160009052600381526101e051816020015260028160400152600081606001528090502060005b600281121561159057806020026102c05101518282015560018101905061156e565b700100000000000000000000000000000000600003816020026102c051015116828201555050610c80517bffff0000000000000000000000000000000000000000000000000000056113e0526113e051610b805101610be052606060605990590160009052600381526101e051816020015260008160400152809050205461140052601061140001610be0518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061140051606060605990590160009052600381526101e0518160200152600081604001528090502055660400000000000354610be051121515611703576101e051660400000000000255610be0516604000000000003555b601c6020599059016000905201610120516101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a350610120516114a05260206114a0f35b601c602059905901600090520161276a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a35060006114c05260206114c0f35b630f5995ce8114156119a157365990590160009052366004823760043560208201016114e05260243561150052604435602082010161152052606435604052506114e05160208103516020599059016000905260208183856000600287604801f150805190509050905061156052602059905901600090526020816020611560600060026068f1508051905060005b6020811215611843578181601f031a816116400153600181019050611823565b50506116405161154052604060206114e051035114156118a457601c6020599059016000905201614e52611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a3506000611660526020611660f35b6080601c6101ac59905901600090520163bd136cb3601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff161192357fe5b6084810192506101488201518080858260c487015160006004600a8705601201f161194a57fe5b508084019350508083036020611680828434306123555a03f15061168051905090509050905061042052600161042051141561199357611540516116a05260206116a0f36119a0565b60006116c05260206116c0f35b5b63bd136cb3811415611d8c573659905901600090523660048237600435611540526024356115005260443560208201016115205260643560405250601c606459905901600090520163d467ae03601c82035260405160048201526060606059905901600090526003815260405181602001526003816040015280905020546bffffffffffffffffffffffff166024820152602061170060448334306123555a03f1506117005190501515611a9757601c6020599059016000905201614e2a611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e2a611720526020611720f35b601c6044599059016000905201633d73b705601c82035260405160048201526020611740602483600030602d5a03f15061174051905015611b1a57601c6020599059016000905201614e34611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e34611760526020611760f35b601c604459905901600090520163b041b285601c82035260405160048201526020611780602483600030602d5a03f1506117805190501515611b9e57601c6020599059016000905201614e3e611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e3e6117a05260206117a0f35b6060601c61014c59905901600090520163b7129afb601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1611c1557fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1611c3c57fe5b5080840193505080830360206117e08284600030602d5a03f1506117e05190509050905090506117c0526080608059905901600090526003815260405181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006002820154046401000000006001830154020160005b6020811215611ce4578181601f031a816118a00153600181019050611cc4565b50506118a051905061180052611800516117c0511415611d4457601c60205990590160009052016001611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a35060016118c05260206118c0f35b601c6020599059016000905201614e48611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e486118e05260206118e0f35b63318a3fee81141561205657365990590160009052366004823760043560208201016114e0526024356115005260443560208201016115205260643560405260843561190052506080601c6101ac599059016000905201630f5995ce601c8203526114e0516020601f6020830351010460200260200183600484015260208203608484015280610108840152808401935050506115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff1611e7b57fe5b60848101925061010882015180808582608487015160006004600a8705601201f1611ea257fe5b508084019350506101488201518080858260c487015160006004600a8705601201f1611eca57fe5b508084019350508083036020611920828434306123555a03f15061192051905090509050905061154052600061154051141515612010576040601c60ec599059016000905201631c0b6367601c8203526114e0516020601f6020830351010460200260200183600484015260208203604484015280608884015280840193505050611540516024820152816004015990590160009052604481604484600060046018f1611f7357fe5b604481019250608882015180808582604487015160006004600a8705601201f1611f9957fe5b5080840193505080830360206119608284600061190051602d5a03f15061196051905090509050905061194052601c602059905901600090520161194051611540517f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061194051611980526020611980f35b601c602059905901600090520161753a60007f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061753a6119a05260206119a0f35b6309dd0e81811415612076576604000000000002546119c05260206119c0f35b63023948728114156120d2577801000000000000000000000000000000000000000000000000606060605990590160009052600381526604000000000002548160200152600081604001528090502054046119e05260206119e0f35b632c181929811415612139577001000000000000000000000000000000007001000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540204611a20526020611a20f35b637ca823d58114156122af576604000000000002546101e052700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611a60526000611260525b600a61126051121561224c57608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612230578181601f031a81611b200153600181019050612210565b5050611b205190506101e05260016112605101611260526121a8565b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611b4052611b4051611a605103611b80526020611b80f35b63b7129afb81141561246a57365990590160009052366004823760043561154052602435611500526044356020820101611520525061154051611ba0526020611520510351611bc0526000611260525b611bc05161126051121561245b5761126051602002611520510151611be05260026115005107611c00526001611c0051141561234a57611be051611c2052611ba051611c4052612368565b6000611c0051141561236757611ba051611c2052611be051611c40525b5b60405990590160009052611c205160005b6020811215612399578181601f031a81611ca00153600181019050612379565b5050611ca0518152611c405160005b60208112156123c8578181601f031a81611d2001536001810190506123a8565b5050611d2051602082015260205990590160009052602081604084600060026088f15080519050611d4052602059905901600090526020816020611d40600060026068f1508051905060005b6020811215612434578181601f031a81611de00153600181019050612414565b5050611de0519050611ba052600261150051056115005260016112605101611260526122ff565b611ba051611e00526020611e00f35b633d73b70581141561255b576004356040526604000000000002546101e0526000611260525b600661126051121561254e576101e05160405114156124b6576001611e20526020611e20f35b608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612532578181601f031a81611ec00153600181019050612512565b5050611ec05190506101e0526001611260510161126052612490565b6000611ee0526020611ee0f35b631f794436811415612737576004356101e052601c606459905901600090520163d467ae03601c8203526101e0516004820152606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff1660248201526020611f2060448334306123555a03f150611f20519050151561265657601c602059905901600090520160006101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350602159905901600090526001815260006020820152602081019050602060408203526020601f6020830351604001010460200260408203f3505b601c602059905901600090520160016101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350608060805990590160009052600381526101e0518160200152600281604001526000816060015280905020607059905901600090526050815260208101905060005b60028112156126f05780830154816020028301526001810190506126d1565b70010000000000000000000000000000000060000381840154168160200283015281905090509050602060408203526020601f6020830351604001010460200260408203f3505b6313f955e18114156128ca573659905901600090523660048237600435602082010161204052602435612060525060506120805260006120a052612080516120c0526000611260525b612060516112605112156128bb576120a051806120c051038080602001599059016000905281815260208101905090508180828286612040510160006004600a8705601201f16127cc57fe5b50809050905090506120e0526020601c608c599059016000905201632b861629601c8203526120e0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161284157fe5b602481019250604882015180808582602487015160006004600a8705601201f161286757fe5b5080840193505080830360206121a08284600030602d5a03f1506121a051905090509050905061042052612080516120a051016120a052612080516120c051016120c0526001611260510161126052612780565b610420516121c05260206121c0f35b50", - "storage": { - "0x292b7a8d467a95cffd303c7edd99875892cdb3eaee87e5ca29057dc88a09ffbd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4d2fcf8ac901ad7dcf5b1c3979801430d9979c87157230ae066a0276984c6ac7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xdf951a5d1d9283b06d4f1de58542f1e1e310d8d17aada46586ddb9598bc42894": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x9c8d09d387f3ba5dd4733e24c63e4d549864a7cd57a1bdf1fdd831a2a0184815": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4ab3b783bb170e11b0932a5ce8f5f343f67058b3925da271001a75ae498bd655": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x0000000000000000000000000000000000000004": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x0000000000000000000000000000000000000002": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "559198", - "difficulty": "1814830", - "timestamp": "1577471205", - "gasLimit": "6327338", - "miner": "0x774c398d763161f55b66a646f17edda4addad2ca" - }, - "tracerConfig": { - "includePrecompiles": true - }, - "input": "0xf9026f8301307b85746a52880083124f80946cc68eb482a757c690dd151d2bd5e774ada38bdc80b9020413f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e00000000000000000000000000000000081a1a01c9e9d742c8e69daba2a026ccafdde618f2e44c96db281c2209c22f183ad03a2a049a61d267d22226896d4c065525819c238784c439dc2afa7d17fce76595730d1", - "result": [ - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "gas": "0x124f80", - "input": "0x13f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1c6ff", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 20, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1a", - "input": "0x04000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x18", - "output": "0x04000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67" - }, - "subtraces": 0, - "traceAddress": [ - 0 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x15", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x15", - "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020" - }, - "subtraces": 0, - "traceAddress": [ - 1 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1e", - "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1b", - "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 2 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x114243", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 2, - "traceAddress": [ - 3 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x98", - "input": "0x04000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x60", - "output": "0xb099ea4048830027371dc31039920ae4fd19a641a7cbe57c198edd19d60f158a" - }, - "subtraces": 0, - "traceAddress": [ - 3, - 0 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x68", - "input": "0xb099ea4048830027371dc31039920ae4fd19a641a7cbe57c198edd19d60f158a", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x48", - "output": "0x5b53875b0f1381589859adcf938980f4a8fb0af4c88450070000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 3, - 1 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1a", - "input": "0x040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae7", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x18", - "output": "0x040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae7" - }, - "subtraces": 0, - "traceAddress": [ - 4 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x15", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x15", - "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020" - }, - "subtraces": 0, - "traceAddress": [ - 5 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1e", - "input": "0x0000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 6 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x110d3b", - "input": "0x2b86162900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 2, - "traceAddress": [ - 7 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x98", - "input": "0x040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae7", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x60", - "output": "0xa0c6939b58a99b0d940f4435ab7db7d54d6b7786e68e00d9ff3890d69f95565d" - }, - "subtraces": 0, - "traceAddress": [ - 7, - 0 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x68", - "input": "0xa0c6939b58a99b0d940f4435ab7db7d54d6b7786e68e00d9ff3890d69f95565d", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x48", - "output": "0xabbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 7, - 1 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1a", - "input": "0x04000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc303", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x18", - "output": "0x04000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc303" - }, - "subtraces": 0, - "traceAddress": [ - 8 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x15", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x15", - "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020" - }, - "subtraces": 0, - "traceAddress": [ - 9 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1e", - "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1b", - "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 10 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x10d833", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 2, - "traceAddress": [ - 11 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x98", - "input": "0x04000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc303", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x60", - "output": "0x6defff59ba277fa4511f8675ca98ca7d9c237c7433684490cf1ce09a9249e32f" - }, - "subtraces": 0, - "traceAddress": [ - 11, - 0 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x68", - "input": "0x6defff59ba277fa4511f8675ca98ca7d9c237c7433684490cf1ce09a9249e32f", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x48", - "output": "0xe93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 11, - 1 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1a", - "input": "0x04000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x18", - "output": "0x04000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de" - }, - "subtraces": 0, - "traceAddress": [ - 12 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x15", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x15", - "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020" - }, - "subtraces": 0, - "traceAddress": [ - 13 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1e", - "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1b", - "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 14 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x10a328", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 2, - "traceAddress": [ - 15 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x98", - "input": "0x04000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x60", - "output": "0x996652142ffecd9cc272f376ca0e8228871a903772996289f847a6dbe2ce2698" - }, - "subtraces": 0, - "traceAddress": [ - 15, - 0 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x68", - "input": "0x996652142ffecd9cc272f376ca0e8228871a903772996289f847a6dbe2ce2698", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x48", - "output": "0xf2e372a0b5b837116eee8f968840393d85975a15313468070000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 15, - 1 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1a", - "input": "0x04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e0", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x18", - "output": "0x04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e0" - }, - "subtraces": 0, - "traceAddress": [ - 16 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x15", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x15", - "output": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020" - }, - "subtraces": 0, - "traceAddress": [ - 17 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x1e", - "input": "0x000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000004", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1b", - "output": "0x000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 18 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x106e1d", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 2, - "traceAddress": [ - 19 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x98", - "input": "0x04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e0", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x60", - "output": "0xe57cf1c1d6132b9cfd9e90f54f907c038b47941b2a7f3800783af26e852ec116" - }, - "subtraces": 0, - "traceAddress": [ - 19, - 0 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x68", - "input": "0xe57cf1c1d6132b9cfd9e90f54f907c038b47941b2a7f3800783af26e852ec116", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x0000000000000000000000000000000000000002", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x48", - "output": "0x8d5b6fafc6216500f9ef1ab16b30a59df9122d7de0f4910a0000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 19, - 1 - ], - "type": "call" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json deleted file mode 100644 index 6c4ce18063..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_create_oog_outer_throw.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "context": { - "difficulty": "3451177886", - "gasLimit": "4709286", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2290744", - "timestamp": "1513616439" - }, - "genesis": { - "alloc": { - "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a": { - "balance": "0x0", - "code": "0x606060405263ffffffff60e060020a6000350416633b91f50681146100505780635bb47808146100715780635f51fca01461008c578063bc7647a9146100ad578063f1bd0d7a146100c8575b610000565b346100005761006f600160a060020a03600435811690602435166100e9565b005b346100005761006f600160a060020a0360043516610152565b005b346100005761006f600160a060020a036004358116906024351661019c565b005b346100005761006f600160a060020a03600435166101fa565b005b346100005761006f600160a060020a0360043581169060243516610db8565b005b600160a060020a038083166000908152602081905260408120549091908116903316811461011657610000565b839150600160a060020a038316151561012d573392505b6101378284610e2e565b6101418284610db8565b61014a826101fa565b5b5b50505050565b600154600160a060020a03908116903316811461016e57610000565b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0384161790555b5b5050565b600254600160a060020a0390811690331681146101b857610000565b600160a060020a038381166000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790555b5b505050565b6040805160e260020a631a481fc102815260016024820181905260026044830152606482015262093a8060848201819052600060a4830181905260c06004840152601e60c48401527f736574456e7469747953746174757328616464726573732c75696e743829000060e484015292519091600160a060020a038516916369207f049161010480820192879290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526000602482018190526001604483015260606004830152602360648301527f626567696e506f6c6c28616464726573732c75696e7436342c626f6f6c2c626f60848301527f6f6c29000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f61646453746f636b28616464726573732c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f697373756553746f636b2875696e74382c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602160648301527f6772616e7453746f636b2875696e74382c75696e743235362c61646472657373608483015260f860020a60290260a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f115610000575050604080517f010555b8000000000000000000000000000000000000000000000000000000008152600160a060020a03338116602483015260006044830181905260606004840152603c60648401527f6772616e7456657374656453746f636b2875696e74382c75696e743235362c6160848401527f6464726573732c75696e7436342c75696e7436342c75696e743634290000000060a48401529251908716935063010555b89260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601260c48201527f626567696e53616c65286164647265737329000000000000000000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601a60648301527f7472616e7366657253616c6546756e64732875696e743235362900000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152602d60c48201527f7365744163636f756e74696e6753657474696e67732875696e743235362c756960e48201527f6e7436342c75696e7432353629000000000000000000000000000000000000006101048201529051600160a060020a03861692506369207f04916101248082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152603460648301527f637265617465526563757272696e6752657761726428616464726573732c756960848301527f6e743235362c75696e7436342c737472696e672900000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601b60648301527f72656d6f7665526563757272696e675265776172642875696e7429000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602360648301527f697373756552657761726428616464726573732c75696e743235362c7374726960848301527f6e6729000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f61737369676e53746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f72656d6f766553746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260026024808301919091526003604483015260006064830181905267ffffffffffffffff8616608484015260ff871660a484015260c0600484015260c48301919091527f7365744164647265737342796c617728737472696e672c616464726573732c6260e48301527f6f6f6c29000000000000000000000000000000000000000000000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152602160c48301527f73657453746174757342796c617728737472696e672c75696e74382c626f6f6c60e483015260f860020a6029026101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152603860c48301527f736574566f74696e6742796c617728737472696e672c75696e743235362c756960e48301527f6e743235362c626f6f6c2c75696e7436342c75696e74382900000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f115610000575050505b505050565b604080517f225553a4000000000000000000000000000000000000000000000000000000008152600160a060020a0383811660048301526002602483015291519184169163225553a49160448082019260009290919082900301818387803b156100005760325a03f115610000575050505b5050565b600082604051611fd280610f488339600160a060020a03909216910190815260405190819003602001906000f0801561000057905082600160a060020a03166308b027418260016040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b156100005760325a03f115610000575050604080517fa14e3ee300000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152600160a060020a0386811660448401529251928716935063a14e3ee39260648084019382900301818387803b156100005760325a03f115610000575050505b5050505600606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029a165627a7a723058200e78a5f7e0f91739035d0fbf5eca02f79377210b722f63431f29a22e2880b3bd0029", - "nonce": "789", - "storage": { - "0xfe9ec0542a1c009be8b1f3acf43af97100ffff42eb736850fb038fa1151ad4d9": "0x000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8" - } - }, - "0x5cb4a6b902fcb21588c86c3517e797b07cdaadb9": { - "balance": "0x0", - "code": "0x", - "nonce": "0", - "storage": {} - }, - "0xe4a13bc304682a903e9472f469c33801dd18d9e8": { - "balance": "0x33c763c929f62c4f", - "code": "0x", - "nonce": "14", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3451177886", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4713874", - "hash": "0x5d52a672417cd1269bf4f7095e25dcbf837747bba908cd5ef809dc1bd06144b5", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x01a12845ed546b94a038a7a03e8df8d7952024ed41ccb3db7a7ade4abc290ce1", - "nonce": "0x28c446f1cb9748c1", - "number": "2290743", - "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708", - "timestamp": "1513616414", - "totalDifficulty": "7146523769022564" - }, - "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281", - "result": [ - { - "action": { - "callType": "call", - "from": "0xe4a13bc304682a903e9472f469c33801dd18d9e8", - "gas": "0x493e0", - "input": "0x3b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8", - "to": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a", - "value": "0x0" - }, - "blockNumber": 2290744, - "error": "invalid jump destination", - "result": {}, - "subtraces": 1, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "from": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a", - "gas": "0x39ff0", - "init": "0x606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182", - "value": "0x0" - }, - "blockNumber": 0, - "error": "contract creation code storage out of gas", - "result": {}, - "subtraces": 0, - "traceAddress": [0], - "type": "create" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json deleted file mode 100644 index 4de08f2cca..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_instafail.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "genesis": { - "difficulty": "117067574", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712380", - "hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486", - "miner": "0x0c062b329265c965deef1eede55183b3acb8f611", - "mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d", - "nonce": "0x2b469722b8e28c45", - "number": "24973", - "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369", - "timestamp": "1479891145", - "totalDifficulty": "1892250259406", - "alloc": { - "0x6c06b16512b332e6cd8293a2974872674716ce18": { - "balance": "0x0", - "nonce": "1", - "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056", - "storage": {} - }, - "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": { - "balance": "0x229ebbb36c3e0f20", - "nonce": "3", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 3, - "homesteadBlock": 0, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "byzantiumBlock": 1700000, - "constantinopleBlock": 4230000, - "petersburgBlock": 4939394, - "istanbulBlock": 6485846, - "muirGlacierBlock": 7117117, - "ethash": {} - } - }, - "context": { - "number": "24974", - "difficulty": "117067574", - "timestamp": "1479891162", - "gasLimit": "4712388", - "miner": "0xc822ef32e6d26e170b70cf761e204c1806265914" - }, - "input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745", - "result": [ - { - "action": { - "callType": "call", - "from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", - "gas": "0x1f97e", - "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000", - "to": "0x6c06b16512b332e6cd8293a2974872674716ce18", - "value": "0x0" - }, - "blockNumber": 24974, - "result": { - "gasUsed": "0x72de", - "output": "0x" - }, - "subtraces": 0, - "traceAddress": [], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json deleted file mode 100644 index 70442fdb9a..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_precompiled_wrong_gas.json +++ /dev/null @@ -1,219 +0,0 @@ -{ - "genesis": { - "number": "559197", - "hash": "0x0742a2bfab0452e2c634f3685b7e49ceb065c7000609b2b73f086e01fd1dfb58", - "nonce": "0x3060ad521440e1c2", - "mixHash": "0x59e7d4ae6cc3c38d23dac3f869b21984c7ba8f38070f4116a4941d9c403b6299", - "stateRoot": "0x68418fb5cf4afa9b807dc079e8cdde0e148ac2c8afb378e675465b5bed1fbd02", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "difficulty": "1813945", - "totalDifficulty": "469107641961", - "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", - "gasLimit": "6321166", - "timestamp": "1577471202", - "alloc": { - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0xc5e6fdae52af83f7e28", - "nonce": "77947", - "code": "0x", - "storage": {} - }, - "0x774c398d763161f55b66a646f17edda4addad2ca": { - "balance": "0xf09ef316eff819ee488", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc": { - "balance": "0x0", - "nonce": "1", - "code": "0x60006121df537c01000000000000000000000000000000000000000000000000000000006000350463b041b2858114156100d257600435604052780100000000000000000000000000000000000000000000000060606060599059016000905260038152604051816020015260008160400152809050205404606052606051151561008f57600060a052602060a0f35b604051601c604459905901600090520163e0e9a17b601c82035260605160048201526020610100602483600030602d5a03f1506101005190501460c052602060c0f35b632cce81aa81141561019957600435610120526001610120511280156100f85780610143565b78010000000000000000000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540461012051135b905015610157576000610180526020610180f35b601c604459905901600090520163e0e9a17b601c82035261012051600482015260206101c0602483600030602d5a03f1506101c05190506101a05260206101a0f35b63e0e9a17b8114156102e957600435610120526604000000000002546101e0526007610200525b610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540413156102da575b6102005160050a610120517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e051816020015260008160400152809050205404031215610269576000610200511361026c565b60005b1561028157600161020051036102005261020b565b7c01000000000000000000000000000000000000000000000000000000006102005160200260020a606060605990590160009052600381526101e05181602001526001816040015280905020540204546101e0526101c0565b6101e051610280526020610280f35b63cef887b08114156103e757365990590160009052366004823760043560208201016102c0526024356102e052506060601c61014c5990590160009052016390fa337d601c8203526102c0516020601f602083035101046020026020018360048401526020820360648401528060c8840152808401935050506102e051602482015233604482015281600401599059016000905260648160648460006004601cf161039057fe5b60648101925060c882015180808582606487015160006004600a8705601201f16103b657fe5b5080840193505080830360206103a08284600030602d5a03f1506103a0519050905090509050610300526020610300f35b6390fa337d81141561065f57365990590160009052366004823760043560208201016102c0526024356102e0526044356103e052505a610400526020601c608c599059016000905201632b861629601c8203526102c0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161048a57fe5b602481019250604882015180808582602487015160006004600a8705601201f16104b057fe5b5080840193505080830360206104408284600030602d5a03f15061044051905090509050905061042052610420511561065e576102c05160208103516020599059016000905260208183856000600287604801f150805190509050905061046052602059905901600090526020816020610460600060026068f1508051905060005b6020811215610552578181601f031a816105400153600181019050610532565b5050610540516101e0526102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020555a61058052700100000000000000000000000000000000660400000000000154046105a0526104006105a0516103ff02056105c0526104006105a05161040102056105e0526105c0513a12156105f6576105c05161060052610615565b6105e0513a131561060e576105e05161060052610614565b3a610600525b5b6105805161040051036106005160020202610620526106205170010000000000000000000000000000000061060051021766040000000000015561042051610640526020610640f35b5b63d467ae0381141561073257600435604052602435610660526106605134121515610725576000341315610718576c01000000000000000000000000606060605990590160009052600381526040518160200152600381604001528090502054046103e0526000600060006000346103e051611388f115156106dd57fe5b601c60405990590160009052013481526103e0517f15e746bf513b8a58e4265cc1162d7fc445da5c9b1928d7cfcde2582735d4677f602083a2505b60016106a05260206106a0f35b60006106c05260206106c0f35b63ea4971ee811415610851576004356101e0526024356102e0526044356103e052601c606459905901600090520163d467ae03601c8203526101e05160048201526604000000000001546fffffffffffffffffffffffffffffffff16602482015260206106e060448334306123555a03f1506106e051905015156107bd576000610700526020610700f35b606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166102e0511215610844576102e0516c010000000000000000000000006103e0510217606060605990590160009052600381526101e05181602001526003816040015280905020556001610760526020610760f35b6000610780526020610780f35b6387def0818114156108a3576004356101e0526c01000000000000000000000000606060605990590160009052600381526101e0518160200152600381604001528090502054046107a05260206107a0f35b630aece23c8114156108f4576004356101e052606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff166107e05260206107e0f35b63fa14df6b811415610926576604000000000001546fffffffffffffffffffffffffffffffff16610820526020610820f35b63b8c48f8c811415610b1b576004356101e0526024356108405260443561086052600066040000000000035414151561096a576000610880526020610880f3610976565b60016604000000000003555b6101e051660400000000000255606060605990590160009052600381526101e05181602001526000816040015280905020546108a0526108a0610840518060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a600783015350506108a051606060605990590160009052600381526101e0518160200152600081604001528090502055606060605990590160009052600381526101e051816020015260008160400152809050205461094052601061094001610860518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061094051606060605990590160009052600381526101e051816020015260008160400152809050205560016109e05260206109e0f35b632b86162981141561179457365990590160009052366004823760043560208201016102c0525060483560005b6020811215610b68578181601f031a81610a600153600181019050610b48565b5050610a6051610a00526102c05160208103516020599059016000905260208183856000600287604801f1508051905090509050610a8052602059905901600090526020816020610a80600060026068f1508051905060005b6020811215610be1578181601f031a81610b600153600181019050610bc1565b5050610b60516101e05270010000000000000000000000000000000070010000000000000000000000000000000060606060599059016000905260038152610a005181602001526000816040015280905020540204610b8052610b80511515610c8b57601c602059905901600090520161272e6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610bc0526020610bc0f35b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204610be0526000610be051141515610d2e57601c60205990590160009052016127386101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610c20526020610c20f35b608c35610c40526301000000610c405160031a0262010000610c405160021a02610100610c405160011a02610c405160001a010101610c60526301000000610c605104610ca05262ffffff610c605116610cc0526003610ca051036101000a610cc05102610c805260006101e0511315610db057610c80516101e05112610db3565b60005b1561174d57780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a00518160200152600081604001528090502054046001016101205260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610d405250610d405160081a610d405160091a61010002610d4051600a1a6201000002610d4051600b1a630100000002010101610d005260006107e0610120510614158015610e7e5780610e8b565b6001660400000000000054145b905015610f0257610d0051610c6051141515610eae576000610d00511415610eb1565b60005b15610efd57601c602059905901600090520161271a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000610da0526020610da0f35b6111b4565b6301000000610d005104610de05262ffffff610d005116610e00526003610de051036101000a610e005102610dc05260806080599059016000905260038152610a005181602001526002816040015260008160600152809050206002810154610e605250610e605160041a610e605160051a61010002610e605160061a6201000002610e605160071a630100000002010101610e2052601c604459905901600090520163e0e9a17b601c8203526107e0610120510360048201526020610ec0602483600030602d5a03f150610ec0519050610ea05260806080599059016000905260038152610ea05181602001526002816040015260008160600152809050206002810154610f205250610f205160041a610f205160051a61010002610f205160061a6201000002610f205160071a630100000002010101610ee052610ee051610e20510362049d408112156110595762049d4090505b6249d40081131561106b576249d40090505b62127500610dc0518202047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8113156110ba577bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90505b600860076000835b80156110d9576002810490506001820191506110c2565b5080905001046000600382131515611103578160030360080260020a62ffffff841602905061111a565b6003820360080260020a8304905062ffffff811690505b6280000081161561113357610100810490506001820191505b6301000000820281179050905090509050610f6052610f6051610c6051141515611164576000610f60511415611167565b60005b156111b357601c60205990590160009052016127246101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a3506000611040526020611040f35b5b6101e0516101e0516101e05166040000000000005455606060605990590160009052600381526101e0518160200152600081604001528090502054611060526008611060016604000000000000548060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061106051606060605990590160009052600381526101e0518160200152600081604001528090502055600166040000000000005401660400000000000055606060605990590160009052600381526101e0518160200152600081604001528090502054611100526111006001780100000000000000000000000000000000000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205404018060181a82538060191a600183015380601a1a600283015380601b1a600383015380601c1a600483015380601d1a600583015380601e1a600683015380601f1a6007830153505061110051606060605990590160009052600381526101e051816020015260008160400152809050205560006111c05278010000000000000000000000000000000000000000000000006801000000000000000060606060599059016000905260038152610a0051816020015260008160400152809050205402046111e0526111c06111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350506001611260525b6008611260511215611515576112605160050a611280526001611280517801000000000000000000000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540407141561148757611260516004026111c0016111e05180601c1a825380601d1a600183015380601e1a600283015380601f1a60038301535050611505565b611260516004026111c0017c01000000000000000000000000000000000000000000000000000000006112605160200260020a60606060599059016000905260038152610a00518160200152600181604001528090502054020480601c1a825380601d1a600183015380601e1a600283015380601f1a600383015350505b60016112605101611260526113ec565b6111c051606060605990590160009052600381526101e05181602001526001816040015280905020555050608060805990590160009052600381526101e051816020015260028160400152600081606001528090502060005b600281121561159057806020026102c05101518282015560018101905061156e565b700100000000000000000000000000000000600003816020026102c051015116828201555050610c80517bffff0000000000000000000000000000000000000000000000000000056113e0526113e051610b805101610be052606060605990590160009052600381526101e051816020015260008160400152809050205461140052601061140001610be0518060101a82538060111a60018301538060121a60028301538060131a60038301538060141a60048301538060151a60058301538060161a60068301538060171a60078301538060181a60088301538060191a600983015380601a1a600a83015380601b1a600b83015380601c1a600c83015380601d1a600d83015380601e1a600e83015380601f1a600f830153505061140051606060605990590160009052600381526101e0518160200152600081604001528090502055660400000000000354610be051121515611703576101e051660400000000000255610be0516604000000000003555b601c6020599059016000905201610120516101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a350610120516114a05260206114a0f35b601c602059905901600090520161276a6101e0517f055e4f8dd3a534789b3feb8e0681afa2aee8713fdd6472f25b2c30dc7bf4e0f4600084a35060006114c05260206114c0f35b630f5995ce8114156119a157365990590160009052366004823760043560208201016114e05260243561150052604435602082010161152052606435604052506114e05160208103516020599059016000905260208183856000600287604801f150805190509050905061156052602059905901600090526020816020611560600060026068f1508051905060005b6020811215611843578181601f031a816116400153600181019050611823565b50506116405161154052604060206114e051035114156118a457601c6020599059016000905201614e52611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a3506000611660526020611660f35b6080601c6101ac59905901600090520163bd136cb3601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff161192357fe5b6084810192506101488201518080858260c487015160006004600a8705601201f161194a57fe5b508084019350508083036020611680828434306123555a03f15061168051905090509050905061042052600161042051141561199357611540516116a05260206116a0f36119a0565b60006116c05260206116c0f35b5b63bd136cb3811415611d8c573659905901600090523660048237600435611540526024356115005260443560208201016115205260643560405250601c606459905901600090520163d467ae03601c82035260405160048201526060606059905901600090526003815260405181602001526003816040015280905020546bffffffffffffffffffffffff166024820152602061170060448334306123555a03f1506117005190501515611a9757601c6020599059016000905201614e2a611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e2a611720526020611720f35b601c6044599059016000905201633d73b705601c82035260405160048201526020611740602483600030602d5a03f15061174051905015611b1a57601c6020599059016000905201614e34611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e34611760526020611760f35b601c604459905901600090520163b041b285601c82035260405160048201526020611780602483600030602d5a03f1506117805190501515611b9e57601c6020599059016000905201614e3e611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e3e6117a05260206117a0f35b6060601c61014c59905901600090520163b7129afb601c8203526115405160048201526115005160248201526115205160208103516020026020018360448401526020820360a4840152806101088401528084019350505081600401599059016000905260648160648460006004601cf1611c1557fe5b6064810192506101088201518080858260a487015160006004600a8705601201f1611c3c57fe5b5080840193505080830360206117e08284600030602d5a03f1506117e05190509050905090506117c0526080608059905901600090526003815260405181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006002820154046401000000006001830154020160005b6020811215611ce4578181601f031a816118a00153600181019050611cc4565b50506118a051905061180052611800516117c0511415611d4457601c60205990590160009052016001611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a35060016118c05260206118c0f35b601c6020599059016000905201614e48611540517fd008620948a1ed10f4fed82dc43cf79acad36dc6b7c2c924e27c9813193b83ad600084a350614e486118e05260206118e0f35b63318a3fee81141561205657365990590160009052366004823760043560208201016114e0526024356115005260443560208201016115205260643560405260843561190052506080601c6101ac599059016000905201630f5995ce601c8203526114e0516020601f6020830351010460200260200183600484015260208203608484015280610108840152808401935050506115005160248201526115205160208103516020026020018360448401526020820360c48401528061014884015280840193505050604051606482015281600401599059016000905260848160848460006004601ff1611e7b57fe5b60848101925061010882015180808582608487015160006004600a8705601201f1611ea257fe5b508084019350506101488201518080858260c487015160006004600a8705601201f1611eca57fe5b508084019350508083036020611920828434306123555a03f15061192051905090509050905061154052600061154051141515612010576040601c60ec599059016000905201631c0b6367601c8203526114e0516020601f6020830351010460200260200183600484015260208203604484015280608884015280840193505050611540516024820152816004015990590160009052604481604484600060046018f1611f7357fe5b604481019250608882015180808582604487015160006004600a8705601201f1611f9957fe5b5080840193505080830360206119608284600061190051602d5a03f15061196051905090509050905061194052601c602059905901600090520161194051611540517f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061194051611980526020611980f35b601c602059905901600090520161753a60007f2d0d11d0f27e21fab56a8712078721096066b7faaa8540a3ea566e70b97de2d4600084a35061753a6119a05260206119a0f35b6309dd0e81811415612076576604000000000002546119c05260206119c0f35b63023948728114156120d2577801000000000000000000000000000000000000000000000000606060605990590160009052600381526604000000000002548160200152600081604001528090502054046119e05260206119e0f35b632c181929811415612139577001000000000000000000000000000000007001000000000000000000000000000000006060606059905901600090526003815266040000000000025481602001526000816040015280905020540204611a20526020611a20f35b637ca823d58114156122af576604000000000002546101e052700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611a60526000611260525b600a61126051121561224c57608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612230578181601f031a81611b200153600181019050612210565b5050611b205190506101e05260016112605101611260526121a8565b700100000000000000000000000000000000700100000000000000000000000000000000606060605990590160009052600381526101e05181602001526000816040015280905020540204611b4052611b4051611a605103611b80526020611b80f35b63b7129afb81141561246a57365990590160009052366004823760043561154052602435611500526044356020820101611520525061154051611ba0526020611520510351611bc0526000611260525b611bc05161126051121561245b5761126051602002611520510151611be05260026115005107611c00526001611c0051141561234a57611be051611c2052611ba051611c4052612368565b6000611c0051141561236757611ba051611c2052611be051611c40525b5b60405990590160009052611c205160005b6020811215612399578181601f031a81611ca00153600181019050612379565b5050611ca0518152611c405160005b60208112156123c8578181601f031a81611d2001536001810190506123a8565b5050611d2051602082015260205990590160009052602081604084600060026088f15080519050611d4052602059905901600090526020816020611d40600060026068f1508051905060005b6020811215612434578181601f031a81611de00153600181019050612414565b5050611de0519050611ba052600261150051056115005260016112605101611260526122ff565b611ba051611e00526020611e00f35b633d73b70581141561255b576004356040526604000000000002546101e0526000611260525b600661126051121561254e576101e05160405114156124b6576001611e20526020611e20f35b608060805990590160009052600381526101e05181602001526002816040015260008160600152809050207c01000000000000000000000000000000000000000000000000000000006001820154046401000000008254020160005b6020811215612532578181601f031a81611ec00153600181019050612512565b5050611ec05190506101e0526001611260510161126052612490565b6000611ee0526020611ee0f35b631f794436811415612737576004356101e052601c606459905901600090520163d467ae03601c8203526101e0516004820152606060605990590160009052600381526101e05181602001526003816040015280905020546bffffffffffffffffffffffff1660248201526020611f2060448334306123555a03f150611f20519050151561265657601c602059905901600090520160006101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350602159905901600090526001815260006020820152602081019050602060408203526020601f6020830351604001010460200260408203f3505b601c602059905901600090520160016101e0517f60ab231f060fa320acea170017564b7ee77f477e6465a8c964380cffb270aaf4600084a350608060805990590160009052600381526101e0518160200152600281604001526000816060015280905020607059905901600090526050815260208101905060005b60028112156126f05780830154816020028301526001810190506126d1565b70010000000000000000000000000000000060000381840154168160200283015281905090509050602060408203526020601f6020830351604001010460200260408203f3505b6313f955e18114156128ca573659905901600090523660048237600435602082010161204052602435612060525060506120805260006120a052612080516120c0526000611260525b612060516112605112156128bb576120a051806120c051038080602001599059016000905281815260208101905090508180828286612040510160006004600a8705601201f16127cc57fe5b50809050905090506120e0526020601c608c599059016000905201632b861629601c8203526120e0516020601f6020830351010460200260200183600484015260208203602484015280604884015280840193505050816004015990590160009052602481602484600060046015f161284157fe5b602481019250604882015180808582602487015160006004600a8705601201f161286757fe5b5080840193505080830360206121a08284600030602d5a03f1506121a051905090509050905061042052612080516120a051016120a052612080516120c051016120c0526001611260510161126052612780565b610420516121c05260206121c0f35b50", - "storage": { - "0x292b7a8d467a95cffd303c7edd99875892cdb3eaee87e5ca29057dc88a09ffbd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4d2fcf8ac901ad7dcf5b1c3979801430d9979c87157230ae066a0276984c6ac7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xdf951a5d1d9283b06d4f1de58542f1e1e310d8d17aada46586ddb9598bc42894": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x9c8d09d387f3ba5dd4733e24c63e4d549864a7cd57a1bdf1fdd831a2a0184815": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4ab3b783bb170e11b0932a5ce8f5f343f67058b3925da271001a75ae498bd655": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x0000000000000000000000000000000000000004": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x0000000000000000000000000000000000000002": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "559198", - "difficulty": "1814830", - "timestamp": "1577471205", - "gasLimit": "6327338", - "miner": "0x774c398d763161f55b66a646f17edda4addad2ca" - }, - "input": "0xf9026f8301307b85746a52880083124f80946cc68eb482a757c690dd151d2bd5e774ada38bdc80b9020413f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e00000000000000000000000000000000081a1a01c9e9d742c8e69daba2a026ccafdde618f2e44c96db281c2209c22f183ad03a2a049a61d267d22226896d4c065525819c238784c439dc2afa7d17fce76595730d1", - "result": [ - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "gas": "0x124f80", - "input": "0x13f955e100000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000019004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a67040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae704000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30304000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de04000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x1c6ff", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 5, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x114243", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000afbe013b4a83b2f91f3d9b6627cf382394c4914fd2b7510700000000000000008621196eb526a0e02430b6dd5c72fd368e768977f3a8364861e5a471a8ae61a1028f745609c40b185f537a6700000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 0 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x110d3b", - "input": "0x2b86162900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000050040000005b53875b0f1381589859adcf938980f4a8fb0af4c8845007000000000000000075289d1c48c8f71deee521a76c8d92948cbe14343991998dfaea6b08596d97dcc891745609c40b18ae825ae700000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 1 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x10d833", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000abbacd8711f647ab97c6c9b9658eb9bef081e2cedb630f010000000000000000549bcab22422baef6c34af382b227e4b1a27bec3312e04dbb62fc315203c67f30f9d745609c40b180fdfc30300000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 2 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x10a328", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000e93433dde5128942e47e8722d37ec4dcc1c8a78cf9c4a4030000000000000000bf92c09e8e37b2c8ffbb4b9cadfccc563e474c4feae6997f52d56236fedafce20a9f745609c40b1840cc27de00000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 3 - ], - "type": "call" - }, - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "gas": "0x106e1d", - "input": "0x2b8616290000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000005004000000f2e372a0b5b837116eee8f968840393d85975a1531346807000000000000000076bc91399edda1de98976ee0774e2ad3b21dd38ad9f5f34d2c816a832747fe7f4c9e745609c40b18e290e9e000000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x6cc68eb482a757c690dd151d2bd5e774ada38bdc", - "value": "0x0" - }, - "result": { - "address": "0x0000000000000000000000000000000000000000", - "gasUsed": "0x27c3", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "subtraces": 0, - "traceAddress": [ - 4 - ], - "type": "call" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json deleted file mode 100644 index bc94708718..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/inner_throw_outer_revert.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "context": { - "difficulty": "3956606365", - "gasLimit": "5413248", - "miner": "0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d", - "number": "2295104", - "timestamp": "1513681256" - }, - "genesis": { - "alloc": { - "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76": { - "balance": "0x0", - "code": "0x60606040526004361061015e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680625b4487146101a257806311df9995146101cb578063278ecde11461022057806330adce0e146102435780633197cbb61461026c5780634bb278f3146102955780636103d70b146102aa57806363a599a4146102bf5780636a2d1cb8146102d457806375f12b21146102fd57806378e979251461032a578063801db9cc1461035357806386d1a69f1461037c5780638da5cb5b146103915780638ef26a71146103e65780639890220b1461040f5780639b39caef14610424578063b85dfb801461044d578063be9a6555146104a1578063ccb07cef146104b6578063d06c91e4146104e3578063d669e1d414610538578063df40503c14610561578063e2982c2114610576578063f02e030d146105c3578063f2fde38b146105d8578063f3283fba14610611575b600060149054906101000a900460ff1615151561017a57600080fd5b60075442108061018b575060085442115b15151561019757600080fd5b6101a03361064a565b005b34156101ad57600080fd5b6101b5610925565b6040518082815260200191505060405180910390f35b34156101d657600080fd5b6101de61092b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022b57600080fd5b6102416004808035906020019091905050610951565b005b341561024e57600080fd5b610256610c48565b6040518082815260200191505060405180910390f35b341561027757600080fd5b61027f610c4e565b6040518082815260200191505060405180910390f35b34156102a057600080fd5b6102a8610c54565b005b34156102b557600080fd5b6102bd610f3e565b005b34156102ca57600080fd5b6102d261105d565b005b34156102df57600080fd5b6102e76110d5565b6040518082815260200191505060405180910390f35b341561030857600080fd5b6103106110e1565b604051808215151515815260200191505060405180910390f35b341561033557600080fd5b61033d6110f4565b6040518082815260200191505060405180910390f35b341561035e57600080fd5b6103666110fa565b6040518082815260200191505060405180910390f35b341561038757600080fd5b61038f611104565b005b341561039c57600080fd5b6103a4611196565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f157600080fd5b6103f96111bb565b6040518082815260200191505060405180910390f35b341561041a57600080fd5b6104226111c1565b005b341561042f57600080fd5b610437611296565b6040518082815260200191505060405180910390f35b341561045857600080fd5b610484600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061129c565b604051808381526020018281526020019250505060405180910390f35b34156104ac57600080fd5b6104b46112c0565b005b34156104c157600080fd5b6104c9611341565b604051808215151515815260200191505060405180910390f35b34156104ee57600080fd5b6104f6611354565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561054357600080fd5b61054b61137a565b6040518082815260200191505060405180910390f35b341561056c57600080fd5b610574611385565b005b341561058157600080fd5b6105ad600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506116c3565b6040518082815260200191505060405180910390f35b34156105ce57600080fd5b6105d66116db565b005b34156105e357600080fd5b61060f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611829565b005b341561061c57600080fd5b610648600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118fe565b005b600080670de0b6b3a7640000341015151561066457600080fd5b61069b610696670de0b6b3a7640000610688610258346119d990919063ffffffff16565b611a0c90919063ffffffff16565b611a27565b9150660221b262dd80006106ba60065484611a7e90919063ffffffff16565b111515156106c757600080fd5b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156107d557600080fd5b6102c65a03f115156107e657600080fd5b5050506040518051905050610808828260010154611a7e90919063ffffffff16565b8160010181905550610827348260000154611a7e90919063ffffffff16565b816000018190555061084434600554611a7e90919063ffffffff16565b60058190555061085f82600654611a7e90919063ffffffff16565b6006819055503373ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c836040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e8583600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060085442108061096b5750651b48eb57e00060065410155b15151561097757600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154821415156109c757600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515610ac857600080fd5b6102c65a03f11515610ad957600080fd5b5050506040518051905050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68836000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610b7d57600080fd5b6102c65a03f11515610b8e57600080fd5b505050604051805190501515610ba357600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506000811115610c4457610c433382611a9c565b5b5050565b60055481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb157600080fd5b600854421015610cd357660221b262dd8000600654141515610cd257600080fd5b5b651b48eb57e000600654108015610cf057506213c6806008540142105b151515610cfc57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610d7557600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610e3a57600080fd5b6102c65a03f11515610e4b57600080fd5b5050506040518051905090506000811115610f2057600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610ef957600080fd5b6102c65a03f11515610f0a57600080fd5b505050604051805190501515610f1f57600080fd5b5b6001600960006101000a81548160ff02191690831515021790555050565b600080339150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114151515610f9657600080fd5b803073ffffffffffffffffffffffffffffffffffffffff163110151515610fbc57600080fd5b610fd181600254611b5090919063ffffffff16565b6002819055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561105957fe5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110b857600080fd5b6001600060146101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b600060149054906101000a900460ff1681565b60075481565b651b48eb57e00081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561115f57600080fd5b600060149054906101000a900460ff16151561117a57600080fd5b60008060146101000a81548160ff021916908315150217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561121c57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561129457600080fd5b565b61025881565b600a6020528060005260406000206000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561131b57600080fd5b600060075414151561132c57600080fd5b4260078190555062278d004201600881905550565b600960009054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b660221b262dd800081565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113e557600080fd5b600654660221b262dd800003925061142b670de0b6b3a764000061141c610258670de0b6b3a76400006119d990919063ffffffff16565b81151561142557fe5b04611a27565b915081831115151561143c57600080fd5b600a60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561158c57600080fd5b6102c65a03f1151561159d57600080fd5b50505060405180519050506115bf838260010154611a7e90919063ffffffff16565b81600101819055506115dc83600654611a7e90919063ffffffff16565b6006819055503073ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c846040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60016020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561173657600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b151561181357600080fd5b6102c65a03f1151561182457600080fd5b505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415156118fb57806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561195957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561199557600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080828402905060008414806119fa57508284828115156119f757fe5b04145b1515611a0257fe5b8091505092915050565b6000808284811515611a1a57fe5b0490508091505092915050565b6000611a416202a300600754611a7e90919063ffffffff16565b421015611a7557611a6e611a5f600584611a0c90919063ffffffff16565b83611a7e90919063ffffffff16565b9050611a79565b8190505b919050565b6000808284019050838110151515611a9257fe5b8091505092915050565b611aee81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611a7e90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b4681600254611a7e90919063ffffffff16565b6002819055505050565b6000828211151515611b5e57fe5b8183039050929150505600a165627a7a72305820ec0d82a406896ccf20989b3d6e650abe4dc104e400837f1f58e67ef499493ae90029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008d69d00910d0b2afb2a99ed6c16c8129fa8e1751", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000e819f024b41358d2c08e3a868a5c5dd0566078d4", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000000000000000000000000000000000005a388981", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000005a3b38e6" - } - }, - "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826": { - "balance": "0x2a2dd979a35cf000", - "code": "0x", - "nonce": "0", - "storage": {} - }, - "0xe819f024b41358d2c08e3a868a5c5dd0566078d4": { - "balance": "0x0", - "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c681461027257806370a08231146102ad5780638da5cb5b146102fa57806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e14610437578063f2fde38b146104a3575b600080fd5b34156100ca57600080fd5b6100d26104dc565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610515565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba61069c565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106a2565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610952565b6040518082815260200191505060405180910390f35b341561027d57600080fd5b6102936004808035906020019091905050610957565b604051808215151515815260200191505060405180910390f35b34156102b857600080fd5b6102e4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610abe565b6040518082815260200191505060405180910390f35b341561030557600080fd5b61030d610b07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561035a57600080fd5b610362610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b66565b604051808215151515815260200191505060405180910390f35b341561044257600080fd5b61048d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d01565b6040518082815260200191505060405180910390f35b34156104ae57600080fd5b6104da600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d88565b005b6040805190810160405280600b81526020017f416c6c436f6465436f696e00000000000000000000000000000000000000000081525081565b6000808214806105a157506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ac57600080fd5b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905061077683600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061080b83600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108618382610e7d90919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b600681565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109b557600080fd5b610a0782600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610a5f82600054610e7d90919063ffffffff16565b60008190555060003373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600481526020017f414c4c430000000000000000000000000000000000000000000000000000000081525081565b6000610bba82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c4f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610e5c5780600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000808284019050838110151515610e7357fe5b8091505092915050565b6000828211151515610e8b57fe5b8183039050929150505600a165627a7a7230582059f3ea3df0b054e9ab711f37969684ba83fe38f255ffe2c8d850d951121c51100029", - "nonce": "1", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3956606365", - "extraData": "0x566961425443", - "gasLimit": "5418523", - "hash": "0x6f37eb930a25da673ea1bb80fd9e32ddac19cdf7cd4bb2eac62cc13598624077", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "mixHash": "0x10971cde68c587c750c23b8589ae868ce82c2c646636b97e7d9856470c5297c7", - "nonce": "0x810f923ff4b450a1", - "number": "2295103", - "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e", - "timestamp": "1513681246", - "totalDifficulty": "7162347056825919" - }, - "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea", - "result": [ - { - "action": { - "callType": "call", - "from": "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826", - "gas": "0x7dfa6", - "input": "0x", - "to": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76", - "value": "0xe92596fd6290000" - }, - "blockNumber": 2295104, - "error": "execution reverted", - "result": { - "gasUsed": "0x7c1c8" - }, - "subtraces": 1, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76", - "gas": "0x75fe3", - "input": "0xa9059cbb000000000000000000000000d4fcab9f0a6dc0493af47c864f6f17a8a5e2e82600000000000000000000000000000000000000000000000000000000000002f4", - "to": "0xe819f024b41358d2c08e3a868a5c5dd0566078d4", - "value": "0x0" - }, - "blockNumber": 0, - "error": "invalid opcode: INVALID", - "result": {}, - "subtraces": 0, - "traceAddress": [0], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json deleted file mode 100644 index 3fcc61fc80..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "genesis": { - "difficulty": "1808543", - "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", - "gasLimit": "4875092", - "hash": "0x3851fdc18bd5f2314cf0c90439356f9a1fe157d7fb06c20e20b77954da903671", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "mixHash": "0x3d4e702d6058acf94c9547560f05536d45d515bd4f9014564ec41b5b4ff9578b", - "nonce": "0x1695153e7b16c1e7", - "number": "555461", - "stateRoot": "0xba8272acd0dfeb5f04376328e8bfc5b276b177697000c204a060f6f7b629ae32", - "timestamp": "1577423350", - "totalDifficulty": "462222992438", - "alloc": { - "0xcf5b3467dfa45cdc8e5358a7a1ba4deb02e5faed": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x16c102a3b09c02abdace", - "nonce": "19049", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "555462", - "difficulty": "1808543", - "timestamp": "1577423360", - "gasLimit": "4873701", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf90451824a6985746a52880083053e908080b903fb60606040525b60405161015b806102a0833901809050604051809103906000f0600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b610247806100596000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900480632ef9db1314610044578063e37678761461007157610042565b005b61005b6004803590602001803590602001506100ad565b6040518082815260200191505060405180910390f35b61008860048035906020018035906020015061008a565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600060008484604051808381526020018281526020019250505060405180910390209150610120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167f6164640000000000000000000000000000000000000000000000000000000000846101e3565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681868660405180807f616464000000000000000000000000000000000000000000000000000000000081526020015060200184815260200183815260200182815260200193505050506000604051808303816000866161da5a03f191505050600060005060008281526020019081526020016000206000505492506101db565b505092915050565b60004340848484604051808581526020018473ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140183815260200182815260200194505050505060405180910390209050610240565b9392505050566060604052610148806100136000396000f30060606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b50505681a1a0b9a85df655d3b6aa081e52d8c3db52c50c2bf97d9d993a980113b2262649c125a00d51e63880ca8ef4705914a71e7ff906834a9cdcff0cbd063ff4e43a5905890d", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x53e90", - "init": "0x60606040525b60405161015b806102a0833901809050604051809103906000f0600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b610247806100596000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900480632ef9db1314610044578063e37678761461007157610042565b005b61005b6004803590602001803590602001506100ad565b6040518082815260200191505060405180910390f35b61008860048035906020018035906020015061008a565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600060008484604051808381526020018281526020019250505060405180910390209150610120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167f6164640000000000000000000000000000000000000000000000000000000000846101e3565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681868660405180807f616464000000000000000000000000000000000000000000000000000000000081526020015060200184815260200183815260200182815260200193505050506000604051808303816000866161da5a03f191505050600060005060008281526020019081526020016000206000505492506101db565b505092915050565b60004340848484604051808581526020018473ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140183815260200182815260200194505050505060405180910390209050610240565b9392505050566060604052610148806100136000396000f30060606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b505056" - }, - "result": { - "gasUsed": "0x53e90", - "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632ef9db1314610044578063e37678761461007157610042565b005b61005b6004803590602001803590602001506100ad565b6040518082815260200191505060405180910390f35b61008860048035906020018035906020015061008a565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000600060008484604051808381526020018281526020019250505060405180910390209150610120600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167f6164640000000000000000000000000000000000000000000000000000000000846101e3565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681868660405180807f616464000000000000000000000000000000000000000000000000000000000081526020015060200184815260200183815260200182815260200193505050506000604051808303816000866161da5a03f191505050600060005060008281526020019081526020016000206000505492506101db565b505092915050565b60004340848484604051808581526020018473ffffffffffffffffffffffffffffffffffffffff166c0100000000000000000000000002815260140183815260200182815260200194505050505060405180910390209050610240565b939250505056", - "address": "0x9db7a1baf185a865ffee3824946ccd8958191e5e" - }, - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 23, - "transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03", - "blockNumber": 555462, - "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1", - "time": "1.147715ms" - }, - { - "type": "create", - "action": { - "from": "0x9db7a1baf185a865ffee3824946ccd8958191e5e", - "value": "0x0", - "gas": "0x30b34", - "init": "0x6060604052610148806100136000396000f30060606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b505056" - }, - "result": { - "gasUsed": "0x1009d", - "code": "0x60606040526000357c010000000000000000000000000000000000000000000000000000000090048063471407e614610044578063e37678761461007757610042565b005b6100616004803590602001803590602001803590602001506100b3565b6040518082815260200191505060405180910390f35b61008e600480359060200180359060200150610090565b005b8060006000506000848152602001908152602001600020600050819055505b5050565b6000818301905080506100c684826100d5565b8090506100ce565b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff16828260405180807f7265676973746572496e74000000000000000000000000000000000000000000815260200150602001838152602001828152602001925050506000604051808303816000866161da5a03f1915050505b505056", - "address": "0xcf5b3467dfa45cdc8e5358a7a1ba4deb02e5faed" - }, - "traceAddress": [0], - "subtraces": 0, - "transactionPosition": 23, - "transactionHash": "0xe267552ce8437a5bc7081385c99f912de5723ad34b958db215dbc41abd5f6c03", - "blockNumber": 555462, - "blockHash": "0x38bba9e3965b57205097ea5ec53fc403cf3941bec2e4c933faae244de5ca4ba1" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json deleted file mode 100644 index 0eaa3f867a..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create2_action_gas.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "genesis": { - "difficulty": "4635413", - "extraData": "0xd683010b05846765746886676f312e3133856c696e7578", - "gasLimit": "9289294", - "hash": "0x359775cf1a2ae2400e26ec68bf33bcfe38b7979c76b7e616f42c4ca7e7605e39", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "mixHash": "0x4b2a0ef121a9c7d732fa0fbd4166a0e1041d2da2b8cb677c61edabf8b7183b64", - "nonce": "0x2a8a64ad9757be55", - "number": "1555160", - "stateRoot": "0x95067c12148e2362fcd4a89df286ff0b1739ef097a40ca42ae7f698af9a9d913", - "timestamp": "1590793999", - "totalDifficulty": "2242063623471", - "alloc": { - "0x8785e369f0ef0a4e5c5a5f929680427dc75273a5": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x623145b285b3f551fa3f", - "nonce": "260617", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555161", - "difficulty": "4633150", - "timestamp": "1590794020", - "gasLimit": "9298364", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf85e8303fa09843b9aca0083019ed880808a6000600060006000f50081a2a0485ea410e210740eef8e6f6de11c530f46f8da80eecb02afbb6c5f61749ac015a068d72f1b0f1d3cb4e214d5def79b49a73e6ee91db2df83499a54c656c144600f", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x19ed8", - "init": "0x6000600060006000f500" - }, - "result": { - "gasUsed": "0x14c78", - "code": "0x", - "address": "0x2e8eded627eead210cb6143eb39ef7a3e44e4f00" - }, - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 31, - "transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41", - "blockNumber": 1555161, - "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171", - "time": "889.048µs" - }, - { - "type": "create", - "action": { - "from": "0x2e8eded627eead210cb6143eb39ef7a3e44e4f00", - "value": "0x0", - "gas": "0x5117", - "init": "0x" - }, - "result": { - "gasUsed": "0x0", - "code": "0x", - "address": "0x8785e369f0ef0a4e5c5a5f929680427dc75273a5" - }, - "traceAddress": [0], - "subtraces": 0, - "transactionPosition": 31, - "transactionHash": "0x1257b698c5833c54ce786734087002b097275abc3877af082b5c2a538e894a41", - "blockNumber": 1555161, - "blockHash": "0xb0793dd508dd106a19794b8ce1dfc0ff8d98c76aab61bf32a11799854149a171" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json deleted file mode 100644 index 132b84df36..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_action_gas.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "genesis": { - "difficulty": "4639933", - "extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578", - "gasLimit": "9280188", - "hash": "0x9a5f3a98eb1c60f6e3f450658a9cea190157e7021d04f927b752ad6482cf9194", - "miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3", - "mixHash": "0x6b6f8fcaa54b8565c4c1ae7cf0a020e938a53007f4561e758b17bc05c9044d78", - "nonce": "0x773aba50dc51b462", - "number": "1555169", - "stateRoot": "0xc4b9703de3e59ff795baae2c3afa010cf039c37244a7a6af7f3f491a10601348", - "timestamp": "1590794111", - "totalDifficulty": "2242105342155", - "alloc": { - "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x62325b40cbbd0915c4b9", - "nonce": "260875", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555170", - "difficulty": "4642198", - "timestamp": "1590794112", - "gasLimit": "9289249", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf8658303fb0b843b9aca0083019ee48080915a600055600060006000f0505a6001550081a2a01a7deb3a16d967b766459ef486b00656c6581e5ad58968184a33701e27e0eb8aa07162ccdfe2018d64360a605310a62c399dd586c7282dd42a88c54f02f51d451f", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x19ee4", - "init": "0x5a600055600060006000f0505a60015500" - }, - "error": "out of gas", - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 63, - "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650", - "blockNumber": 1555170, - "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e", - "time": "952.736µs" - }, - { - "type": "create", - "action": { - "from": "0x9c5cfe45b15eaff4ad617af4250189e26024a4f8", - "value": "0x0", - "gas": "0x3cb", - "init": "0x" - }, - "result": { - "gasUsed": "0x0", - "code": "0x", - "address": "0x5ac5599fc9df172c89ee7ec55ad9104ccbfed40d" - }, - "traceAddress": [0], - "subtraces": 0, - "transactionPosition": 63, - "transactionHash": "0x60e881fae3884657b5430925c5d0053535b45cce0b8188f2a6be1feee8bcc650", - "blockNumber": 1555170, - "blockHash": "0xea46fbf941d51bf1e4180fbf26d22fda3896f49c7f371d109c226de95dd7b02e" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json deleted file mode 100644 index 28e96684b2..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_create_inerror.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "genesis": { - "difficulty": "3244991", - "extraData": "0x", - "gasLimit": "7968787", - "hash": "0x62bbf18c203068a8793af8d8360d054f95a63bc62b87ade550861ed490af3f15", - "miner": "0x9f2659ffe7b3b467e46dcec3623392cf51635079", - "mixHash": "0xc8dec711fd1e03972b6a279a09dc0cd29c5171b60f42c4ce37c7c51ff445f776", - "nonce": "0x40b1bbcc25ddb804", - "number": "839246", - "stateRoot": "0x4bb3b02ec70b837651233957fb61a6ea3fc6a4244c1f55df7a713c154829ec0a", - "timestamp": "1581179375", - "totalDifficulty": "1023985623933", - "alloc": { - "0x76554b33410b6d90b7dc889bfed0451ad195f27e": { - "balance": "0x0", - "nonce": "1", - "code": "0x6080604052348015600f57600080fd5b506004361060505760003560e01c8063391521f414605557806355313dea14605d5780636d3d14161460655780638da5cb5b14606d578063b9d1e5aa1460b5575b600080fd5b605b60bd565b005b606360c8565b005b606b60ca565b005b607360cf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b60bb60f4565b005b6020610123600af050565b005b600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565bfefea165627a7a723058202094d5aa5dbbd493e9a2c64c50b62eba4b109b2a12d2bb73a5d0d54982651fc80029", - "storage": {} - }, - "0xed69ab7145a9bae7152406d062c077c6ecc6ae18": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0xa3b31cbd5168d3c99756660d4b7625d679e12573": { - "balance": "0x569bc6535d3083fce", - "nonce": "26", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "839247", - "difficulty": "3213311", - "timestamp": "1581179571", - "gasLimit": "7961006", - "miner": "0x9f2659ffe7b3b467e46dcec3623392cf51635079" - }, - "input": "0xf86a1a8509502f9000830334509476554b33410b6d90b7dc889bfed0451ad195f27e8084391521f481a2a02e4ff0d171a860c8c7de2283978e2f225f9ba3ed4dec446b773c6b2d73ef22dea02a6a517528b491cb71b204f534db11a1c8059035f54d5bae347d1cab536bde2c", - "result": [ - { - "type": "call", - "action": { - "from": "0xa3b31cbd5168d3c99756660d4b7625d679e12573", - "to": "0x76554b33410b6d90b7dc889bfed0451ad195f27e", - "value": "0x0", - "gas": "0x33450", - "input": "0x391521f4", - "callType": "call" - }, - "result": { - "gasUsed": "0xd0b5", - "output": "0x" - }, - "traceAddress": [], - "subtraces": 0, - "transactionPosition": 26, - "transactionHash": "0xcb1090fa85d2a3da8326b75333e92b3dca89963c895d9c981bfdaa64643135e4", - "blockNumber": 839247, - "blockHash": "0xce7ff7d84ca97f0f89d6065e2c12409a795c9f607cdb14aef0713cad5d7e311c", - "time": "182.267µs" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json deleted file mode 100644 index c3191d61bc..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/nested_pointer_issue.json +++ /dev/null @@ -1,189 +0,0 @@ -{ - "genesis": { - "number": "13535", - "hash": "0x6f706fe8026edb51577b57685574dc152dba4e2ebfc8a50bb63a8c95a4f8818d", - "nonce": "0x0000000000000000", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "stateRoot": "0x7f54db248a004ca182fe87fdfa6efda97163908b4f0cc84b36a6d60699d5d1be", - "miner": "0x0000000000000000000000000000000000000000", - "difficulty": "1", - "totalDifficulty": "24766", - "extraData": "0xf09f928e20407072796c616273206e6f64652d3020f09f928e000000000000001d32ac3baf238e163e18ed6d77b67b0b54b08ad9781dc4ffd93c5ede1ca12c5f21b36ac39c7ebb88dff65da91f5b9461f19873a02602230b931ba388a809119f00", - "gasLimit": "8000000", - "timestamp": "1549153003", - "alloc": { - "0x0b1ba0af832d7c05fd64161e0db78e85978e8082": { - "balance": "0x0", - "nonce": "1", - "code": "0x6080604052600436106100ae5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde0381146100b8578063095ea7b31461014257806318160ddd1461018757806323b872dd146101ae5780632e1a7d4d146101e5578063313ce567146101fd57806370a082311461022857806395d89b4114610256578063a9059cbb1461026b578063d0e30db0146100ae578063dd62ed3e1461029c575b6100b66102d0565b005b3480156100c457600080fd5b506100cd61031f565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101075781810151838201526020016100ef565b50505050905090810190601f1680156101345780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561014e57600080fd5b5061017373ffffffffffffffffffffffffffffffffffffffff600435166024356103cb565b604080519115158252519081900360200190f35b34801561019357600080fd5b5061019c61043e565b60408051918252519081900360200190f35b3480156101ba57600080fd5b5061017373ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610443565b3480156101f157600080fd5b506100b66004356105e3565b34801561020957600080fd5b50610212610678565b6040805160ff9092168252519081900360200190f35b34801561023457600080fd5b5061019c73ffffffffffffffffffffffffffffffffffffffff60043516610681565b34801561026257600080fd5b506100cd610693565b34801561027757600080fd5b5061017373ffffffffffffffffffffffffffffffffffffffff6004351660243561070b565b3480156102a857600080fd5b5061019c73ffffffffffffffffffffffffffffffffffffffff6004358116906024351661071f565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156103c35780601f10610398576101008083540402835291602001916103c3565b820191906000526020600020905b8154815290600101906020018083116103a657829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b303190565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081205482111561047557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841633148015906104eb575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105655773ffffffffffffffffffffffffffffffffffffffff8416600090815260046020908152604080832033845290915290205482111561052d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b336000908152600360205260409020548111156105ff57600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f1935050505015801561063e573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156103c35780601f10610398576101008083540402835291602001916103c3565b6000610718338484610443565b9392505050565b6004602090815260009283526040808420909152908252902054815600a165627a7a72305820228981f11f47ad9630080069b0a81423fcfba5aa8e0f478a579c4bc080ba7e820029", - "storage": { - "0xbe8a6e3827dad84a671edac41a02b0f5b47b9d0339adb1e9411b9ba4e2118738": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x48bacb9266a570d521063ef5dd96e61686dbe788": { - "balance": "0x0", - "nonce": "1", - "code": "0x6080604052600436106101b65763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663288cdc9181146101bb578063297bb70b146101f15780632ac126221461021e5780633683ef8e1461024b5780633c28d8611461026d5780633e228bae1461029a5780633fd3c997146102ba5780634ac14782146102e75780634d0ae546146103075780634f9559b11461032757806350dde190146103475780636070410814610367578063642f2eaf1461039457806364a3bc15146103b457806377fcce68146103d45780637b8e3514146103f45780637e1d9808146104145780637e9d74dc1461043457806382c174d0146104615780638da5cb5b146104815780639363470214610496578063a3e20380146104b6578063b4be83d5146104d6578063bfc8bfce146104f6578063c585bb9314610516578063c75e0a8114610536578063d46b02c314610563578063d9bfa73e14610583578063db123b1a146105a3578063dd1c7d18146105c5578063e306f779146105e5578063e5fa431b146105fa578063eea086ba1461061a578063f2fde38b1461062f578063ffa1ad741461064f575b600080fd5b3480156101c757600080fd5b506101db6101d63660046148ee565b610664565b6040516101e89190615513565b60405180910390f35b3480156101fd57600080fd5b5061021161020c366004614811565b610676565b6040516101e891906157ed565b34801561022a57600080fd5b5061023e6102393660046148ee565b6107a1565b6040516101e89190615505565b34801561025757600080fd5b5061026b61026636600461492b565b6107b6565b005b34801561027957600080fd5b5061028d610288366004614a5f565b6108a3565b6040516101e891906157fb565b3480156102a657600080fd5b506102116102b5366004614b1f565b610a3a565b3480156102c657600080fd5b506102da6102d53660046149ee565b610a90565b6040516101e891906155cf565b3480156102f357600080fd5b5061026b6103023660046147dc565b610ab8565b34801561031357600080fd5b50610211610322366004614811565b610b85565b34801561033357600080fd5b5061026b6103423660046148ee565b610c75565b34801561035357600080fd5b50610211610362366004614811565b610e2a565b34801561037357600080fd5b506103876103823660046149ee565b610ebe565b6040516101e89190615425565b3480156103a057600080fd5b5061023e6103af3660046148ee565b610f0c565b3480156103c057600080fd5b506102116103cf366004614b1f565b610f21565b3480156103e057600080fd5b5061026b6103ef3660046147ac565b610fcc565b34801561040057600080fd5b5061023e61040f366004614772565b611106565b34801561042057600080fd5b5061021161042f3660046148a5565b611126565b34801561044057600080fd5b5061045461044f3660046147dc565b61128a565b6040516101e891906154f4565b34801561046d57600080fd5b5061023e61047c36600461490c565b61131f565b34801561048d57600080fd5b5061038761133f565b3480156104a257600080fd5b5061023e6104b1366004614993565b61135b565b3480156104c257600080fd5b506102116104d13660046148a5565b6118de565b3480156104e257600080fd5b506102116104f1366004614b1f565b6119f1565b34801561050257600080fd5b5061026b610511366004614b68565b611a6c565b34801561052257600080fd5b5061026b610531366004614754565b611d05565b34801561054257600080fd5b50610556610551366004614a2a565b611f30565b6040516101e8919061580a565b34801561056f57600080fd5b5061026b61057e366004614a2a565b61202a565b34801561058f57600080fd5b506101db61059e366004614772565b6120c6565b3480156105af57600080fd5b506105b86120e3565b6040516101e891906155be565b3480156105d157600080fd5b506102116105e03660046148a5565b61218e565b3480156105f157600080fd5b506101db612263565b34801561060657600080fd5b506102116106153660046148a5565b612269565b34801561062657600080fd5b506103876123db565b34801561063b57600080fd5b5061026b61064a366004614754565b6123f7565b34801561065b57600080fd5b506105b86124a8565b60046020526000908152604090205481565b61067e614386565b600080610689614386565b60005460ff16156106cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558751935091505b81831461076f57610758878381518110151561071957fe5b90602001906020020151878481518110151561073157fe5b90602001906020020151878581518110151561074957fe5b906020019060200201516124df565b9050610764848261257d565b600190910190610701565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055509392505050565b60056020526000908152604090205460ff1681565b73ffffffffffffffffffffffffffffffffffffffff831633146108465761080e848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375061135b945050505050565b1515610846576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061569d565b5050600091825260076020908152604080842073ffffffffffffffffffffffffffffffffffffffff9093168452919052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6108ab6143af565b6108b36143de565b6108bb6143de565b6000805460ff16156108f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561016080890151610140808a01919091528901519088015261094588611f30565b925061095087611f30565b915061095a6125df565b905061096888848389612611565b61097487838388612611565b61097e88886127a9565b610992888885604001518560400151612809565b8051602081015190519195506109ad918a9186918190612990565b6020808501519081015190516109c99189918591908190612990565b6109e28882856020015186604001518860000151612aa9565b6109fb8782846020015185604001518860200151612aa9565b610a0788888387612b55565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550949350505050565b610a42614386565b6060610a4f858585612d2d565b9050608081825160208401305af48015610a8657815183526020820151602084015260408201516040840152606082015160608401525b505b509392505050565b600b6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b60008054819060ff1615610af8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558151905b808214610b5857610b508382815181101515610b4157fe5b90602001906020020151612eff565b600101610b29565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b610b8d614386565b600080610b98614386565b60005460ff1615610bd5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558751935091505b81831461076f57610c5e8783815181101515610c1f57fe5b906020019060200201518784815181101515610c3757fe5b906020019060200201518785815181101515610c4f57fe5b90602001906020020151612f2a565b9050610c6a848261257d565b600190910190610c07565b6000805481908190819060ff1615610cb9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610cec6125df565b935073ffffffffffffffffffffffffffffffffffffffff84163314610d115733610d14565b60005b73ffffffffffffffffffffffffffffffffffffffff8086166000908152600660209081526040808320938516835292905220549093506001860192509050808211610d8b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061572d565b73ffffffffffffffffffffffffffffffffffffffff80851660008181526006602090815260408083209488168084529490915290819020859055517f82af639571738f4ebd4268fb0363d8957ebe1bbb9e78dba5ebd69eed39b154f090610df3908690615513565b60405180910390a35050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055505050565b610e32614386565b600080610e3d614386565b86519250600091505b818314610eb457610e9d8783815181101515610e5e57fe5b906020019060200201518784815181101515610e7657fe5b906020019060200201518785815181101515610e8e57fe5b90602001906020020151610a3a565b9050610ea9848261257d565b600190910190610e46565b5050509392505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600b602052604090205473ffffffffffffffffffffffffffffffffffffffff165b919050565b60096020526000908152604090205460ff1681565b610f29614386565b60005460ff1615610f66576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610f9c848484612f2a565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055949350505050565b6000805460ff161561100a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561103d6125df565b73ffffffffffffffffffffffffffffffffffffffff8181166000818152600860209081526040808320948916808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168715151790555192935090917fa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba891906110d1908690615505565b60405180910390a35050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550565b600860209081526000928352604080842090915290825290205460ff1681565b61112e614386565b6060600080600061113d614386565b60005460ff161561117a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117815589518a919081106111b257fe5b906020019060200201516101600151945088519350600092505b828414611255578489848151811015156111e257fe5b906020019060200201516101600181905250611202888760200151612f7d565b915061122e898481518110151561121557fe5b9060200190602002015183898681518110151561074957fe5b905061123a868261257d565b6020860151881161124a57611255565b6001909201916111cc565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055509195945050505050565b606060006060600084519250826040519080825280602002602001820160405280156112d057816020015b6112bd6143de565b8152602001906001900390816112b55790505b509150600090505b808314610a88576112ff85828151811015156112f057fe5b90602001906020020151611f30565b828281518110151561130d57fe5b602090810290910101526001016112d8565b600760209081526000928352604080842090915290825290205460ff1681565b60035473ffffffffffffffffffffffffffffffffffffffff1681565b600080600080600080600080600089511115156113a4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061571d565b6113ad89612fc4565b7f010000000000000000000000000000000000000000000000000000000000000090049650600760ff88161061140f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061563d565b8660ff16600781111561141e57fe5b9550600086600781111561142e57fe5b1415611466576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061570d565b600186600781111561147457fe5b14156114bc578851156114b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157dd565b600097506118d0565b60028660078111156114ca57fe5b141561160557885160411461150b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155dd565b88600081518110151561151a57fe5b01602001517f010000000000000000000000000000000000000000000000000000000000000090819004810204945061155a89600163ffffffff61308816565b935061156d89602163ffffffff61308816565b925060018b86868660405160008152602001604052604051611592949392919061556e565b60206040516020810390808403906000865af11580156115b6573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015173ffffffffffffffffffffffffffffffffffffffff8c811690821614995092506118d09050565b600386600781111561161357fe5b14156117b9578851604114611654576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155dd565b88600081518110151561166357fe5b01602001517f01000000000000000000000000000000000000000000000000000000000000009081900481020494506116a389600163ffffffff61308816565b93506116b689602163ffffffff61308816565b925060018b60405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c0182600019166000191681526020019150506040516020818303038152906040526040518082805190602001908083835b6020831061175757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161171a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822060008352910192839052611592945092508991899150889061556e565b60048660078111156117c757fe5b14156117df576117d88b8b8b6130d3565b97506118d0565b60058660078111156117ed57fe5b1415611850576117fc89613228565b73ffffffffffffffffffffffffffffffffffffffff808c1660009081526008602090815260408083209385168352929052205490915060ff16151561184457600097506118d0565b6117d8818c8c8c6132a1565b600686600781111561185e57fe5b141561189e5760008b815260076020908152604080832073ffffffffffffffffffffffffffffffffffffffff8e16845290915290205460ff1697506118d0565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061563d565b505050505050509392505050565b6118e6614386565b60606000806000806118f6614386565b89600081518110151561190557fe5b906020019060200201516101400151955089519450600093505b8385146119e457858a8581518110151561193557fe5b6020908102909101015161014001528651611951908a90612f7d565b92506119948a8581518110151561196457fe5b9060200190602002015160a001518b8681518110151561198057fe5b9060200190602002015160800151856133fd565b91506119c08a858151811015156119a757fe5b90602001906020020151838a87815181101515610e8e57fe5b90506119cc878261257d565b865189116119d9576119e4565b60019093019261191f565b5050505050509392505050565b6119f9614386565b60005460ff1615611a36576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610f9c8484846124df565b600a5460009073ffffffffffffffffffffffffffffffffffffffff1615611abf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b611b02611afd888888888080601f01602080910402602001604051908101604052809392919081815260200183838082843750613453945050505050565b613694565b60008181526009602052604090205490915060ff1615611b4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061568d565b73ffffffffffffffffffffffffffffffffffffffff86163314611c1f57611ba6818785858080601f0160208091040260200160405190810160405280939291908181526020018383808284375061135b945050505050565b1515611bde576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157cd565b600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff88161790555b6000818152600960205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790555130908690869080838380828437820191505092505050600060405180830381855af49150501515611cb6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156bd565b73ffffffffffffffffffffffffffffffffffffffff86163314611cfc57600a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b50505050505050565b6003546000908190819073ffffffffffffffffffffffffffffffffffffffff163314611d5d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061577d565b8392508273ffffffffffffffffffffffffffffffffffffffff1663ae25532e6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015611dc457600080fd5b505af1158015611dd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611dfc9190810190614a0c565b7fffffffff0000000000000000000000000000000000000000000000000000000081166000908152600b602052604090205490925073ffffffffffffffffffffffffffffffffffffffff1690508015611e81576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061561d565b7fffffffff0000000000000000000000000000000000000000000000000000000082166000908152600b60205260409081902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8616179055517fd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c0319490611f2290849087906155a3565b60405180910390a150505050565b611f386143de565b611f41826136d1565b6020808301829052600091825260049052604090819020549082015260808201511515611f755760015b60ff168152610f07565b60a08201511515611f87576002611f6b565b60a0820151604082015110611f9d576005611f6b565b6101008201514210611fb0576004611f6b565b60208082015160009081526005909152604090205460ff1615611fd4576006611f6b565b610120820151825173ffffffffffffffffffffffffffffffffffffffff90811660009081526006602090815260408083206060880151909416835292905220541115612021576006611f6b565b60038152919050565b60005460ff1615612067576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905561209b81612eff565b50600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600660209081526000928352604080842090915290825290205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156121865780601f1061215b57610100808354040283529160200191612186565b820191906000526020600020905b81548152906001019060200180831161216957829003601f168201915b505050505081565b612196614386565b606060008060006121a5614386565b8860008151811015156121b457fe5b906020019060200201516101600151945088519350600092505b828414612257578489848151811015156121e457fe5b906020019060200201516101600181905250612204888760200151612f7d565b9150612230898481518110151561221757fe5b90602001906020020151838986815181101515610e8e57fe5b905061223c868261257d565b6020860151881161224c57612257565b6001909201916121ce565b50505050509392505050565b60025481565b612271614386565b6060600080600080612281614386565b60005460ff16156122be576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061576d565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011781558a518b919081106122f657fe5b906020019060200201516101400151955089519450600093505b8385146123a557858a8581518110151561232657fe5b6020908102909101015161014001528651612342908a90612f7d565b92506123558a8581518110151561196457fe5b91506123818a8581518110151561236857fe5b90602001906020020151838a8781518110151561074957fe5b905061238d878261257d565b8651891161239a576123a5565b600190930192612310565b5050600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905550929695505050505050565b600a5473ffffffffffffffffffffffffffffffffffffffff1681565b60035473ffffffffffffffffffffffffffffffffffffffff163314612448576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061577d565b73ffffffffffffffffffffffffffffffffffffffff8116156124a557600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b60408051808201909152600581527f322e302e30000000000000000000000000000000000000000000000000000000602082015281565b6124e7614386565b6124ef6143de565b60008060006124fd88611f30565b93506125076125df565b925061251588858589612611565b6125278860a001518560400151612f7d565b915061253387836136df565b9050612546888589848960000151612990565b61255088826136f5565b945061256788848660200151876040015189612aa9565b612572888487613756565b505050509392505050565b8151815161258b9190613864565b8252602080830151908201516125a19190613864565b6020830152604080830151908201516125ba9190613864565b6040830152606080830151908201516125d39190613864565b60609092019190915250565b600a5460009073ffffffffffffffffffffffffffffffffffffffff16818115612608578161260a565b335b9392505050565b825160ff1660031461264f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061579d565b606084015173ffffffffffffffffffffffffffffffffffffffff16156126c257606084015173ffffffffffffffffffffffffffffffffffffffff1633146126c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157ad565b602084015173ffffffffffffffffffffffffffffffffffffffff161561274d578173ffffffffffffffffffffffffffffffffffffffff16846020015173ffffffffffffffffffffffffffffffffffffffff1614151561274d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155ed565b604083015115156127a35761276b836020015185600001518361135b565b15156127a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061565d565b50505050565b6127bb8260a001518260a001516138ae565b6127cd836080015183608001516138ae565b1015612805576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157bd565b5050565b6128116143af565b6000806000806128258960a0015188612f7d565b935061283a89608001518a60a0015186613909565b925061284a8860a0015187612f7d565b915061285f88608001518960a0015184613909565b90508084106128a25760208086018051839052805182018490525151865182015260808a015160a08b015187519092015161289a9290613909565b8551526128df565b845183905284516020908101859052855181015190860180519190915260a089015160808a01519151516128d69290613986565b60208087015101525b84515160208087015101516128f49190612f7d565b604086015284515160808a015160c08b0151612911929190613909565b85516040015284516020015160a08a015160e08b0151612932929190613909565b855160600152602085015151608089015160c08a0151612953929190613909565b8560200151604001818152505061297b8560200151602001518960a001518a60e00151613909565b60208601516060015250505050949350505050565b8215156129c9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156dd565b82821115612a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156cd565b8460a00151612a16856040015184613864565b1115612a4e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906155fd565b612a5c8560800151836138ae565b612a6a828760a001516138ae565b1115612aa2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061575d565b5050505050565b612ab7828260200151613864565b600084815260046020908152604091829020929092558681015187518451938501518584015160608701516101408c01516101608d015196518b9873ffffffffffffffffffffffffffffffffffffffff9788169897909616967f0bcc4c97732e47d9946f229edb95f5b6323f601300e4690de719993f3c37112996612b46968f96339692959194909390615433565b60405180910390a45050505050565b60018054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101008789161502019095169490940493840181900481028201810190925282815260609390929091830182828015612bfe5780601f10612bd357610100808354040283529160200191612bfe565b820191906000526020600020905b815481529060010190602001808311612be157829003601f168201915b50505050509050612c2685610140015186600001518660000151856020015160200151613a23565b61014084015184518651845160200151612c4293929190613a23565b612c5b8561014001518660000151858560400151613a23565b612c778186600001518760400151856000015160400151613a23565b612c938185600001518660400151856020015160400151613a23565b836040015173ffffffffffffffffffffffffffffffffffffffff16856040015173ffffffffffffffffffffffffffffffffffffffff161415612cfd57612cf881848760400151612cf3866000015160600151876020015160600151613864565b613a23565b612aa2565b612d1581848760400151856000015160600151613a23565b612aa281848660400151856020015160600151613a23565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b81811015612e34578351855260209485019490930192600101612e16565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b81811015612e7d578351855260209485019490930192600101612e5f565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b81811015612ec5578351855260209485019490930192600101612ea7565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b612f076143de565b612f1082611f30565b9050612f1c8282613bed565b612805828260200151613d04565b612f32614386565b612f3d8484846124df565b6020810151909150831461260a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061574d565b600082821115612fb9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061560d565b508082035b92915050565b6000808251111515613002576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156fd565b815182907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811061303257fe5b016020015182517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909252507f0100000000000000000000000000000000000000000000000000000000000000908190040290565b6000816020018351101515156130ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061562d565b50016020015190565b6040516000906060907f1626ba7e000000000000000000000000000000000000000000000000000000009061310e908790869060240161554e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093178352815191935090829081885afa8080156131ab576001811461321c57612572565b7f08c379a0000000000000000000000000000000000000000000000000000000006000527c20000000000000000000000000000000000000000000000000000000006020527c0c57414c4c45545f4552524f5200000000000000000000000000000000604052600060605260646000fd5b50505195945050505050565b60006014825110151515613268576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061578d565b613276826014845103613dab565b82517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec019092525090565b6040516000906060907f9363470200000000000000000000000000000000000000000000000000000000906132de90879087908790602401615521565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783528151919350908290818a5afa80801561337b57600181146133ec576133f1565b7f08c379a0000000000000000000000000000000000000000000000000000000006000527c20000000000000000000000000000000000000000000000000000000006020527c0f56414c494441544f525f4552524f5200000000000000000000000000604052600060605260646000fd5b825194505b50505050949350505050565b6000808311613438576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b61344b61344585846138ae565b84613e0c565b949350505050565b604080517f5a65726f45785472616e73616374696f6e2800000000000000000000000000006020808301919091527f75696e743235362073616c742c0000000000000000000000000000000000000060328301527f61646472657373207369676e6572416464726573732c00000000000000000000603f8301527f627974657320646174610000000000000000000000000000000000000000000060558301527f2900000000000000000000000000000000000000000000000000000000000000605f830152825180830384018152606090920192839052815160009384938493909282918401908083835b6020831061357c57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161353f565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905260405191909301819003812089519097508995509093508392850191508083835b6020831061361257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016135d5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040805192909401829003822097825281019a909a525073ffffffffffffffffffffffffffffffffffffffff97909716968801969096525050606085015250506080909120919050565b600280546040517f190100000000000000000000000000000000000000000000000000000000000081529182015260228101919091526042902090565b6000612fbe611afd83613e23565b60008183106136ee578161260a565b5090919050565b6136fd614386565b6020810182905260a08301516080840151613719918491613909565b808252608084015160c0850151613731929190613909565b604082015260a083015160e084015161374b918491613909565b606082015292915050565b60018054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156137ff5780601f106137d4576101008083540402835291602001916137ff565b820191906000526020600020905b8154815290600101906020018083116137e257829003601f168201915b5050505050905061381f8461014001518560000151858560000151613a23565b6138388461016001518486600001518560200151613a23565b61385081856000015186604001518560400151613a23565b6127a3818486604001518560600151613a23565b6000828201838110156138a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061567d565b8091505b5092915050565b6000808315156138c157600091506138a7565b508282028284828115156138d157fe5b04146138a3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061567d565b6000808311613944576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b61394f84848461427c565b15613438576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156ad565b60008083116139c1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b6139cc848484614301565b15613a03576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156ad565b61344b613445613a1386856138ae565b613a1e866001612f7d565b613864565b600080600083118015613a6257508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614155b15613be5578551600310613aa2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061573d565b50506020848101517fffffffff00000000000000000000000000000000000000000000000000000000166000818152600b90925260409091205473ffffffffffffffffffffffffffffffffffffffff16801515613b2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906156ed565b604051660fffffffffffe0603f885101168060840182017fa85e59e40000000000000000000000000000000000000000000000000000000083526080600484015273ffffffffffffffffffffffffffffffffffffffff8816602484015273ffffffffffffffffffffffffffffffffffffffff87166044840152856064840152608483015b81811015613bc757895181526020998a019901613baf565b61020084858403866000895af1801515613bdf573d85fd5b50505050505b505050505050565b805160009060ff16600314613c2e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061579d565b606083015173ffffffffffffffffffffffffffffffffffffffff1615613ca157606083015173ffffffffffffffffffffffffffffffffffffffff163314613ca1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c6906157ad565b613ca96125df565b835190915073ffffffffffffffffffffffffffffffffffffffff808316911614613cff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061566d565b505050565b6000818152600560205260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558281015183516101408501516101608601519351859473ffffffffffffffffffffffffffffffffffffffff9485169493909316927fdc47b3613d9fe400085f6dbdc99453462279057e6207385042827ed6b1a62cf792613d9f923392906154b7565b60405180910390a45050565b600081601401835110151515613ded576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061578d565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b6000808284811515613e1a57fe5b04949350505050565b604080517f4f726465722800000000000000000000000000000000000000000000000000006020808301919091527f61646472657373206d616b6572416464726573732c000000000000000000000060268301527f616464726573732074616b6572416464726573732c0000000000000000000000603b8301527f6164647265737320666565526563697069656e74416464726573732c0000000060508301527f616464726573732073656e646572416464726573732c00000000000000000000606c8301527f75696e74323536206d616b65724173736574416d6f756e742c0000000000000060828301527f75696e743235362074616b65724173736574416d6f756e742c00000000000000609b8301527f75696e74323536206d616b65724665652c00000000000000000000000000000060b48301527f75696e743235362074616b65724665652c00000000000000000000000000000060c58301527f75696e743235362065787069726174696f6e54696d655365636f6e64732c000060d68301527f75696e743235362073616c742c0000000000000000000000000000000000000060f48301527f6279746573206d616b65724173736574446174612c00000000000000000000006101018301527f62797465732074616b65724173736574446174610000000000000000000000006101168301527f290000000000000000000000000000000000000000000000000000000000000061012a830152825161010b81840301815261012b90920192839052815160009384938493849391929182918401908083835b602083106140ab57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161406e565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101408b0151805191995095509093508392850191508083835b6020831061414657805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101614109565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990921691161790526040519190930181900381206101608b0151805191985095509093508392850191508083835b602083106141e157805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016141a4565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909116921691909117905260405192018290039091207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180516101408b018051610160909c0180519a84529881529288526101a0822091529890525050509190525090919050565b6000808084116142b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b8215806142c3575084155b156142d15760009150610a88565b838015156142db57fe5b85840990506142ea85846138ae565b6142f66103e8836138ae565b101595945050505050565b60008080841161433d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106c69061564d565b821580614348575084155b156143565760009150610a88565b8380151561436057fe5b8584099050836143708583612f7d565b81151561437957fe5b0690506142ea85846138ae565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b610120604051908101604052806143c4614386565b81526020016143d1614386565b8152602001600081525090565b604080516060810182526000808252602082018190529181019190915290565b600061260a82356158b0565b6000601f8201831361441b57600080fd5b813561442e6144298261583f565b615818565b81815260209384019390925082018360005b8381101561446c578135860161445688826145bc565b8452506020928301929190910190600101614440565b5050505092915050565b6000601f8201831361448757600080fd5b81356144956144298261583f565b81815260209384019390925082018360005b8381101561446c57813586016144bd888261460b565b84525060209283019291909101906001016144a7565b6000601f820183136144e457600080fd5b81356144f26144298261583f565b9150818183526020840193506020810190508385602084028201111561451757600080fd5b60005b8381101561446c578161452d888261454f565b845250602092830192919091019060010161451a565b600061260a82356158c9565b600061260a82356158ce565b600061260a82356158d1565b600061260a82516158d1565b600080601f8301841361458557600080fd5b50813567ffffffffffffffff81111561459d57600080fd5b6020830191508360018202830111156145b557600080fd5b9250929050565b6000601f820183136145cd57600080fd5b81356145db61442982615860565b915080825260208301602083018583830111156145f757600080fd5b614602838284615907565b50505092915050565b6000610180828403121561461e57600080fd5b614629610180615818565b9050600061463784846143fe565b8252506020614648848483016143fe565b602083015250604061465c848285016143fe565b6040830152506060614670848285016143fe565b60608301525060806146848482850161454f565b60808301525060a06146988482850161454f565b60a08301525060c06146ac8482850161454f565b60c08301525060e06146c08482850161454f565b60e0830152506101006146d58482850161454f565b610100830152506101206146eb8482850161454f565b6101208301525061014082013567ffffffffffffffff81111561470d57600080fd5b614719848285016145bc565b6101408301525061016082013567ffffffffffffffff81111561473b57600080fd5b614747848285016145bc565b6101608301525092915050565b60006020828403121561476657600080fd5b600061344b84846143fe565b6000806040838503121561478557600080fd5b600061479185856143fe565b92505060206147a2858286016143fe565b9150509250929050565b600080604083850312156147bf57600080fd5b60006147cb85856143fe565b92505060206147a285828601614543565b6000602082840312156147ee57600080fd5b813567ffffffffffffffff81111561480557600080fd5b61344b84828501614476565b60008060006060848603121561482657600080fd5b833567ffffffffffffffff81111561483d57600080fd5b61484986828701614476565b935050602084013567ffffffffffffffff81111561486657600080fd5b614872868287016144d3565b925050604084013567ffffffffffffffff81111561488f57600080fd5b61489b8682870161440a565b9150509250925092565b6000806000606084860312156148ba57600080fd5b833567ffffffffffffffff8111156148d157600080fd5b6148dd86828701614476565b93505060206148728682870161454f565b60006020828403121561490057600080fd5b600061344b848461454f565b6000806040838503121561491f57600080fd5b6000614791858561454f565b6000806000806060858703121561494157600080fd5b600061494d878761454f565b945050602061495e878288016143fe565b935050604085013567ffffffffffffffff81111561497b57600080fd5b61498787828801614573565b95989497509550505050565b6000806000606084860312156149a857600080fd5b60006149b4868661454f565b93505060206149c5868287016143fe565b925050604084013567ffffffffffffffff8111156149e257600080fd5b61489b868287016145bc565b600060208284031215614a0057600080fd5b600061344b848461455b565b600060208284031215614a1e57600080fd5b600061344b8484614567565b600060208284031215614a3c57600080fd5b813567ffffffffffffffff811115614a5357600080fd5b61344b8482850161460b565b60008060008060808587031215614a7557600080fd5b843567ffffffffffffffff811115614a8c57600080fd5b614a988782880161460b565b945050602085013567ffffffffffffffff811115614ab557600080fd5b614ac18782880161460b565b935050604085013567ffffffffffffffff811115614ade57600080fd5b614aea878288016145bc565b925050606085013567ffffffffffffffff811115614b0757600080fd5b614b13878288016145bc565b91505092959194509250565b600080600060608486031215614b3457600080fd5b833567ffffffffffffffff811115614b4b57600080fd5b614b578682870161460b565b93505060206149c58682870161454f565b60008060008060008060808789031215614b8157600080fd5b6000614b8d898961454f565b9650506020614b9e89828a016143fe565b955050604087013567ffffffffffffffff811115614bbb57600080fd5b614bc789828a01614573565b9450945050606087013567ffffffffffffffff811115614be657600080fd5b614bf289828a01614573565b92509250509295509295509295565b614c0a816158b0565b82525050565b6000614c1b826158ac565b808452602084019350614c2d836158a6565b60005b82811015614c5d57614c438683516153e5565b614c4c826158a6565b606096909601959150600101614c30565b5093949350505050565b614c0a816158c9565b614c0a816158ce565b614c0a816158d1565b6000614c8d826158ac565b808452614ca1816020860160208601615913565b614caa8161593f565b9093016020019392505050565b614c0a816158fc565b601281527f4c454e4754485f36355f52455155495245440000000000000000000000000000602082015260400190565b600d81527f494e56414c49445f54414b455200000000000000000000000000000000000000602082015260400190565b600e81527f4f524445525f4f56455246494c4c000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f414c52454144595f455849535453000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601581527f5349474e41545552455f554e535550504f525445440000000000000000000000602082015260400190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601781527f494e56414c49445f4f524445525f5349474e4154555245000000000000000000602082015260400190565b600d81527f494e56414c49445f4d414b455200000000000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b600f81527f494e56414c49445f54585f484153480000000000000000000000000000000000602082015260400190565b601181527f494e56414c49445f5349474e4154555245000000000000000000000000000000602082015260400190565b600e81527f524f554e44494e475f4552524f52000000000000000000000000000000000000602082015260400190565b601081527f4641494c45445f455845435554494f4e00000000000000000000000000000000602082015260400190565b600d81527f54414b45525f4f56455250415900000000000000000000000000000000000000602082015260400190565b601481527f494e56414c49445f54414b45525f414d4f554e54000000000000000000000000602082015260400190565b601a81527f41535345545f50524f58595f444f45535f4e4f545f4558495354000000000000602082015260400190565b602181527f475245415445525f5448414e5f5a45524f5f4c454e4754485f5245515549524560208201527f4400000000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f5349474e41545552455f494c4c4547414c000000000000000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f305f52455155495245440000602082015260400190565b601781527f494e56414c49445f4e45575f4f524445525f45504f4348000000000000000000602082015260400190565b601e81527f4c454e4754485f475245415445525f5448414e5f335f52455155495245440000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601281527f494e56414c49445f46494c4c5f50524943450000000000000000000000000000602082015260400190565b601281527f5245454e5452414e43595f494c4c4547414c0000000000000000000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4f524445525f554e46494c4c41424c4500000000000000000000000000000000602082015260400190565b600e81527f494e56414c49445f53454e444552000000000000000000000000000000000000602082015260400190565b601881527f4e454741544956455f5350524541445f52455155495245440000000000000000602082015260400190565b601481527f494e56414c49445f54585f5349474e4154555245000000000000000000000000602082015260400190565b601181527f4c454e4754485f305f5245515549524544000000000000000000000000000000602082015260400190565b805160808301906153738482614c70565b5060208201516153866020850182614c70565b5060408201516153996040850182614c70565b5060608201516127a36060850182614c70565b80516101208301906153be8482615362565b5060208201516153d16080850182615362565b5060408201516127a3610100850182614c70565b805160608301906153f6848261541c565b5060208201516154096020850182614c70565b5060408201516127a36040850182614c70565b614c0a816158f6565b60208101612fbe8284614c01565b6101008101615442828b614c01565b61544f602083018a614c01565b61545c6040830189614c70565b6154696060830188614c70565b6154766080830187614c70565b61548360a0830186614c70565b81810360c08301526154958185614c82565b905081810360e08301526154a98184614c82565b9a9950505050505050505050565b606081016154c58286614c01565b81810360208301526154d78185614c82565b905081810360408301526154eb8184614c82565b95945050505050565b6020808252810161260a8184614c10565b60208101612fbe8284614c67565b60208101612fbe8284614c70565b6060810161552f8286614c70565b61553c6020830185614c01565b81810360408301526154eb8184614c82565b6040810161555c8285614c70565b818103602083015261344b8184614c82565b6080810161557c8287614c70565b615589602083018661541c565b6155966040830185614c70565b6154eb6060830184614c70565b604081016155b18285614c79565b61260a6020830184614c01565b6020808252810161260a8184614c82565b60208101612fbe8284614cb7565b60208082528101612fbe81614cc0565b60208082528101612fbe81614cf0565b60208082528101612fbe81614d20565b60208082528101612fbe81614d50565b60208082528101612fbe81614d80565b60208082528101612fbe81614db0565b60208082528101612fbe81614e06565b60208082528101612fbe81614e36565b60208082528101612fbe81614e66565b60208082528101612fbe81614e96565b60208082528101612fbe81614ec6565b60208082528101612fbe81614ef6565b60208082528101612fbe81614f26565b60208082528101612fbe81614f56565b60208082528101612fbe81614f86565b60208082528101612fbe81614fb6565b60208082528101612fbe81614fe6565b60208082528101612fbe81615016565b60208082528101612fbe81615046565b60208082528101612fbe8161509c565b60208082528101612fbe816150cc565b60208082528101612fbe816150fc565b60208082528101612fbe8161512c565b60208082528101612fbe8161515c565b60208082528101612fbe8161518c565b60208082528101612fbe816151bc565b60208082528101612fbe816151ec565b60208082528101612fbe8161521c565b60208082528101612fbe81615272565b60208082528101612fbe816152a2565b60208082528101612fbe816152d2565b60208082528101612fbe81615302565b60208082528101612fbe81615332565b60808101612fbe8284615362565b6101208101612fbe82846153ac565b60608101612fbe82846153e5565b60405181810167ffffffffffffffff8111828210171561583757600080fd5b604052919050565b600067ffffffffffffffff82111561585657600080fd5b5060209081020190565b600067ffffffffffffffff82111561587757600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b60200190565b5190565b73ffffffffffffffffffffffffffffffffffffffff1690565b151590565b90565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b60ff1690565b6000612fbe826158b0565b82818337506000910152565b60005b8381101561592e578181015183820152602001615916565b838111156127a35750506000910152565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016905600a265627a7a72305820d41ee66f45c4d1637cb6e5f109447c6d5d7fef3204a685dc442151c0f029b7da6c6578706572696d656e74616cf50037", - "storage": { - "0x1458d05345aa0372fb580f207529f32cbb6e9242890d36a93225785d4496083e": "0x0000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48" - } - }, - "0x5409ed021d9299bf6814279a6a1411a7e866a631": { - "balance": "0xac6bd1cc338c2000", - "nonce": "22", - "code": "0x", - "storage": {} - }, - "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c": { - "balance": "0x0", - "nonce": "1", - "code": "0x606060405236156100965763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610098578063095ea7b31461014657806318160ddd1461018657806323b872dd146101a8578063313ce567146101ee57806370a082311461021457806395d89b411461024f578063a9059cbb146102fd578063dd62ed3e1461033d575bfe5b34156100a057fe5b6100a861037e565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561014e57fe5b61017273ffffffffffffffffffffffffffffffffffffffff600435166024356103b5565b604080519115158252519081900360200190f35b341561018e57fe5b61019661042d565b60408051918252519081900360200190f35b34156101b057fe5b61017273ffffffffffffffffffffffffffffffffffffffff60043581169060243516604435610433565b604080519115158252519081900360200190f35b34156101f657fe5b6101fe6105d4565b6040805160ff9092168252519081900360200190f35b341561021c57fe5b61019673ffffffffffffffffffffffffffffffffffffffff600435166105d9565b60408051918252519081900360200190f35b341561025757fe5b6100a8610605565b60408051602080825283518183015283519192839290830191850190808383821561010c575b80518252602083111561010c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016100ce565b505050905090810190601f1680156101385780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561030557fe5b61017273ffffffffffffffffffffffffffffffffffffffff6004351660243561063c565b604080519115158252519081900360200190f35b341561034557fe5b61019673ffffffffffffffffffffffffffffffffffffffff60043581169060243516610727565b60408051918252519081900360200190f35b60408051808201909152601181527f30782050726f746f636f6c20546f6b656e000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff338116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b60035481565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832033909516835293815283822054928252819052918220548390108015906104835750828110155b80156104b6575073ffffffffffffffffffffffffffffffffffffffff841660009081526020819052604090205483810110155b156105c65773ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220805487019055918716815220805484900390557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8110156105585773ffffffffffffffffffffffffffffffffffffffff808616600090815260016020908152604080832033909416835292905220805484900390555b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3600191506105cb565b600091505b5b509392505050565b601281565b73ffffffffffffffffffffffffffffffffffffffff81166000908152602081905260409020545b919050565b60408051808201909152600381527f5a52580000000000000000000000000000000000000000000000000000000000602082015281565b73ffffffffffffffffffffffffffffffffffffffff3316600090815260208190526040812054829010801590610699575073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205482810110155b156107185773ffffffffffffffffffffffffffffffffffffffff33811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3506001610427565b506000610427565b5b92915050565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600160209081526040808320938516835292905220545b929150505600a165627a7a723058201b5b70cf82a73dec658c2e60ab9a0f8e2ba01a74b66a6f5b0402f56d2ea0ffcf0029", - "storage": { - "0xd37b858806ebf992fe75c1dd1a61cc7625ea52328d19005ba6b8b62506ae5306": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - } - }, - "config": { - "chainId": 5, - "supportedProtocolVersions": [ - 67, - 66 - ], - "homesteadBlock": 0, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 1561651, - "berlinBlock": 4460644, - "londonBlock": 5062605, - "terminalTotalDifficulty": 10790000, - "terminalTotalDifficultyPassed": true, - "clique": { - "period": 15, - "epoch": 30000 - }, - "trustedCheckpoint": { - "sectionIndex": 210, - "sectionHead": "0xbb11eaf551a6c06f74a6c7bbfe1699cbf64b8f248b64691da916dd443176db2f", - "chtRoot": "0x9934ae326d00d9c7de2e074c0e51689efb7fa7fcba18929ff4279c27259c45e6", - "bloomRoot": "0x7fe3bd4fd45194aa8a5cfe5ac590edff1f870d3d98d3c310494e7f67613a87ff" - }, - "trustedCheckpointOracle": { - "address": "0x18ca0e045f0d772a851bc7e48357bcaab0a0795d", - "signers": [ - "0x4769bcad07e3b938b7f43eb7d278bc7cb9effb38", - "0x78d1ad571a1a09d60d9bbf25894b44e4c8859595", - "0x286834935f4a8cfb4ff4c77d5770c2775ae2b0e7", - "0xb86e2b0ab5a4b1373e40c51a7c712c70ba2f9f8e", - "0x0df8fa387c602ae62559cc4afa4972a7045d6707" - ], - "threshold": 2 - } - } - }, - "context": { - "number": "13536", - "difficulty": "1", - "timestamp": "1549153018", - "gasLimit": "8000000", - "miner": "0x0000000000000000000000000000000000000000", - "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e" - }, - "input": "0xf92e9e1684ee6b2800832c8c7f8080b92e4c60806040523480156200001157600080fd5b5060405162002d2c38038062002d2c83398101806040526200003791908101906200051d565b6000805433600160a060020a031991821617825560018054909116600160a060020a0386161790558251849084908490849081906200007e906004906020870190620003d0565b50825162000094906005906020860190620003d0565b50620000b0836010640100000000620019476200036f82021704565b9150620000cd846010640100000000620019476200036f82021704565b60028054600160a060020a03948516600160a060020a031991821617909155600380549285169290911691909117905550600154604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130181207f6070410800000000000000000000000000000000000000000000000000000000825291909216945063607041089350620001739250906004016200068e565b602060405180830381600087803b1580156200018e57600080fd5b505af1158015620001a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620001c99190810190620004f4565b9050600160a060020a038116151562000219576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021090620006b0565b60405180910390fd5b6002546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b39062000268908490600019906004016200066f565b602060405180830381600087803b1580156200028357600080fd5b505af115801562000298573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620002be9190810190620005a1565b506003546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b3906200030e908490600019906004016200066f565b602060405180830381600087803b1580156200032957600080fd5b505af11580156200033e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620003649190810190620005a1565b50505050506200077a565b600081601401835110151515620003b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000210906200069e565b506014818301810151910190600160a060020a03165b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200041357805160ff191683800117855562000443565b8280016001018555821562000443579182015b828111156200044357825182559160200191906001019062000426565b506200045192915062000455565b5090565b6200047291905b808211156200045157600081556001016200045c565b90565b600062000483825162000711565b9392505050565b600062000483825162000742565b6000601f82018313620004aa57600080fd5b8151620004c1620004bb82620006e9565b620006c2565b91508082526020830160208301858383011115620004de57600080fd5b620004eb83828462000747565b50505092915050565b6000602082840312156200050757600080fd5b600062000515848462000475565b949350505050565b6000806000606084860312156200053357600080fd5b600062000541868662000475565b93505060208401516001604060020a038111156200055e57600080fd5b6200056c8682870162000498565b92505060408401516001604060020a038111156200058957600080fd5b620005978682870162000498565b9150509250925092565b600060208284031215620005b457600080fd5b60006200051584846200048a565b620005cd8162000711565b82525050565b620005cd816200071d565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601881527f554e524547495354455245445f41535345545f50524f58590000000000000000602082015260400190565b620005cd8162000472565b604081016200067f8285620005c2565b62000483602083018462000664565b60208101620003ca8284620005d3565b60208082528101620003ca81620005de565b60208082528101620003ca8162000634565b6040518181016001604060020a0381118282101715620006e157600080fd5b604052919050565b60006001604060020a038211156200070057600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b151590565b60005b83811015620007645781810151838201526020016200074a565b8381111562000774576000848401525b50505050565b6125a2806200078a6000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318978e8281146100c8578063630f1e6c146100f25780638da5cb5b146101125780639395525c14610134578063f2fde38b14610147575b60025473ffffffffffffffffffffffffffffffffffffffff1633146100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612388565b60405180910390fd5b005b6100db6100d6366004611df1565b610167565b6040516100e9929190612488565b60405180910390f35b3480156100fe57600080fd5b506100c661010d366004611eec565b6102f7565b34801561011e57600080fd5b50610127610388565b6040516100e99190612337565b6100db610142366004611d0b565b6103a4565b34801561015357600080fd5b506100c6610162366004611ce5565b61050a565b61016f6119fa565b6101776119fa565b6000806101826105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815261025c939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b50505050508c600081518110151561024157fe5b6020908102909101015161014001519063ffffffff61069616565b156102875761026c8b8b8b6107c3565b935061028084600001518560600151610ac1565b90506102ae565b6102928b8b8b610b03565b9350836060015191506102a68883896107c3565b845190935090505b6102c2846020015184602001518888610d15565b6102e98b60008151811015156102d457fe5b90602001906020020151610140015182610f29565b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610348576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b61038383838080601f01602080910402602001604051908101604052809392919081815260200183838082843750879450610f299350505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6103ac6119fa565b6103b46119fa565b60008060006103c16105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152610441939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b156104925761046a670de0b6b3a7640000610464670de0b6b3a76400008a611045565b3461108f565b92506104778b848c6110e7565b945061048b85600001518660600151610ac1565b90506104d6565b6104ad670d2f13f7789f0000670de0b6b3a76400003461108f565b92506104ba8b848c6110e7565b9450846060015191506104ce89838a6107c3565b855190945090505b6104ea856020015185602001518989610d15565b6104fc8b60008151811015156102d457fe5b505050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b73ffffffffffffffffffffffffffffffffffffffff8116156105b857600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600034116105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612398565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b5050505050565b6000815183511480156107ba5750816040518082805190602001908083835b602083106106f257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016106b5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b6020831061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161074a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b90505b92915050565b6107cb6119fa565b60608060008060008060006107de6119fa565b8a15156107ea57610ab2565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561088e5780601f106108635761010080835404028352916020019161088e565b820191906000526020600020905b81548152906001019060200180831161087157829003601f168201915b505060058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152969e509194509250840190508282801561093d5780601f106109125761010080835404028352916020019161093d565b820191906000526020600020905b81548152906001019060200180831161092057829003601f168201915b50505050509650600095508b519450600093505b838514610a7857878c8581518110151561096757fe5b6020908102909101015161014001528b5187908d908690811061098657fe5b60209081029091010151610160015261099f8b87610ac1565b9250610a068c858151811015156109b257fe5b9060200190602002015160a00151610a008e878151811015156109d157fe5b90602001906020020151608001518f888151811015156109ed57fe5b9060200190602002015160e00151610ac1565b8561128b565b9150610a418c85815181101515610a1957fe5b90602001906020020151838c87815181101515610a3257fe5b906020019060200201516112e6565b9050610a4d898261135e565b610a5f89600001518a60600151610ac1565b95508a8610610a6d57610a78565b600190930192610951565b8a861015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b50505050505050509392505050565b600082821115610afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123b8565b50900390565b610b0b6119fa565b606080600080600080610b1c6119fa565b60008b6000815181101515610b2d57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929b5092909190830182828015610be55780601f10610bba57610100808354040283529160200191610be5565b820191906000526020600020905b815481529060010190602001808311610bc857829003601f168201915b505050505096508b519550600094505b848614610cdb57878c86815181101515610c0b57fe5b6020908102909101015161014001528b5187908d9087908110610c2a57fe5b6020908102909101015161016001528851610c46908c90610ac1565b9350610c898c86815181101515610c5957fe5b9060200190602002015160a001518d87815181101515610c7557fe5b90602001906020020151608001518661128b565b9250610cb58c86815181101515610c9c57fe5b90602001906020020151848c88815181101515610a3257fe5b9150610cc1898361135e565b5087518a8110610cd057610cdb565b600190940193610bf5565b8a811015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b600080808066b1a2bc2ec50000861115610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612448565b610d658888611045565b935034841115610da1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123a8565b610dab3485610ac1565b9250610dc086670de0b6b3a76400008a61108f565b915082821115610dfc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612428565b6000831115610f1f576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90610e5b9086906004016124a4565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b505050506000821115610edb5760405173ffffffffffffffffffffffffffffffffffffffff86169083156108fc029084906000818181858888f19350505050158015610ed9573d6000803e3d6000fd5b505b610ee58383610ac1565b90506000811115610f1f57604051339082156108fc029083906000818181858888f19350505050158015610f1d573d6000803e3d6000fd5b505b5050505050505050565b6000610f3b838263ffffffff6113c016565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff0000000000000000000000000000000000000000000000000000000080831691161415610fab57610fa6838361142d565b610383565b604080517f455243373231546f6b656e28616464726573732c75696e7432353629000000008152905190819003601c0190207fffffffff000000000000000000000000000000000000000000000000000000008281169116141561101357610fa6838361161b565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123f8565b600082820183811015611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b8091505b5092915050565b60008083116110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d78584611703565b8461175e565b90505b9392505050565b6110ef6119fa565b60608060008060006110ff6119fa565b89600081518110151561110e57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929950929091908301828280156111c65780601f1061119b576101008083540402835291602001916111c6565b820191906000526020600020905b8154815290600101906020018083116111a957829003601f168201915b5050505050945089519350600092505b82841461127e57858a848151811015156111ec57fe5b602090810290910101516101400152895185908b908590811061120b57fe5b90602001906020020151610160018190525061122b898860200151610ac1565b91506112578a8481518110151561123e57fe5b90602001906020020151838a86815181101515610a3257fe5b9050611263878261135e565b602087015189116112735761127e565b6001909201916111d6565b5050505050509392505050565b60008083116112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d76112d68685611703565b6112e1866001610ac1565b611045565b6112ee6119fa565b606060006112fd868686611775565b600154815191935073ffffffffffffffffffffffffffffffffffffffff1691506080908390602082016000855af1801561135457825184526020830151602085015260408301516040850152606083015160608501525b5050509392505050565b8151815161136c9190611045565b8252602080830151908201516113829190611045565b60208301526040808301519082015161139b9190611045565b6040830152606080830151908201516113b49190611045565b60609092019190915250565b600081600401835110151515611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612468565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b60008061144184601063ffffffff61194716565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812091935073ffffffffffffffffffffffffffffffffffffffff8416919061149f903390879060240161236d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b8381101561154357818101518382015260200161152b565b50505050905090810190601f1680156115705780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1925050508015156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b3d156115dc575060003d602014156115dc5760206000803e506000515b801515611615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b50505050565b60008060018314611658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612478565b61166984601063ffffffff61194716565b915061167c84602463ffffffff6119a816565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906116d590309033908690600401612345565b600060405180830381600087803b1580156116ef57600080fd5b505af1158015610f1f573d6000803e3d6000fd5b6000808315156117165760009150611088565b5082820282848281151561172657fe5b0414611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b600080828481151561176c57fe5b04949350505050565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b8181101561187c57835185526020948501949093019260010161185e565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b818110156118c55783518552602094850194909301926001016118a7565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b8181101561190d5783518552602094850194909301926001016118ef565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b600081601401835110151515611989576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612458565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006107ba83836000816020018351101515156119f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123c8565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006107ba8235612540565b6000601f82018313611a4057600080fd5b8135611a53611a4e826124d9565b6124b2565b81815260209384019390925082018360005b83811015611a915781358601611a7b8882611b41565b8452506020928301929190910190600101611a65565b5050505092915050565b6000601f82018313611aac57600080fd5b8135611aba611a4e826124d9565b81815260209384019390925082018360005b83811015611a915781358601611ae28882611b90565b8452506020928301929190910190600101611acc565b600080601f83018413611b0a57600080fd5b50813567ffffffffffffffff811115611b2257600080fd5b602083019150836001820283011115611b3a57600080fd5b9250929050565b6000601f82018313611b5257600080fd5b8135611b60611a4e826124fa565b91508082526020830160208301858383011115611b7c57600080fd5b611b8783828461255c565b50505092915050565b60006101808284031215611ba357600080fd5b611bae6101806124b2565b90506000611bbc8484611a23565b8252506020611bcd84848301611a23565b6020830152506040611be184828501611a23565b6040830152506060611bf584828501611a23565b6060830152506080611c0984828501611cd9565b60808301525060a0611c1d84828501611cd9565b60a08301525060c0611c3184828501611cd9565b60c08301525060e0611c4584828501611cd9565b60e083015250610100611c5a84828501611cd9565b61010083015250610120611c7084828501611cd9565b6101208301525061014082013567ffffffffffffffff811115611c9257600080fd5b611c9e84828501611b41565b6101408301525061016082013567ffffffffffffffff811115611cc057600080fd5b611ccc84828501611b41565b6101608301525092915050565b60006107ba8235612559565b600060208284031215611cf757600080fd5b6000611d038484611a23565b949350505050565b60008060008060008060c08789031215611d2457600080fd5b863567ffffffffffffffff811115611d3b57600080fd5b611d4789828a01611a9b565b965050602087013567ffffffffffffffff811115611d6457600080fd5b611d7089828a01611a2f565b955050604087013567ffffffffffffffff811115611d8d57600080fd5b611d9989828a01611a9b565b945050606087013567ffffffffffffffff811115611db657600080fd5b611dc289828a01611a2f565b9350506080611dd389828a01611cd9565b92505060a0611de489828a01611a23565b9150509295509295509295565b600080600080600080600060e0888a031215611e0c57600080fd5b873567ffffffffffffffff811115611e2357600080fd5b611e2f8a828b01611a9b565b9750506020611e408a828b01611cd9565b965050604088013567ffffffffffffffff811115611e5d57600080fd5b611e698a828b01611a2f565b955050606088013567ffffffffffffffff811115611e8657600080fd5b611e928a828b01611a9b565b945050608088013567ffffffffffffffff811115611eaf57600080fd5b611ebb8a828b01611a2f565b93505060a0611ecc8a828b01611cd9565b92505060c0611edd8a828b01611a23565b91505092959891949750929550565b600080600060408486031215611f0157600080fd5b833567ffffffffffffffff811115611f1857600080fd5b611f2486828701611af8565b93509350506020611f3786828701611cd9565b9150509250925092565b611f4a81612540565b82525050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b600d81527f4f564552534f4c445f5745544800000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601781527f554e535550504f525445445f41535345545f50524f5859000000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601a81527f494e53554646494349454e545f4554485f52454d41494e494e47000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b601881527f4645455f50455243454e544147455f544f4f5f4c415247450000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160808301906122f9848261232e565b50602082015161230c602085018261232e565b50604082015161231f604085018261232e565b50606082015161161560608501825b611f4a81612559565b602081016107bd8284611f41565b606081016123538286611f41565b6123606020830185611f41565b611d03604083018461232e565b6040810161237b8285611f41565b6110e0602083018461232e565b602080825281016107bd81611f50565b602080825281016107bd81611fa6565b602080825281016107bd81611fd6565b602080825281016107bd81612006565b602080825281016107bd81612036565b602080825281016107bd8161208c565b602080825281016107bd816120bc565b602080825281016107bd816120ec565b602080825281016107bd8161211c565b602080825281016107bd8161214c565b602080825281016107bd8161217c565b602080825281016107bd816121ac565b602080825281016107bd816121dc565b602080825281016107bd8161220c565b602080825281016107bd81612262565b602080825281016107bd816122b8565b610100810161249782856122e8565b6110e060808301846122e8565b602081016107bd828461232e565b60405181810167ffffffffffffffff811182821017156124d157600080fd5b604052919050565b600067ffffffffffffffff8211156124f057600080fd5b5060209081020190565b600067ffffffffffffffff82111561251157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b828183375060009101525600a265627a7a72305820d9f418f11e0f91f06f6f9d22924be0add925495eeb76a6388b5417adb505eeb36c6578706572696d656e74616cf5003700000000000000000000000048bacb9266a570d521063ef5dd96e61686dbe788000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e8082000000000000000000000000000000000000000000000000000000001ba0a7c6b0c9a5cb47eb4a8449556851a943353640d4fe93a64eb89eff56245c27f1a00e0d13877bfb8842dc394fd206d041b1f76be95a371eff128c8c34812a1b24c8", - "result": [ - { - "action": { - "from": "0x5409ed021d9299bf6814279a6a1411a7e866a631", - "gas": "0x2c8c7f", - "init": "0x60806040523480156200001157600080fd5b5060405162002d2c38038062002d2c83398101806040526200003791908101906200051d565b6000805433600160a060020a031991821617825560018054909116600160a060020a0386161790558251849084908490849081906200007e906004906020870190620003d0565b50825162000094906005906020860190620003d0565b50620000b0836010640100000000620019476200036f82021704565b9150620000cd846010640100000000620019476200036f82021704565b60028054600160a060020a03948516600160a060020a031991821617909155600380549285169290911691909117905550600154604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130181207f6070410800000000000000000000000000000000000000000000000000000000825291909216945063607041089350620001739250906004016200068e565b602060405180830381600087803b1580156200018e57600080fd5b505af1158015620001a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620001c99190810190620004f4565b9050600160a060020a038116151562000219576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021090620006b0565b60405180910390fd5b6002546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b39062000268908490600019906004016200066f565b602060405180830381600087803b1580156200028357600080fd5b505af115801562000298573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620002be9190810190620005a1565b506003546040517f095ea7b3000000000000000000000000000000000000000000000000000000008152600160a060020a039091169063095ea7b3906200030e908490600019906004016200066f565b602060405180830381600087803b1580156200032957600080fd5b505af11580156200033e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250620003649190810190620005a1565b50505050506200077a565b600081601401835110151515620003b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000210906200069e565b506014818301810151910190600160a060020a03165b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200041357805160ff191683800117855562000443565b8280016001018555821562000443579182015b828111156200044357825182559160200191906001019062000426565b506200045192915062000455565b5090565b6200047291905b808211156200045157600081556001016200045c565b90565b600062000483825162000711565b9392505050565b600062000483825162000742565b6000601f82018313620004aa57600080fd5b8151620004c1620004bb82620006e9565b620006c2565b91508082526020830160208301858383011115620004de57600080fd5b620004eb83828462000747565b50505092915050565b6000602082840312156200050757600080fd5b600062000515848462000475565b949350505050565b6000806000606084860312156200053357600080fd5b600062000541868662000475565b93505060208401516001604060020a038111156200055e57600080fd5b6200056c8682870162000498565b92505060408401516001604060020a038111156200058957600080fd5b620005978682870162000498565b9150509250925092565b600060208284031215620005b457600080fd5b60006200051584846200048a565b620005cd8162000711565b82525050565b620005cd816200071d565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601881527f554e524547495354455245445f41535345545f50524f58590000000000000000602082015260400190565b620005cd8162000472565b604081016200067f8285620005c2565b62000483602083018462000664565b60208101620003ca8284620005d3565b60208082528101620003ca81620005de565b60208082528101620003ca8162000634565b6040518181016001604060020a0381118282101715620006e157600080fd5b604052919050565b60006001604060020a038211156200070057600080fd5b506020601f91909101601f19160190565b600160a060020a031690565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b151590565b60005b83811015620007645781810151838201526020016200074a565b8381111562000774576000848401525b50505050565b6125a2806200078a6000396000f30060806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318978e8281146100c8578063630f1e6c146100f25780638da5cb5b146101125780639395525c14610134578063f2fde38b14610147575b60025473ffffffffffffffffffffffffffffffffffffffff1633146100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612388565b60405180910390fd5b005b6100db6100d6366004611df1565b610167565b6040516100e9929190612488565b60405180910390f35b3480156100fe57600080fd5b506100c661010d366004611eec565b6102f7565b34801561011e57600080fd5b50610127610388565b6040516100e99190612337565b6100db610142366004611d0b565b6103a4565b34801561015357600080fd5b506100c6610162366004611ce5565b61050a565b61016f6119fa565b6101776119fa565b6000806101826105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815261025c939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b50505050508c600081518110151561024157fe5b6020908102909101015161014001519063ffffffff61069616565b156102875761026c8b8b8b6107c3565b935061028084600001518560600151610ac1565b90506102ae565b6102928b8b8b610b03565b9350836060015191506102a68883896107c3565b845190935090505b6102c2846020015184602001518888610d15565b6102e98b60008151811015156102d457fe5b90602001906020020151610140015182610f29565b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610348576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b61038383838080601f01602080910402602001604051908101604052809392919081815260200183838082843750879450610f299350505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6103ac6119fa565b6103b46119fa565b60008060006103c16105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152610441939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b156104925761046a670de0b6b3a7640000610464670de0b6b3a76400008a611045565b3461108f565b92506104778b848c6110e7565b945061048b85600001518660600151610ac1565b90506104d6565b6104ad670d2f13f7789f0000670de0b6b3a76400003461108f565b92506104ba8b848c6110e7565b9450846060015191506104ce89838a6107c3565b855190945090505b6104ea856020015185602001518989610d15565b6104fc8b60008151811015156102d457fe5b505050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b73ffffffffffffffffffffffffffffffffffffffff8116156105b857600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600034116105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612398565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b5050505050565b6000815183511480156107ba5750816040518082805190602001908083835b602083106106f257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016106b5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b6020831061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161074a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b90505b92915050565b6107cb6119fa565b60608060008060008060006107de6119fa565b8a15156107ea57610ab2565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561088e5780601f106108635761010080835404028352916020019161088e565b820191906000526020600020905b81548152906001019060200180831161087157829003601f168201915b505060058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152969e509194509250840190508282801561093d5780601f106109125761010080835404028352916020019161093d565b820191906000526020600020905b81548152906001019060200180831161092057829003601f168201915b50505050509650600095508b519450600093505b838514610a7857878c8581518110151561096757fe5b6020908102909101015161014001528b5187908d908690811061098657fe5b60209081029091010151610160015261099f8b87610ac1565b9250610a068c858151811015156109b257fe5b9060200190602002015160a00151610a008e878151811015156109d157fe5b90602001906020020151608001518f888151811015156109ed57fe5b9060200190602002015160e00151610ac1565b8561128b565b9150610a418c85815181101515610a1957fe5b90602001906020020151838c87815181101515610a3257fe5b906020019060200201516112e6565b9050610a4d898261135e565b610a5f89600001518a60600151610ac1565b95508a8610610a6d57610a78565b600190930192610951565b8a861015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b50505050505050509392505050565b600082821115610afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123b8565b50900390565b610b0b6119fa565b606080600080600080610b1c6119fa565b60008b6000815181101515610b2d57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929b5092909190830182828015610be55780601f10610bba57610100808354040283529160200191610be5565b820191906000526020600020905b815481529060010190602001808311610bc857829003601f168201915b505050505096508b519550600094505b848614610cdb57878c86815181101515610c0b57fe5b6020908102909101015161014001528b5187908d9087908110610c2a57fe5b6020908102909101015161016001528851610c46908c90610ac1565b9350610c898c86815181101515610c5957fe5b9060200190602002015160a001518d87815181101515610c7557fe5b90602001906020020151608001518661128b565b9250610cb58c86815181101515610c9c57fe5b90602001906020020151848c88815181101515610a3257fe5b9150610cc1898361135e565b5087518a8110610cd057610cdb565b600190940193610bf5565b8a811015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b600080808066b1a2bc2ec50000861115610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612448565b610d658888611045565b935034841115610da1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123a8565b610dab3485610ac1565b9250610dc086670de0b6b3a76400008a61108f565b915082821115610dfc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612428565b6000831115610f1f576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90610e5b9086906004016124a4565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b505050506000821115610edb5760405173ffffffffffffffffffffffffffffffffffffffff86169083156108fc029084906000818181858888f19350505050158015610ed9573d6000803e3d6000fd5b505b610ee58383610ac1565b90506000811115610f1f57604051339082156108fc029083906000818181858888f19350505050158015610f1d573d6000803e3d6000fd5b505b5050505050505050565b6000610f3b838263ffffffff6113c016565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff0000000000000000000000000000000000000000000000000000000080831691161415610fab57610fa6838361142d565b610383565b604080517f455243373231546f6b656e28616464726573732c75696e7432353629000000008152905190819003601c0190207fffffffff000000000000000000000000000000000000000000000000000000008281169116141561101357610fa6838361161b565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123f8565b600082820183811015611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b8091505b5092915050565b60008083116110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d78584611703565b8461175e565b90505b9392505050565b6110ef6119fa565b60608060008060006110ff6119fa565b89600081518110151561110e57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929950929091908301828280156111c65780601f1061119b576101008083540402835291602001916111c6565b820191906000526020600020905b8154815290600101906020018083116111a957829003601f168201915b5050505050945089519350600092505b82841461127e57858a848151811015156111ec57fe5b602090810290910101516101400152895185908b908590811061120b57fe5b90602001906020020151610160018190525061122b898860200151610ac1565b91506112578a8481518110151561123e57fe5b90602001906020020151838a86815181101515610a3257fe5b9050611263878261135e565b602087015189116112735761127e565b6001909201916111d6565b5050505050509392505050565b60008083116112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d76112d68685611703565b6112e1866001610ac1565b611045565b6112ee6119fa565b606060006112fd868686611775565b600154815191935073ffffffffffffffffffffffffffffffffffffffff1691506080908390602082016000855af1801561135457825184526020830151602085015260408301516040850152606083015160608501525b5050509392505050565b8151815161136c9190611045565b8252602080830151908201516113829190611045565b60208301526040808301519082015161139b9190611045565b6040830152606080830151908201516113b49190611045565b60609092019190915250565b600081600401835110151515611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612468565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b60008061144184601063ffffffff61194716565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812091935073ffffffffffffffffffffffffffffffffffffffff8416919061149f903390879060240161236d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b8381101561154357818101518382015260200161152b565b50505050905090810190601f1680156115705780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1925050508015156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b3d156115dc575060003d602014156115dc5760206000803e506000515b801515611615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b50505050565b60008060018314611658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612478565b61166984601063ffffffff61194716565b915061167c84602463ffffffff6119a816565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906116d590309033908690600401612345565b600060405180830381600087803b1580156116ef57600080fd5b505af1158015610f1f573d6000803e3d6000fd5b6000808315156117165760009150611088565b5082820282848281151561172657fe5b0414611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b600080828481151561176c57fe5b04949350505050565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b8181101561187c57835185526020948501949093019260010161185e565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b818110156118c55783518552602094850194909301926001016118a7565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b8181101561190d5783518552602094850194909301926001016118ef565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b600081601401835110151515611989576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612458565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006107ba83836000816020018351101515156119f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123c8565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006107ba8235612540565b6000601f82018313611a4057600080fd5b8135611a53611a4e826124d9565b6124b2565b81815260209384019390925082018360005b83811015611a915781358601611a7b8882611b41565b8452506020928301929190910190600101611a65565b5050505092915050565b6000601f82018313611aac57600080fd5b8135611aba611a4e826124d9565b81815260209384019390925082018360005b83811015611a915781358601611ae28882611b90565b8452506020928301929190910190600101611acc565b600080601f83018413611b0a57600080fd5b50813567ffffffffffffffff811115611b2257600080fd5b602083019150836001820283011115611b3a57600080fd5b9250929050565b6000601f82018313611b5257600080fd5b8135611b60611a4e826124fa565b91508082526020830160208301858383011115611b7c57600080fd5b611b8783828461255c565b50505092915050565b60006101808284031215611ba357600080fd5b611bae6101806124b2565b90506000611bbc8484611a23565b8252506020611bcd84848301611a23565b6020830152506040611be184828501611a23565b6040830152506060611bf584828501611a23565b6060830152506080611c0984828501611cd9565b60808301525060a0611c1d84828501611cd9565b60a08301525060c0611c3184828501611cd9565b60c08301525060e0611c4584828501611cd9565b60e083015250610100611c5a84828501611cd9565b61010083015250610120611c7084828501611cd9565b6101208301525061014082013567ffffffffffffffff811115611c9257600080fd5b611c9e84828501611b41565b6101408301525061016082013567ffffffffffffffff811115611cc057600080fd5b611ccc84828501611b41565b6101608301525092915050565b60006107ba8235612559565b600060208284031215611cf757600080fd5b6000611d038484611a23565b949350505050565b60008060008060008060c08789031215611d2457600080fd5b863567ffffffffffffffff811115611d3b57600080fd5b611d4789828a01611a9b565b965050602087013567ffffffffffffffff811115611d6457600080fd5b611d7089828a01611a2f565b955050604087013567ffffffffffffffff811115611d8d57600080fd5b611d9989828a01611a9b565b945050606087013567ffffffffffffffff811115611db657600080fd5b611dc289828a01611a2f565b9350506080611dd389828a01611cd9565b92505060a0611de489828a01611a23565b9150509295509295509295565b600080600080600080600060e0888a031215611e0c57600080fd5b873567ffffffffffffffff811115611e2357600080fd5b611e2f8a828b01611a9b565b9750506020611e408a828b01611cd9565b965050604088013567ffffffffffffffff811115611e5d57600080fd5b611e698a828b01611a2f565b955050606088013567ffffffffffffffff811115611e8657600080fd5b611e928a828b01611a9b565b945050608088013567ffffffffffffffff811115611eaf57600080fd5b611ebb8a828b01611a2f565b93505060a0611ecc8a828b01611cd9565b92505060c0611edd8a828b01611a23565b91505092959891949750929550565b600080600060408486031215611f0157600080fd5b833567ffffffffffffffff811115611f1857600080fd5b611f2486828701611af8565b93509350506020611f3786828701611cd9565b9150509250925092565b611f4a81612540565b82525050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b600d81527f4f564552534f4c445f5745544800000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601781527f554e535550504f525445445f41535345545f50524f5859000000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601a81527f494e53554646494349454e545f4554485f52454d41494e494e47000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b601881527f4645455f50455243454e544147455f544f4f5f4c415247450000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160808301906122f9848261232e565b50602082015161230c602085018261232e565b50604082015161231f604085018261232e565b50606082015161161560608501825b611f4a81612559565b602081016107bd8284611f41565b606081016123538286611f41565b6123606020830185611f41565b611d03604083018461232e565b6040810161237b8285611f41565b6110e0602083018461232e565b602080825281016107bd81611f50565b602080825281016107bd81611fa6565b602080825281016107bd81611fd6565b602080825281016107bd81612006565b602080825281016107bd81612036565b602080825281016107bd8161208c565b602080825281016107bd816120bc565b602080825281016107bd816120ec565b602080825281016107bd8161211c565b602080825281016107bd8161214c565b602080825281016107bd8161217c565b602080825281016107bd816121ac565b602080825281016107bd816121dc565b602080825281016107bd8161220c565b602080825281016107bd81612262565b602080825281016107bd816122b8565b610100810161249782856122e8565b6110e060808301846122e8565b602081016107bd828461232e565b60405181810167ffffffffffffffff811182821017156124d157600080fd5b604052919050565b600067ffffffffffffffff8211156124f057600080fd5b5060209081020190565b600067ffffffffffffffff82111561251157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b828183375060009101525600a265627a7a72305820d9f418f11e0f91f06f6f9d22924be0add925495eeb76a6388b5417adb505eeb36c6578706572696d656e74616cf5003700000000000000000000000048bacb9266a570d521063ef5dd96e61686dbe788000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000024f47261b0000000000000000000000000871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f47261b00000000000000000000000000b1ba0af832d7c05fd64161e0db78e85978e808200000000000000000000000000000000000000000000000000000000", - "value": "0x0" - }, - "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8", - "blockNumber": 13536, - "result": { - "address": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414", - "code": "0x60806040526004361061006c5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166318978e8281146100c8578063630f1e6c146100f25780638da5cb5b146101125780639395525c14610134578063f2fde38b14610147575b60025473ffffffffffffffffffffffffffffffffffffffff1633146100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612388565b60405180910390fd5b005b6100db6100d6366004611df1565b610167565b6040516100e9929190612488565b60405180910390f35b3480156100fe57600080fd5b506100c661010d366004611eec565b6102f7565b34801561011e57600080fd5b50610127610388565b6040516100e99190612337565b6100db610142366004611d0b565b6103a4565b34801561015357600080fd5b506100c6610162366004611ce5565b61050a565b61016f6119fa565b6101776119fa565b6000806101826105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815261025c939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b820191906000526020600020905b81548152906001019060200180831161021057829003601f168201915b50505050508c600081518110151561024157fe5b6020908102909101015161014001519063ffffffff61069616565b156102875761026c8b8b8b6107c3565b935061028084600001518560600151610ac1565b90506102ae565b6102928b8b8b610b03565b9350836060015191506102a68883896107c3565b845190935090505b6102c2846020015184602001518888610d15565b6102e98b60008151811015156102d457fe5b90602001906020020151610140015182610f29565b505097509795505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610348576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b61038383838080601f01602080910402602001604051908101604052809392919081815260200183838082843750879450610f299350505050565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b6103ac6119fa565b6103b46119fa565b60008060006103c16105bb565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152610441939092909183018282801561022d5780601f106102025761010080835404028352916020019161022d565b156104925761046a670de0b6b3a7640000610464670de0b6b3a76400008a611045565b3461108f565b92506104778b848c6110e7565b945061048b85600001518660600151610ac1565b90506104d6565b6104ad670d2f13f7789f0000670de0b6b3a76400003461108f565b92506104ba8b848c6110e7565b9450846060015191506104ce89838a6107c3565b855190945090505b6104ea856020015185602001518989610d15565b6104fc8b60008151811015156102d457fe5b505050965096945050505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461055b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612438565b73ffffffffffffffffffffffffffffffffffffffff8116156105b857600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83161790555b50565b600034116105f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612398565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004016000604051808303818588803b15801561067b57600080fd5b505af115801561068f573d6000803e3d6000fd5b5050505050565b6000815183511480156107ba5750816040518082805190602001908083835b602083106106f257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016106b5565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0180199092169116179052604051919093018190038120885190955088945090928392508401908083835b6020831061078757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161074a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b90505b92915050565b6107cb6119fa565b60608060008060008060006107de6119fa565b8a15156107ea57610ab2565b6004805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561088e5780601f106108635761010080835404028352916020019161088e565b820191906000526020600020905b81548152906001019060200180831161087157829003601f168201915b505060058054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6101006001881615020190951694909404938401819004810282018101909252828152969e509194509250840190508282801561093d5780601f106109125761010080835404028352916020019161093d565b820191906000526020600020905b81548152906001019060200180831161092057829003601f168201915b50505050509650600095508b519450600093505b838514610a7857878c8581518110151561096757fe5b6020908102909101015161014001528b5187908d908690811061098657fe5b60209081029091010151610160015261099f8b87610ac1565b9250610a068c858151811015156109b257fe5b9060200190602002015160a00151610a008e878151811015156109d157fe5b90602001906020020151608001518f888151811015156109ed57fe5b9060200190602002015160e00151610ac1565b8561128b565b9150610a418c85815181101515610a1957fe5b90602001906020020151838c87815181101515610a3257fe5b906020019060200201516112e6565b9050610a4d898261135e565b610a5f89600001518a60600151610ac1565b95508a8610610a6d57610a78565b600190930192610951565b8a861015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b50505050505050509392505050565b600082821115610afd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123b8565b50900390565b610b0b6119fa565b606080600080600080610b1c6119fa565b60008b6000815181101515610b2d57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929b5092909190830182828015610be55780601f10610bba57610100808354040283529160200191610be5565b820191906000526020600020905b815481529060010190602001808311610bc857829003601f168201915b505050505096508b519550600094505b848614610cdb57878c86815181101515610c0b57fe5b6020908102909101015161014001528b5187908d9087908110610c2a57fe5b6020908102909101015161016001528851610c46908c90610ac1565b9350610c898c86815181101515610c5957fe5b9060200190602002015160a001518d87815181101515610c7557fe5b90602001906020020151608001518661128b565b9250610cb58c86815181101515610c9c57fe5b90602001906020020151848c88815181101515610a3257fe5b9150610cc1898361135e565b5087518a8110610cd057610cdb565b600190940193610bf5565b8a811015610ab2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612418565b600080808066b1a2bc2ec50000861115610d5b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612448565b610d658888611045565b935034841115610da1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123a8565b610dab3485610ac1565b9250610dc086670de0b6b3a76400008a61108f565b915082821115610dfc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612428565b6000831115610f1f576002546040517f2e1a7d4d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690632e1a7d4d90610e5b9086906004016124a4565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b505050506000821115610edb5760405173ffffffffffffffffffffffffffffffffffffffff86169083156108fc029084906000818181858888f19350505050158015610ed9573d6000803e3d6000fd5b505b610ee58383610ac1565b90506000811115610f1f57604051339082156108fc029083906000818181858888f19350505050158015610f1d573d6000803e3d6000fd5b505b5050505050505050565b6000610f3b838263ffffffff6113c016565b604080517f4552433230546f6b656e28616464726573732900000000000000000000000000815290519081900360130190209091507fffffffff0000000000000000000000000000000000000000000000000000000080831691161415610fab57610fa6838361142d565b610383565b604080517f455243373231546f6b656e28616464726573732c75696e7432353629000000008152905190819003601c0190207fffffffff000000000000000000000000000000000000000000000000000000008281169116141561101357610fa6838361161b565b6040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123f8565b600082820183811015611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b8091505b5092915050565b60008083116110ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d78584611703565b8461175e565b90505b9392505050565b6110ef6119fa565b60608060008060006110ff6119fa565b89600081518110151561110e57fe5b6020908102919091018101516101400151600580546040805160026001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190931692909204601f8101869004860283018601909152808252929950929091908301828280156111c65780601f1061119b576101008083540402835291602001916111c6565b820191906000526020600020905b8154815290600101906020018083116111a957829003601f168201915b5050505050945089519350600092505b82841461127e57858a848151811015156111ec57fe5b602090810290910101516101400152895185908b908590811061120b57fe5b90602001906020020151610160018190525061122b898860200151610ac1565b91506112578a8481518110151561123e57fe5b90602001906020020151838a86815181101515610a3257fe5b9050611263878261135e565b602087015189116112735761127e565b6001909201916111d6565b5050505050509392505050565b60008083116112c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123d8565b6110dd6110d76112d68685611703565b6112e1866001610ac1565b611045565b6112ee6119fa565b606060006112fd868686611775565b600154815191935073ffffffffffffffffffffffffffffffffffffffff1691506080908390602082016000855af1801561135457825184526020830151602085015260408301516040850152606083015160608501525b5050509392505050565b8151815161136c9190611045565b8252602080830151908201516113829190611045565b60208301526040808301519082015161139b9190611045565b6040830152606080830151908201516113b49190611045565b60609092019190915250565b600081600401835110151515611402576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612468565b5001602001517fffffffff000000000000000000000000000000000000000000000000000000001690565b60008061144184601063ffffffff61194716565b604080517f7472616e7366657228616464726573732c75696e7432353629000000000000008152905190819003601901812091935073ffffffffffffffffffffffffffffffffffffffff8416919061149f903390879060240161236d565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931783525181519192909182919080838360005b8381101561154357818101518382015260200161152b565b50505050905090810190601f1680156115705780820380516001836020036101000a031916815260200191505b509150506000604051808303816000865af1925050508015156115bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b3d156115dc575060003d602014156115dc5760206000803e506000515b801515611615576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612408565b50505050565b60008060018314611658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612478565b61166984601063ffffffff61194716565b915061167c84602463ffffffff6119a816565b6040517f23b872dd00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8316906323b872dd906116d590309033908690600401612345565b600060405180830381600087803b1580156116ef57600080fd5b505af1158015610f1f573d6000803e3d6000fd5b6000808315156117165760009150611088565b5082820282848281151561172657fe5b0414611084576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123e8565b600080828481151561176c57fe5b04949350505050565b604080517fb4be83d5000000000000000000000000000000000000000000000000000000006020808301919091526060602483018181528751608485019081528884015160a48601529488015160c48501529087015160e4840152608087015161010484015260a087015161012484015260c087015161014484015260e08701516101648401526101008701516101848401526101208701516101a4840152610140870180516101c485019081526101608901516101e4860152610180905251805161020485018190529394919384936044870192849261022489019291820191601f82010460005b8181101561187c57835185526020948501949093019260010161185e565b50505050818103610160808401919091528a0151805180835260209283019291820191601f82010460005b818110156118c55783518552602094850194909301926001016118a7565b50505089845250848103602093840190815288518083529093918201918981019190601f82010460005b8181101561190d5783518552602094850194909301926001016118ef565b5050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08883030188525060405250505050509392505050565b600081601401835110151515611989576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd90612458565b50016014015173ffffffffffffffffffffffffffffffffffffffff1690565b60006107ba83836000816020018351101515156119f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906123c8565b50016020015190565b608060405190810160405280600081526020016000815260200160008152602001600081525090565b60006107ba8235612540565b6000601f82018313611a4057600080fd5b8135611a53611a4e826124d9565b6124b2565b81815260209384019390925082018360005b83811015611a915781358601611a7b8882611b41565b8452506020928301929190910190600101611a65565b5050505092915050565b6000601f82018313611aac57600080fd5b8135611aba611a4e826124d9565b81815260209384019390925082018360005b83811015611a915781358601611ae28882611b90565b8452506020928301929190910190600101611acc565b600080601f83018413611b0a57600080fd5b50813567ffffffffffffffff811115611b2257600080fd5b602083019150836001820283011115611b3a57600080fd5b9250929050565b6000601f82018313611b5257600080fd5b8135611b60611a4e826124fa565b91508082526020830160208301858383011115611b7c57600080fd5b611b8783828461255c565b50505092915050565b60006101808284031215611ba357600080fd5b611bae6101806124b2565b90506000611bbc8484611a23565b8252506020611bcd84848301611a23565b6020830152506040611be184828501611a23565b6040830152506060611bf584828501611a23565b6060830152506080611c0984828501611cd9565b60808301525060a0611c1d84828501611cd9565b60a08301525060c0611c3184828501611cd9565b60c08301525060e0611c4584828501611cd9565b60e083015250610100611c5a84828501611cd9565b61010083015250610120611c7084828501611cd9565b6101208301525061014082013567ffffffffffffffff811115611c9257600080fd5b611c9e84828501611b41565b6101408301525061016082013567ffffffffffffffff811115611cc057600080fd5b611ccc84828501611b41565b6101608301525092915050565b60006107ba8235612559565b600060208284031215611cf757600080fd5b6000611d038484611a23565b949350505050565b60008060008060008060c08789031215611d2457600080fd5b863567ffffffffffffffff811115611d3b57600080fd5b611d4789828a01611a9b565b965050602087013567ffffffffffffffff811115611d6457600080fd5b611d7089828a01611a2f565b955050604087013567ffffffffffffffff811115611d8d57600080fd5b611d9989828a01611a9b565b945050606087013567ffffffffffffffff811115611db657600080fd5b611dc289828a01611a2f565b9350506080611dd389828a01611cd9565b92505060a0611de489828a01611a23565b9150509295509295509295565b600080600080600080600060e0888a031215611e0c57600080fd5b873567ffffffffffffffff811115611e2357600080fd5b611e2f8a828b01611a9b565b9750506020611e408a828b01611cd9565b965050604088013567ffffffffffffffff811115611e5d57600080fd5b611e698a828b01611a2f565b955050606088013567ffffffffffffffff811115611e8657600080fd5b611e928a828b01611a9b565b945050608088013567ffffffffffffffff811115611eaf57600080fd5b611ebb8a828b01611a2f565b93505060a0611ecc8a828b01611cd9565b92505060c0611edd8a828b01611a23565b91505092959891949750929550565b600080600060408486031215611f0157600080fd5b833567ffffffffffffffff811115611f1857600080fd5b611f2486828701611af8565b93509350506020611f3786828701611cd9565b9150509250925092565b611f4a81612540565b82525050565b602381527f44454641554c545f46554e4354494f4e5f574554485f434f4e54524143545f4f60208201527f4e4c590000000000000000000000000000000000000000000000000000000000604082015260600190565b601181527f494e56414c49445f4d53475f56414c5545000000000000000000000000000000602082015260400190565b600d81527f4f564552534f4c445f5745544800000000000000000000000000000000000000602082015260400190565b601181527f55494e543235365f554e444552464c4f57000000000000000000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f33325f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b601081527f4449564953494f4e5f42595f5a45524f00000000000000000000000000000000602082015260400190565b601081527f55494e543235365f4f564552464c4f5700000000000000000000000000000000602082015260400190565b601781527f554e535550504f525445445f41535345545f50524f5859000000000000000000602082015260400190565b600f81527f5452414e534645525f4641494c45440000000000000000000000000000000000602082015260400190565b601481527f434f4d504c4554455f46494c4c5f4641494c4544000000000000000000000000602082015260400190565b601a81527f494e53554646494349454e545f4554485f52454d41494e494e47000000000000602082015260400190565b601381527f4f4e4c595f434f4e54524143545f4f574e455200000000000000000000000000602082015260400190565b601881527f4645455f50455243454e544147455f544f4f5f4c415247450000000000000000602082015260400190565b602681527f475245415445525f4f525f455155414c5f544f5f32305f4c454e4754485f524560208201527f5155495245440000000000000000000000000000000000000000000000000000604082015260600190565b602581527f475245415445525f4f525f455155414c5f544f5f345f4c454e4754485f52455160208201527f5549524544000000000000000000000000000000000000000000000000000000604082015260600190565b600e81527f494e56414c49445f414d4f554e54000000000000000000000000000000000000602082015260400190565b805160808301906122f9848261232e565b50602082015161230c602085018261232e565b50604082015161231f604085018261232e565b50606082015161161560608501825b611f4a81612559565b602081016107bd8284611f41565b606081016123538286611f41565b6123606020830185611f41565b611d03604083018461232e565b6040810161237b8285611f41565b6110e0602083018461232e565b602080825281016107bd81611f50565b602080825281016107bd81611fa6565b602080825281016107bd81611fd6565b602080825281016107bd81612006565b602080825281016107bd81612036565b602080825281016107bd8161208c565b602080825281016107bd816120bc565b602080825281016107bd816120ec565b602080825281016107bd8161211c565b602080825281016107bd8161214c565b602080825281016107bd8161217c565b602080825281016107bd816121ac565b602080825281016107bd816121dc565b602080825281016107bd8161220c565b602080825281016107bd81612262565b602080825281016107bd816122b8565b610100810161249782856122e8565b6110e060808301846122e8565b602081016107bd828461232e565b60405181810167ffffffffffffffff811182821017156124d157600080fd5b604052919050565b600067ffffffffffffffff8211156124f057600080fd5b5060209081020190565b600067ffffffffffffffff82111561251157600080fd5b506020601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160190565b73ffffffffffffffffffffffffffffffffffffffff1690565b90565b828183375060009101525600a265627a7a72305820d9f418f11e0f91f06f6f9d22924be0add925495eeb76a6388b5417adb505eeb36c6578706572696d656e74616cf50037", - "gasUsed": "0x2c8c7f" - }, - "subtraces": 3, - "traceAddress": [], - "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e", - "transactionPosition": 0, - "type": "create" - }, - { - "action": { - "callType": "call", - "from": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414", - "gas": "0x1dba84", - "input": "0x60704108f47261b000000000000000000000000000000000000000000000000000000000", - "to": "0x48bacb9266a570d521063ef5dd96e61686dbe788", - "value": "0x0" - }, - "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8", - "blockNumber": 13536, - "result": { - "gasUsed": "0x3d9", - "output": "0x0000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48" - }, - "subtraces": 0, - "traceAddress": [ - 0 - ], - "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e", - "transactionPosition": 0, - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414", - "gas": "0x1dad2e", - "input": "0x095ea7b30000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "to": "0x0b1ba0af832d7c05fd64161e0db78e85978e8082", - "value": "0x0" - }, - "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8", - "blockNumber": 13536, - "result": { - "gasUsed": "0x56c8", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [ - 1 - ], - "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e", - "transactionPosition": 0, - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x6000eca38b8b5bba64986182fe2a69c57f6b5414", - "gas": "0x1d4ee1", - "input": "0x095ea7b30000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "to": "0x871dd7c2b4b25e1aa18728e9d5f2af4c4e431f5c", - "value": "0x0" - }, - "blockHash": "0x6456fbd35a3a69a1709c324fad114d68507d2c8ab391e9adb128f9734c8e4ae8", - "blockNumber": 13536, - "result": { - "gasUsed": "0x56ca", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 0, - "traceAddress": [ - 2 - ], - "transactionHash": "0x6974f745a004f030bebb1c01d4595edbda2fafcf01c0bfbd5d335711e2a7b04e", - "transactionPosition": 0, - "type": "call" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json deleted file mode 100644 index bd6059faef..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/oog.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "context": { - "difficulty": "3699098917", - "gasLimit": "5258985", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "number": "2294631", - "timestamp": "1513675366" - }, - "genesis": { - "alloc": { - "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": { - "balance": "0x0", - "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029", - "nonce": "1", - "storage": { - "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0" - } - }, - "0x94194bc2aaf494501d7880b61274a169f6502a54": { - "balance": "0xea8c39a876d19888d", - "code": "0x", - "nonce": "265", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3699098917", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "5263953", - "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", - "nonce": "0xd1bdb150f6fd170e", - "number": "2294630", - "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" - }, - "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956", - "result": [ - { - "action": { - "callType": "call", - "from": "0x94194bc2aaf494501d7880b61274a169f6502a54", - "gas": "0xca1d", - "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000", - "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62", - "value": "0x0" - }, - "blockNumber": 2294631, - "error": "out of gas", - "result": {}, - "subtraces": 0, - "traceAddress": [], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json deleted file mode 100644 index 8888d3e68a..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/option_convert_parity_errors.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "context": { - "difficulty": "3699098917", - "gasLimit": "5258985", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "number": "2294631", - "timestamp": "1513675366" - }, - "genesis": { - "alloc": { - "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": { - "balance": "0x0", - "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029", - "nonce": "1", - "storage": { - "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0" - } - }, - "0x94194bc2aaf494501d7880b61274a169f6502a54": { - "balance": "0xea8c39a876d19888d", - "code": "0x", - "nonce": "265", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3699098917", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "5263953", - "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", - "nonce": "0xd1bdb150f6fd170e", - "number": "2294630", - "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" - }, - "tracerConfig": { - "convertParityErrors": true - }, - "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956", - "result": [ - { - "action": { - "callType": "call", - "from": "0x94194bc2aaf494501d7880b61274a169f6502a54", - "gas": "0xca1d", - "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000", - "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62", - "value": "0x0" - }, - "blockNumber": 2294631, - "error": "Out of gas", - "result": {}, - "subtraces": 0, - "traceAddress": [], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json deleted file mode 100644 index 62baf333b6..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/result_output.json +++ /dev/null @@ -1,111 +0,0 @@ -{ - "genesis": { - "difficulty": "1911202", - "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", - "gasLimit": "7842876", - "hash": "0x4d7bc82e0d56307094378e1a8fbfa6260986f621de95b5fe68a95248b3ba8efe", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "mixHash": "0xc102ad52677c391edab82cc895ca7a7e9fff3eed4fa966ecf7fb61ec1e84bb6b", - "nonce": "0x39f5b074e3437f3f", - "number": "553415", - "stateRoot": "0x8f89e79109c19fa00e72b400502448540dc4773ad92dddd341dbba20c710a3b5", - "timestamp": "1577396195", - "totalDifficulty": "458361299240", - "alloc": { - "0x531f76bad925f6a925474996c7d738c1008045f6": { - "balance": "0x0", - "nonce": "1", - "code": "0x6060604052361561008a576000357c01000000000000000000000000000000000000000000000000000000009004806301cb3b20146102bf57806329dcb0cf146102cc57806338af3eed146102ed5780636e66f6e9146103245780637a3a0e841461035b5780637b3e5e7b1461037c578063a035b1fe1461039d578063dc0d3dff146103be5761008a565b6102bd5b60003490506040604051908101604052803381526020018281526020015060066000506006600050805480919060010190908154818355818115116101365760020281600202836000526020600020918201910161013591906100ec565b808211156101315760006000820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001820160005060009055506001016100ec565b5090565b5b505050815481101561000257906000526020600020906002020160005060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff0219169083021790555060208201518160010160005055905050806002600082828250540192505081905550600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166390b98a11336004600050548404604051837c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750505060405151507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf633826001604051808473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a15b50565b005b6102ca6004506104c8565b005b6102d760045061043a565b6040518082815260200191505060405180910390f35b6102f8600450610402565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61032f60045061044c565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610366600450610428565b6040518082815260200191505060405180910390f35b610387600450610431565b6040518082815260200191505060405180910390f35b6103a8600450610443565b6040518082815260200191505060405180910390f35b6103cf600480359060200150610472565b604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016000505481565b60026000505481565b60036000505481565b60046000505481565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60066000508181548110156100025790600052602060002090600202016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160005054905082565b6000600360005054421015156107d8576001600050546002600050541015156105cf57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600260005054604051809050600060405180830381858888f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002600050546000604051808473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a161079d565b7fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf66000600b600060405180848152602001838152602001828152602001935050505060405180910390a1600090505b60066000505481101561079c57600660005081815481101561000257906000526020600020906002020160005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166000600660005083815481101561000257906000526020600020906002020160005060010160005054604051809050600060405180830381858888f19350505050507fe842aea7a5f1b01049d752008c53c52890b1a6daf660cf39e8eec506112bbdf6600660005082815481101561000257906000526020600020906002020160005060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166006600050838154811015610002579060005260206000209060020201600050600101600050546000604051808473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a15b806001019050805061061e565b5b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b5056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d40": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000000b49180d443dc4ca6028de0031ac09337891fd8ce", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000" - } - }, - "0xb49180d443dc4ca6028de0031ac09337891fd8ce": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x193e9986e2e3f0c58988", - "nonce": "2585", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "553416", - "difficulty": "1909336", - "timestamp": "1577396224", - "gasLimit": "7835218", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf870820a1985e8d4a5100083040b2894531f76bad925f6a925474996c7d738c1008045f6880de0b6b3a76400008081a2a08693170f040d9501b831b404d9e40fba040c5aef4b8974aedc20b3844aea7c32a0476861058ff9b8030c58bcba8be320acc855e4694a633c493fb50fbdb9455489", - "result": [ - { - "type": "call", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "to": "0x531f76bad925f6a925474996c7d738c1008045f6", - "value": "0xde0b6b3a7640000", - "gas": "0x40b28", - "input": "0x", - "callType": "call" - }, - "result": { - "gasUsed": "0x19c3e", - "output": "0x" - }, - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 5, - "transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada", - "blockNumber": 553416, - "blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282", - "time": "617.42µs" - }, - { - "type": "call", - "action": { - "from": "0x531f76bad925f6a925474996c7d738c1008045f6", - "to": "0xb49180d443dc4ca6028de0031ac09337891fd8ce", - "value": "0x0", - "gas": "0x2164e", - "input": "0x90b98a11000000000000000000000000877bd459c9b7d8576b44e59e09d076c25946f4430000000000000000000000000000000000000000000000000000000000000001", - "callType": "call" - }, - "result": { - "gasUsed": "0x0", - "output": "0x" - }, - "traceAddress": [ - 0 - ], - "subtraces": 0, - "transactionPosition": 5, - "transactionHash": "0x04d2029a5cbbed30969cdc0a2ca9e9fc6b719e323af0802b52466f07ee0ecada", - "blockNumber": 553416, - "blockHash": "0x8df024322173d225a09681d35edeaa528aca60743a11a70f854c158862bf5282" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json deleted file mode 100644 index b0346d8603..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "context": { - "difficulty": "3665057456", - "gasLimit": "5232723", - "miner": "0xf4d8e706cfb25c0decbbdd4d2e2cc10c66376a3f", - "number": "2294501", - "timestamp": "1513673601" - }, - "genesis": { - "alloc": { - "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9": { - "balance": "0x2a3fc32bcc019283", - "code": "0x", - "nonce": "10", - "storage": {} - }, - "0xabbcd5b340c80b5f1c0545c04c987b87310296ae": { - "balance": "0x0", - "code": "0x606060405236156100755763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d0335ab811461007a578063548db174146100ab5780637f649783146100fc578063b092145e1461014d578063c3f44c0a14610186578063c47cf5de14610203575b600080fd5b341561008557600080fd5b610099600160a060020a0360043516610270565b60405190815260200160405180910390f35b34156100b657600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061028f95505050505050565b005b341561010757600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061029e95505050505050565b005b341561015857600080fd5b610172600160a060020a03600435811690602435166102ad565b604051901515815260200160405180910390f35b341561019157600080fd5b6100fa6004803560ff1690602480359160443591606435600160a060020a0316919060a49060843590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965050509235600160a060020a031692506102cd915050565b005b341561020e57600080fd5b61025460046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061056a95505050505050565b604051600160a060020a03909116815260200160405180910390f35b600160a060020a0381166000908152602081905260409020545b919050565b61029a816000610594565b5b50565b61029a816001610594565b5b50565b600160209081526000928352604080842090915290825290205460ff1681565b60008080600160a060020a038416158061030d5750600160a060020a038085166000908152600160209081526040808320339094168352929052205460ff165b151561031857600080fd5b6103218561056a565b600160a060020a038116600090815260208190526040808220549295507f19000000000000000000000000000000000000000000000000000000000000009230918891908b908b90517fff000000000000000000000000000000000000000000000000000000000000008089168252871660018201526c01000000000000000000000000600160a060020a038088168202600284015286811682026016840152602a8301869052841602604a820152605e810182805190602001908083835b6020831061040057805182525b601f1990920191602091820191016103e0565b6001836020036101000a0380198251168184511617909252505050919091019850604097505050505050505051809103902091506001828a8a8a6040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f1151561049957600080fd5b5050602060405103519050600160a060020a03838116908216146104bc57600080fd5b600160a060020a0380841660009081526020819052604090819020805460010190559087169086905180828051906020019080838360005b8381101561050d5780820151818401525b6020016104f4565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b5091505060006040518083038160008661646e5a03f1915050151561055e57600080fd5b5b505050505050505050565b600060248251101561057e5750600061028a565b600160a060020a0360248301511690505b919050565b60005b825181101561060157600160a060020a033316600090815260016020526040812083918584815181106105c657fe5b90602001906020020151600160a060020a031681526020810191909152604001600020805460ff19169115159190911790555b600101610597565b5b5050505600a165627a7a723058200027e8b695e9d2dea9f3629519022a69f3a1d23055ce86406e686ea54f31ee9c0029", - "nonce": "1", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3672229776", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "5227619", - "hash": "0xa07b3d6c6bf63f5f981016db9f2d1d93033833f2c17e8bf7209e85f1faf08076", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x806e151ce2817be922e93e8d5921fa0f0d0fd213d6b2b9a3fa17458e74a163d0", - "nonce": "0xbc5d43adc2c30c7d", - "number": "2294500", - "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d", - "timestamp": "1513673552", - "totalDifficulty": "7160066586979149" - }, - "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a", - "result": [ - { - "action": { - "callType": "call", - "from": "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9", - "gas": "0x2dc6c0", - "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000", - "to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae", - "value": "0x0" - }, - "blockNumber": 2294501, - "error": "execution reverted", - "result": { - "gasUsed": "0x719b" - }, - "subtraces": 0, - "traceAddress": [], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json deleted file mode 100644 index 6759b05e52..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/revert_reason.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "context": { - "difficulty": "2", - "gasLimit": "8000000", - "miner": "0x0000000000000000000000000000000000000000", - "number": "3212651", - "timestamp": "1597246515" - }, - "genesis": { - "alloc": { - "0xf58833cf0c791881b494eb79d461e08a1f043f52": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063609ff1bd11610078578063609ff1bd146101af5780639e7b8d61146101cd578063a3ec138d14610211578063e2ba53f0146102ae576100a5565b80630121b93f146100aa578063013cf08b146100d85780632e4176cf146101215780635c19a95c1461016b575b600080fd5b6100d6600480360360208110156100c057600080fd5b81019080803590602001909291905050506102cc565b005b610104600480360360208110156100ee57600080fd5b8101908080359060200190929190505050610469565b604051808381526020018281526020019250505060405180910390f35b61012961049a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ad6004803603602081101561018157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104bf565b005b6101b76108db565b6040518082815260200191505060405180910390f35b61020f600480360360208110156101e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610952565b005b6102536004803603602081101561022757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b53565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b6102b6610bb0565b6040518082815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f486173206e6f20726967687420746f20766f746500000000000000000000000081525060200191505060405180910390fd5b8060010160009054906101000a900460ff161561040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f416c726561647920766f7465642e00000000000000000000000000000000000081525060200191505060405180910390fd5b60018160010160006101000a81548160ff02191690831515021790555081816002018190555080600001546002838154811061044757fe5b9060005260206000209060020201600101600082825401925050819055505050565b6002818154811061047657fe5b90600052602060002090600202016000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff1615610587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f596f7520616c726561647920766f7465642e000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e000081525060200191505060405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107cc57600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f466f756e64206c6f6f7020696e2064656c65676174696f6e2e0000000000000081525060200191505060405180910390fd5b61062a565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156108bf578160000154600282600201548154811061089c57fe5b9060005260206000209060020201600101600082825401925050819055506108d6565b816000015481600001600082825401925050819055505b505050565b6000806000905060008090505b60028054905081101561094d57816002828154811061090357fe5b9060005260206000209060020201600101541115610940576002818154811061092857fe5b90600052602060002090600202016001015491508092505b80806001019150506108e8565b505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180610bde6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f54686520766f74657220616c726561647920766f7465642e000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414610b0957600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610bbc6108db565b81548110610bc657fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea26469706673582212201d282819f8f06fed792100d60a8b08809b081a34a1ecd225e83a4b41122165ed64736f6c63430006060033", - "nonce": "1", - "storage": { - "0x6200beec95762de01ce05f2a0e58ce3299dbb53c68c9f3254a242121223cdf58": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1": { - "balance": "0x57af9d6b3df812900", - "code": "0x", - "nonce": "6", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "IstanbulBlock": 1561651, - "chainId": 5, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294", - "result": [ - { - "action": { - "callType": "call", - "from": "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", - "gas": "0x2dc6c0", - "input": "0x5c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", - "to": "0xf58833cf0c791881b494eb79d461e08a1f043f52", - "value": "0x0" - }, - "blockNumber": 3212651, - "error": "execution reverted", - "result": { - "gasUsed": "0x5940", - "output": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000" - }, - "subtraces": 0, - "traceAddress": [], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json deleted file mode 100644 index 74fd87cc6c..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/selfdestruct.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "genesis": { - "difficulty": "4628640", - "extraData": "0xd883010b05846765746888676f312e31342e33856c696e7578", - "gasLimit": "9244120", - "hash": "0x5a1f551897cc91265225b0453136ad8c7eef1c1c8b06139da4f2e6e710c1f4df", - "miner": "0x73f26d124436b0791169d63a3af29c2ae47765a3", - "mixHash": "0xd6735e63f8937fe0c5491e0d5836ec28467363be7ada5a2f979f9d107e2c831e", - "nonce": "0x7c35e34d2e328d7d", - "number": "1555145", - "stateRoot": "0x565873b05f71b98595133e37a52d79c3476ce820c05ebedaddd35541b0e894a3", - "timestamp": "1590793819", - "totalDifficulty": "2241994078605", - "alloc": { - "0x119f569a45e9d0089d51d7f9529f5ea9bf5785e2": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x622e8fced69d43eb8d97", - "nonce": "260140", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555146", - "difficulty": "4630900", - "timestamp": "1590793820", - "gasLimit": "9253146", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf8628303f82c843b9aca0083019ecc80808e605a600053600160006001f0ff0081a2a077f539ae2a58746bbfa6370fc423f946870efa32753d697d3729d361a428623aa0384ef9a5650d6630f5c1ddef616bffa5fc72a95a9314361d0918de066aa4475a", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x19ecc", - "init": "0x605a600053600160006001f0ff00" - }, - "result": { - "gasUsed": "0x102a1", - "code": "0x", - "address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca" - }, - "traceAddress": [], - "subtraces": 1, - "transactionPosition": 14, - "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79", - "blockNumber": 1555146, - "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e", - "time": "187.145µs" - }, - { - "type": "suicide", - "action": { - "address": "0x1d99a1a3efa9181f540f9e24fa6e4e08eb7844ca", - "refundAddress": "0x0000000000000000000000000000000000000000", - "balance": "0x0" - }, - "result": null, - "traceAddress": [ - 0 - ], - "subtraces": 0, - "transactionPosition": 14, - "transactionHash": "0xdd76f02407e2f8329303ba688e111cae4f7008ad0d14d6e42c5698424ea36d79", - "blockNumber": 1555146, - "blockHash": "0xafb4f1dd27b9054c805acb81a88ed04384788cb31d84164c21874935c81e5c7e" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json deleted file mode 100644 index a7244e9747..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "result": [ - { - "action": { - "callType": "call", - "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb", - "gas": "0x15f90", - "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "value": "0x0" - }, - "blockNumber": 2289806, - "result": { - "gasUsed": "0x9751", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 1, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "gas": "0x6d05", - "input": "0x", - "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "value": "0x6f05b59d3b20000" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x0", - "output": "0x" - }, - "subtraces": 0, - "traceAddress": [0], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json deleted file mode 100644 index 5fbdf55d22..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/simple_onlytop.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "tracerConfig": { - "onlyTopCall": true - }, - "result": [ - { - "action": { - "callType": "call", - "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb", - "gas": "0x15f90", - "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "value": "0x0" - }, - "blockNumber": 2289806, - "result": { - "gasUsed": "0x9751", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "subtraces": 1, - "traceAddress": [], - "type": "call" - }, - { - "action": { - "callType": "call", - "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "gas": "0x6d05", - "input": "0x", - "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "value": "0x6f05b59d3b20000" - }, - "blockNumber": 0, - "result": { - "gasUsed": "0x0", - "output": "0x" - }, - "subtraces": 0, - "traceAddress": [0], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json deleted file mode 100644 index 96060d5545..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/skip_no_balance_error.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "genesis": { - "difficulty": "4673862", - "extraData": "0xd683010b05846765746886676f312e3133856c696e7578", - "gasLimit": "9471919", - "hash": "0x7f072150c5905c214966e3432d418910badcdbe510aceaac295b1d7059cc0ffc", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "mixHash": "0x113ced8fedb939fdc862008da7bdddde726f997c0e6dfba0e55613994757b489", - "nonce": "0x0f411a2e5552c5b7", - "number": "1555284", - "stateRoot": "0x9fe125b361b72d5479b24ad9be9964b74228c73a2dfb0065060a79b4a6dfaa1e", - "timestamp": "1590795374", - "totalDifficulty": "2242642335405", - "alloc": { - "0xe85df1413eebe1b191c26260e19783a274a6b041": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x6244c985ef1e48e84531", - "nonce": "265775", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "1555285", - "difficulty": "4676144", - "timestamp": "1590795378", - "gasLimit": "9481167", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf9014083040e2f843b9aca008301aab08080b8eb7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5547f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000037f05581a2a09db45e7846f193471f6d897fb6ff58b7ec41a9c6f63d10aca47d821c365981cba052ec320875625e16141a1a9e8b7993de863698fb699f93ae2cab26149bbb144f", - "result": [ - { - "type": "create", - "action": { - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "value": "0x0", - "gas": "0x1aab0", - "init": "0x7f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b57f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000945304eb96065b2a98b57a48a06ae28d285a71b5547f000000000000000000000000000000000000000000000000000000000000c3507f000000000000000000000000000000000000000000000000000000000000c3507f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000037f055" - }, - "error": "out of gas", - "traceAddress": [], - "subtraces": 0, - "transactionPosition": 16, - "transactionHash": "0x384487e5ae8d2997aece8e28403d393cb9752425e6de358891bed981c5af1c05", - "blockNumber": 1555285, - "blockHash": "0x93231d8e9662adb4c5c703583a92c7b3112cd5448f43ab4fa1f0f00a0183ed3f", - "time": "665.278µs" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json deleted file mode 100644 index 45ffbe2db9..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/staticcall_precompiled.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "genesis": { - "difficulty": "2028219", - "extraData": "0xd883010906846765746888676f312e31332e35856c696e7578", - "gasLimit": "23481547", - "hash": "0x3c06114e88c26b52decfe4e5f6d4d51cfaaea0317b646017fac32fadbe7df9f5", - "miner": "0x2a1442b4fbabf7b5507c13ccf076a547abfaeb1b", - "mixHash": "0x46108f74220c5ab23651f93912b14fea37ed1380d22e10639a1f5651c98cb949", - "nonce": "0x426a5267e0b636fe", - "number": "567687", - "stateRoot": "0x7b4b193fe73ef87101c7c325954681861cc240c299d03459784b2b11c9c522ae", - "timestamp": "1577578008", - "totalDifficulty": "485254950048", - "alloc": { - "0x8521f13dd5e4bc3dab3cf0f01a195a5af899e851": { - "balance": "0x0", - "nonce": "1", - "code": "0x608060405260043610610251576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301ffc9a7146102565780630519ce79146102c857806306fdde031461031f578063095ea7b3146103af5780630a0f81681461040a5780631155dfe51461046157806318160ddd1461048c5780631b57cd44146104b7578063200b1e641461050657806327d7874c146105cb5780632ba73c151461061c5780633108e4d71461066d578063317676bf146106bc5780633f4ba83a1461071557806342842e0e1461072c57806346cb96fa146107a75780634e0a3379146107f65780635501d42d146108475780635c975abb146108a05780635fd8c710146108cf5780636352211e146108e65780636af04a571461096157806370a08231146109b85780637158798814610a1d5780637866928014610a6e5780638456cb5914610ae95780638462151c14610b0057806385ac788214610ba657806395787d2614610c2c57806395d89b4114610c6e57806396b5d99214610cfe578063990581b614610d795780639db797f014610e2d578063ab8f933a14610e80578063ad84202814610eab578063b047fb5014610ed6578063b355752214610f2d578063b9db15b414610f7c578063bc4006f514610fd2578063ca083be214611029578063cdd22c9314611082578063cec21acb146110d1578063e078d8b114611136578063e17b25af14611182578063e52ab74b146111d3578063f010432314611222578063fac9c51f1461129d578063fdb33429146112ec578063fffb147914611367575b600080fd5b34801561026257600080fd5b506102ae6004803603602081101561027957600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506113e2565b604051808215151515815260200191505060405180910390f35b3480156102d457600080fd5b506102dd6116cb565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561032b57600080fd5b506103346116f1565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610374578082015181840152602081019050610359565b50505050905090810190601f1680156103a15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103bb57600080fd5b50610408600480360360408110156103d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061172a565b005b34801561041657600080fd5b5061041f6117c4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561046d57600080fd5b506104766117e9565b6040518082815260200191505060405180910390f35b34801561049857600080fd5b506104a16117f6565b6040518082815260200191505060405180910390f35b3480156104c357600080fd5b506104f0600480360360208110156104da57600080fd5b8101908080359060200190929190505050611806565b6040518082815260200191505060405180910390f35b34801561051257600080fd5b506105b5600480360360a081101561052957600080fd5b81019080803590602001909291908035906020019064010000000081111561055057600080fd5b82018360208201111561056257600080fd5b8035906020019184600183028401116401000000008311171561058457600080fd5b9091929391929390803560ff169060200190929190803590602001909291908035906020019092919050505061181e565b6040518082815260200191505060405180910390f35b3480156105d757600080fd5b5061061a600480360360208110156105ee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611cac565b005b34801561062857600080fd5b5061066b6004803603602081101561063f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d86565b005b34801561067957600080fd5b506106a66004803603602081101561069057600080fd5b8101908080359060200190929190505050611e61565b6040518082815260200191505060405180910390f35b3480156106c857600080fd5b506106ff600480360360408110156106df57600080fd5b810190808035906020019092919080359060200190929190505050611e79565b6040518082815260200191505060405180910390f35b34801561072157600080fd5b5061072a611ea9565b005b34801561073857600080fd5b506107a56004803603606081101561074f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f86565b005b3480156107b357600080fd5b506107e0600480360360208110156107ca57600080fd5b8101908080359060200190929190505050612053565b6040518082815260200191505060405180910390f35b34801561080257600080fd5b506108456004803603602081101561081957600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061206b565b005b34801561085357600080fd5b5061088a6004803603604081101561086a57600080fd5b810190808035906020019092919080359060200190929190505050612146565b6040518082815260200191505060405180910390f35b3480156108ac57600080fd5b506108b5612176565b604051808215151515815260200191505060405180910390f35b3480156108db57600080fd5b506108e4612189565b005b3480156108f257600080fd5b5061091f6004803603602081101561090957600080fd5b810190808035906020019092919050505061226d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561096d57600080fd5b506109766122e6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156109c457600080fd5b50610a07600480360360208110156109db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061230c565b6040518082815260200191505060405180910390f35b348015610a2957600080fd5b50610a6c60048036036020811015610a4057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612355565b005b348015610a7a57600080fd5b50610aa760048036036020811015610a9157600080fd5b8101908080359060200190929190505050612472565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610af557600080fd5b50610afe6124a5565b005b348015610b0c57600080fd5b50610b4f60048036036020811015610b2357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125e9565b6040518080602001828103825283818151815260200191508051906020019060200280838360005b83811015610b92578082015181840152602081019050610b77565b505050509050019250505060405180910390f35b348015610bb257600080fd5b50610c16600480360360c0811015610bc957600080fd5b810190808035906020019092919080359060200190929190803515159060200190929190803560ff1690602001909291908035906020019092919080359060200190929190505050612737565b6040518082815260200191505060405180910390f35b610c5860048036036020811015610c4257600080fd5b8101908080359060200190929190505050612c0c565b6040518082815260200191505060405180910390f35b348015610c7a57600080fd5b50610c8361304b565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610cc3578082015181840152602081019050610ca8565b50505050905090810190601f168015610cf05780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610d0a57600080fd5b50610d3760048036036020811015610d2157600080fd5b8101908080359060200190929190505050613084565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610d8557600080fd5b50610db260048036036020811015610d9c57600080fd5b81019080803590602001909291905050506130b7565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610df2578082015181840152602081019050610dd7565b50505050905090810190601f168015610e1f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610e3957600080fd5b50610e6660048036036020811015610e5057600080fd5b810190808035906020019092919050505061317b565b604051808215151515815260200191505060405180910390f35b348015610e8c57600080fd5b50610e956131b3565b6040518082815260200191505060405180910390f35b348015610eb757600080fd5b50610ec06131b9565b6040518082815260200191505060405180910390f35b348015610ee257600080fd5b50610eeb6131bf565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610f3957600080fd5b50610f6660048036036020811015610f5057600080fd5b81019080803590602001909291905050506131e5565b6040518082815260200191505060405180910390f35b348015610f8857600080fd5b50610fb560048036036020811015610f9f57600080fd5b81019080803590602001909291905050506131fd565b604051808381526020018281526020019250505060405180910390f35b348015610fde57600080fd5b50610fe7613235565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561103557600080fd5b5061106c6004803603604081101561104c57600080fd5b81019080803590602001909291908035906020019092919050505061325b565b6040518082815260200191505060405180910390f35b34801561108e57600080fd5b506110bb600480360360208110156110a557600080fd5b810190808035906020019092919050505061328b565b6040518082815260200191505060405180910390f35b3480156110dd57600080fd5b50611120600480360360208110156110f457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132ab565b6040518082815260200191505060405180910390f35b61116c6004803603604081101561114c57600080fd5b8101908080359060200190929190803590602001909291905050506132c3565b6040518082815260200191505060405180910390f35b34801561118e57600080fd5b506111d1600480360360208110156111a557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506134ee565b005b3480156111df57600080fd5b5061120c600480360360208110156111f657600080fd5b810190808035906020019092919050505061358d565b6040518082815260200191505060405180910390f35b34801561122e57600080fd5b5061125b6004803603602081101561124557600080fd5b81019080803590602001909291905050506135ad565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156112a957600080fd5b506112d6600480360360208110156112c057600080fd5b81019080803590602001909291905050506135e0565b6040518082815260200191505060405180910390f35b3480156112f857600080fd5b506113256004803603602081101561130f57600080fd5b81019080803590602001909291905050506135f8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561137357600080fd5b506113a06004803603602081101561138a57600080fd5b810190808035906020019092919050505061362b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060405180807f737570706f727473496e74657266616365286279746573342900000000000000815250601901905060405180910390207bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611610575060405180807f746f6b656e734f664f776e6572286164647265737329000000000000000000008152506016019050604051809103902060405180807f736166655472616e7366657246726f6d28616464726573732c6164647265737381526020017f2c75696e743235362900000000000000000000000000000000000000000000008152506029019050604051809103902060405180807f617070726f766528616464726573732c75696e743235362900000000000000008152506018019050604051809103902060405180807f6f776e65724f662875696e7432353629000000000000000000000000000000008152506010019050604051809103902060405180807f62616c616e63654f6628616464726573732900000000000000000000000000008152506012019050604051809103902060405180807f746f74616c537570706c79282900000000000000000000000000000000000000815250600d019050604051809103902018181818187bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806116c4575060405180807f73796d626f6c28290000000000000000000000000000000000000000000000008152506008019050604051809103902060405180807f6e616d652829000000000000000000000000000000000000000000000000000081525060060190506040518091039020187bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600781526020017f426974766965770000000000000000000000000000000000000000000000000081525081565b600260149054906101000a900460ff1615151561174657600080fd5b611750338261365e565b151561175b57600080fd5b61176581836136ca565b808273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600480549050905090565b6000600160048054905003905090565b60166020528060005260406000206000915090505481565b600085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050506101006000825111801561187a575080825111155b151561188557600080fd5b33896005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156118f557600080fd5b6000878760405160200180838152602001828152602001925050506040516020818303038152906040528051906020012090506000600e6000838152602001908152602001600020541415156119b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f5369676e617475726520416c726561647920557365640000000000000000000081525060200191505060405180910390fd5b600560008d815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660018d60405160200180828152602001915050604051602081830303815290604052805190602001208b8b8b60405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015611a80573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff16141515611aac57600080fd5b611ab4613a21565b6020604051908101604052808d8d8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050815250905060006001600a839080600181540180825580915050906001820390600052602060002001600090919290919091506000820151816000019080519060200190611b54929190613a35565b5050500390508063ffffffff1681141515611b6e57600080fd5b7fe819187a0cf517f3c23c7bd6e6b11a3aec56ec3f2784dc69ac56ebac668748ee3382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a133600b600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508d600c600083815260200190815260200160002081905550600860008f81526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190915055508d600e600085815260200190815260200160002081905550809750505050505050509695505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611d0757600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611d4357600080fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611de157600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515611e1d57600080fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60116020528060005260406000206000915090505481565b600860205281600052604060002081815481101515611e9457fe5b90600052602060002001600091509150505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f0457600080fd5b600260149054906101000a900460ff161515611f1f57600080fd5b600073ffffffffffffffffffffffffffffffffffffffff16601860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515611f7c57600080fd5b611f84613720565b565b600260149054906101000a900460ff16151515611fa257600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515611fde57600080fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561201957600080fd5b61202333826137b3565b151561202e57600080fd5b612038838261365e565b151561204357600080fd5b61204e83838361381f565b505050565b600e6020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156120c657600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561210257600080fd5b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600d6020528160005260406000208181548110151561216157fe5b90600052602060002001600091509150505481565b600260149054906101000a900460ff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156121e557600080fd5b60003073ffffffffffffffffffffffffffffffffffffffff16319050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015612269573d6000803e3d6000fd5b5050565b60006005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156122e157600080fd5b919050565b601860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156123b057600080fd5b600260149054906101000a900460ff1615156123cb57600080fd5b80601860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f450db8da6efbe9c22f2347f7c2021231df1fc58d3ae9a2fa75d39fa44619930581604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600b6020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061254d57506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b806125a55750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156125b057600080fd5b600260149054906101000a900460ff161515156125cc57600080fd5b6001600260146101000a81548160ff021916908315150217905550565b606060006125f68361230c565b9050600081141561263a5760006040519080825280602002602001820160405280156126315781602001602082028038833980820191505090505b50915050612732565b60608160405190808252806020026020018201604052801561266b5781602001602082028038833980820191505090505b50905060006126786117f6565b905060008090506000600190505b8281111515612729578673ffffffffffffffffffffffffffffffffffffffff166005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141561271c5780848381518110151561270557fe5b906020019060200201818152505081806001019250505b8080600101915050612686565b83955050505050505b919050565b600033876005600082815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156127a957600080fd5b60008585604051602001808381526020018281526020019250505060405160208183030381529060405280519060200120905060008911156128715788601260008381526020019081526020016000205414151515612870576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260168152602001807f5369676e617475726520416c726561647920557365640000000000000000000081525060200191505060405180910390fd5b5b600560008b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660018b604051602001808281526020019150506040516020818303038152906040528051906020012089898960405160008152602001604052604051808581526020018460ff1660ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa15801561293e573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff1614151561296a57600080fd5b6000339050600073ffffffffffffffffffffffffffffffffffffffff16600b60008c815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515156129de57600080fd5b8073ffffffffffffffffffffffffffffffffffffffff16600b60008c815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515612a4c57600080fd5b612a54613ab5565b6020604051908101604052808b1515815250905060006001600f8390806001815401808255809150509060018203906000526020600020016000909192909190915060008201518160000160006101000a81548160ff02191690831515021790555050500390508063ffffffff1681141515612acf57600080fd5b7fa10f25ef783c24056e27eb55eb6c0ac1c4863cd5eab7e657cd067926b3dce0648382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1826010600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600d60008d81526020019081526020016000208190806001815401808255809150509060018203906000526020600020016000909192909190915055508b60116000838152602001908152602001600020819055508b60126000868152602001908152602001600020819055508096505050505050509695505050505050565b600034601354808210151515612c2157600080fd5b60003390506000600b600087815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612c9a57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff16600b600088815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614151515612d0857600080fd5b612d10613acb565b602060405190810160405280348152509050600060016014839080600181540180825580915050906001820390600052602060002001600090919290919091506000820151816000015550500390508063ffffffff1681141515612d7357600080fd5b836015600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508760166000838152602001908152602001600020819055506000606434604602811515612dee57fe5b0490506000600d60008b815260200190815260200160002080549050823403811515612e1657fe5b049050600b60008b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015612e92573d6000803e3d6000fd5b5060008090505b600d60008c815260200190815260200160002080549050811015612fcf5760106000600d60008e815260200190815260200160002083815481101515612edb57fe5b9060005260206000200154815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f19350505050158015612f5a573d6000803e3d6000fd5b5060176000858152602001908152602001600020600d60008d815260200190815260200160002082815481101515612f8e57fe5b906000526020600020015490806001815401808255809150509060018203906000526020600020016000909192909190915055508080600101915050612e99565b507f6ea1e5e03071ff9bad53b614eafcc00d29db646e9c351fcc00d45a4118d7c51a8684604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a18298505050505050505050919050565b6040805190810160405280600281526020017f425600000000000000000000000000000000000000000000000000000000000081525081565b60056020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000600a838154811015156130ca57fe5b906000526020600020019050806000018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561316e5780601f106131435761010080835404028352916020019161316e565b820191906000526020600020905b81548152906001019060200180831161315157829003601f168201915b5050505050915050919050565b600080600f8381548110151561318d57fe5b9060005260206000200190508060000160009054906101000a900460ff16915050919050565b60035481565b60135481565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60126020528060005260406000206000915090505481565b600080600060048481548110151561321157fe5b90600052602060002090600202019050806000015492508060010154915050915091565b600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60176020528160005260406000208181548110151561327657fe5b90600052602060002001600091509150505481565b600060086000838152602001908152602001600020805490509050919050565b60066020528060005260406000206000915090505481565b6000346003548082101515156132d857600080fd5b8460007f01000000000000000000000000000000000000000000000000000000000000000281600060208110151561330c57fe5b1a7f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415151561335e57600080fd5b8460007f01000000000000000000000000000000000000000000000000000000000000000281600060208110151561339257fe5b1a7f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141515156133e457600080fd5b60003390506133f1613adf565b60408051908101604052808a81526020018981525090506000600160048390806001815401808255809150509060018203906000526020600020906002020160009091929091909150600082015181600001556020820151816001015550500390508063ffffffff168114151561346757600080fd5b7f982bb66d9aa60573bc0a2066122e1466ecbc4c179a5e7c1c5b589345008ce69a8382604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a16134de6000848361381f565b8097505050505050505092915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561354957600080fd5b80600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600d6000838152602001908152602001600020805490509050919050565b60156020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600c6020528060005260406000206000915090505481565b60076020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60106020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008273ffffffffffffffffffffffffffffffffffffffff166005600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b806007600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561377b57600080fd5b600260149054906101000a900460ff16151561379657600080fd5b6000600260146101000a81548160ff021916908315150217905550565b60008273ffffffffffffffffffffffffffffffffffffffff166007600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614905092915050565b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001019190505550816005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614151561397d57600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001900391905055506007600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b7f70a295484349ac4c2073cdca8ba026869fff31e0d35e268f820e44c9d25f4a2e838383604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a1505050565b602060405190810160405280606081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613a7657805160ff1916838001178555613aa4565b82800160010185558215613aa4579182015b82811115613aa3578251825591602001919060010190613a88565b5b509050613ab19190613aff565b5090565b6020604051908101604052806000151581525090565b602060405190810160405280600081525090565b604080519081016040528060008019168152602001600080191681525090565b613b2191905b80821115613b1d576000816000905550600101613b05565b5090565b9056fea165627a7a72305820b73bf81476c95567782e45ebae5220573d46c55a9004c11243c470bc91f2d26d0029", - "storage": { - "0x05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xa54c2b4154b4f221d71d6d5bc0ec905c931a021bb6fb138fc0495bb0373e2276": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x0000000000000000000000000000000000000001": { - "balance": "0x0", - "nonce": "0", - "code": "0x", - "storage": {} - }, - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0xcec3d4daf44926cc41e", - "nonce": "147795", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "567688", - "difficulty": "2028219", - "timestamp": "1577578023", - "gasLimit": "23504477", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf9018f8302415385746a52880083048196948521f13dd5e4bc3dab3cf0f01a195a5af899e85180b90124200b1e64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001b9af799918107e9a339eba0584b8b60b35aae6f087c74f6bfc00c9301849b204d094ed65e09c76c2597f5516f9440aad2921e50dde096e7caaa65a536d4d9265e00000000000000000000000000000000000000000000000000000000000000504269747669657720697320616e20616d617a696e6720776562736974652e20596f752073686f756c6420646566696e6974656c792061646420796f75722070726f6475637420746f2069742e20e282bf0000000000000000000000000000000081a2a0686e4a69e1fa6cac6b4f751a3935ca5a371d720c34d3a7136988aa017a528ed5a07d993e607b665c24557d0eae166c21fe744e618ed3430902ac6206c63a331dc0", - "result": [ - { - "action": { - "author": "0x0000000000000000000000000000000000000000", - "address": "0x0000000000000000000000000000000000000000", - "balance": "0x0", - "callType": "call", - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "gas": "0x48196", - "input": "0x200b1e64000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000001b9af799918107e9a339eba0584b8b60b35aae6f087c74f6bfc00c9301849b204d094ed65e09c76c2597f5516f9440aad2921e50dde096e7caaa65a536d4d9265e00000000000000000000000000000000000000000000000000000000000000504269747669657720697320616e20616d617a696e6720776562736974652e20596f752073686f756c6420646566696e6974656c792061646420796f75722070726f6475637420746f2069742e20e282bf00000000000000000000000000000000", - "refundAddress": "0x0000000000000000000000000000000000000000", - "to": "0x8521f13dd5e4bc3dab3cf0f01a195a5af899e851", - "value": "0x0" - }, - "error": "execution reverted", - "result": { - "gasUsed": "0x947c" - }, - "subtraces": 0, - "traceAddress": [], - "type": "call" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json deleted file mode 100644 index 16d43767d5..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/suicide.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "genesis": { - "number": "553153", - "hash": "0x88bde20840880a1f3fba92121912a3cc0d3b26d76e4d914fbd85fc2e43da3b3f", - "nonce": "0x7be554ffe4b82fc2", - "mixHash": "0xf73d2ff3c16599c3b8a24b9ebde6c09583b5ee3f747d3cd37845d564f4c8d87a", - "stateRoot": "0x40b5f53d610108947688a04fb68838ff9c0aa0dd6e54156b682537192171ff5c", - "miner": "0x774c398d763161f55b66a646f17edda4addad2ca", - "difficulty": "1928226", - "totalDifficulty": "457857582215", - "extraData": "0xd983010907846765746888676f312e31332e358664617277696e", - "gasLimit": "7999473", - "timestamp": "1577392669", - "alloc": { - "0x877bd459c9b7d8576b44e59e09d076c25946f443": { - "balance": "0x19bb4ac611ca7a1fc881", - "nonce": "701", - "code": "0x", - "storage": {} - }, - "0x8ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91": { - "balance": "0x0", - "nonce": "1", - "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000877bd459c9b7d8576b44e59e09d076c25946f443" - } - } - }, - "config": { - "chainId": 63, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 0, - "eip158Block": 0, - "ethash": {}, - "homesteadBlock": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 301243, - "petersburgBlock": 999983, - "istanbulBlock": 999983 - } - }, - "context": { - "number": "553154", - "difficulty": "1929167", - "timestamp": "1577392670", - "gasLimit": "8000000", - "miner": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "input": "0xf86c8202bd850ee6b280008344aa20948ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91808441c0e1b581a2a03f95ca5cdf7fd727630341c4c6aa1b64ccd9949bd9ecc72cfdd7ce17a2013a69a06d34795ef7fb0108a6dbee4ae0a1bdc48dcd2a4ee53bb6a33d45515af07bb9a8", - "result": [ - { - "action": { - "callType": "call", - "from": "0x877bd459c9b7d8576b44e59e09d076c25946f443", - "gas": "0x44aa20", - "input": "0x41c0e1b5", - "to": "0x8ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91", - "value": "0x0" - }, - "blockHash": "0xf641c3b0f82b07cd3a528adb9927dd83eeb4f1682e2bd523ed36888e0d82c9a9", - "blockNumber": 553154, - "result": { - "gasUsed": "0x347a", - "output": "0x" - }, - "subtraces": 1, - "traceAddress": [], - "transactionHash": "0x6af0a5c3188ffacae4d340d4a17e14fdb5a54187683a80ef241bde248189882b", - "transactionPosition": 15, - "type": "call" - }, - { - "action": { - "address": "0x8ee79c5b3f6e1d214d2c4fcf7ea4092a32e26e91", - "balance": "0x0", - "refundAddress": "0x877bd459c9b7d8576b44e59e09d076c25946f443" - }, - "blockHash": "0xf641c3b0f82b07cd3a528adb9927dd83eeb4f1682e2bd523ed36888e0d82c9a9", - "blockNumber": 553154, - "subtraces": 0, - "traceAddress": [ - 0 - ], - "transactionHash": "0x6af0a5c3188ffacae4d340d4a17e14fdb5a54187683a80ef241bde248189882b", - "transactionPosition": 15, - "type": "suicide" - } - ] -} \ No newline at end of file diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json deleted file mode 100644 index a001178a42..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_flat/throw.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "context": { - "difficulty": "117009631", - "gasLimit": "4712388", - "miner": "0x294e5d6c39a36ce38af1dca70c1060f78dee8070", - "number": "25009", - "timestamp": "1479891666" - }, - "genesis": { - "alloc": { - "0x70c9217d814985faef62b124420f8dfbddd96433": { - "balance": "0x4ecd70668f5d854a", - "code": "0x", - "nonce": "1638", - "storage": {} - }, - "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": { - "balance": "0x0", - "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000061a9", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433" - } - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "117066792", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712388", - "hash": "0xe23e8d4562a1045b70cbc99fefb20c101a8f0fc8559a80d65fea8896e2f1d46e", - "miner": "0x71842f946b98800fe6feb49f0ae4e253259031c9", - "mixHash": "0x0aada9d6e93dd4db0d09c0488dc0a048fca2ccdc1f3fc7b83ba2a8d393a3a4ff", - "nonce": "0x70849d5838dee2e9", - "number": "25008", - "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b", - "timestamp": "1479891641", - "totalDifficulty": "1896347038589" - }, - "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750", - "result": [ - { - "action": { - "callType": "call", - "from": "0x70c9217d814985faef62b124420f8dfbddd96433", - "gas": "0x3d090", - "input": "0x51a34eb8000000000000000000000000000000000000000000000027fad02094277c0000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "value": "0x0" - }, - "blockNumber": 25009, - "error": "invalid jump destination", - "result": {}, - "subtraces": 0, - "traceAddress": [], - "type": "call" - } - ] -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json deleted file mode 100644 index df0b2872b4..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/create.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "context": { - "difficulty": "3755480783", - "gasLimit": "5401723", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "number": "2294702", - "timestamp": "1513676146" - }, - "genesis": { - "alloc": { - "0x13e4acefe6a6700604929946e70e6443e4e73447": { - "balance": "0xcf3e0938579f000", - "code": "0x", - "nonce": "9", - "storage": {} - }, - "0x7dc9c9730689ff0b0fd506c67db815f12d90a448": { - "balance": "0x0", - "code": "0x", - "nonce": "0", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3757315409", - "extraData": "0x566961425443", - "gasLimit": "5406414", - "hash": "0xae107f592eebdd9ff8d6ba00363676096e6afb0e1007a7d3d0af88173077378d", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "mixHash": "0xc927aa05a38bc3de864e95c33b3ae559d3f39c4ccd51cef6f113f9c50ba0caf1", - "nonce": "0x93363bbd2c95f410", - "number": "2294701", - "stateRoot": "0x6b6737d5bde8058990483e915866bd1578014baeff57bd5e4ed228a2bfad635c", - "timestamp": "1513676127", - "totalDifficulty": "7160808139332585" - }, - "input": "0xf907ef098504e3b29200830897be8080b9079c606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a1129a01060f46676a5dff6f407f0f51eb6f37f5c8c54e238c70221e18e65fc29d3ea65a0557b01c50ff4ffaac8ed6e5d31237a4ecbac843ab1bfe8bb0165a0060df7c54f", - "result": { - "from": "0x13e4acefe6a6700604929946e70e6443e4e73447", - "gas": "0x897be", - "gasUsed": "0x897be", - "input": "0x606060405260405160208061077c83398101604052808051906020019091905050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415151561007d57600080fd5b336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506001600460006101000a81548160ff02191690831515021790555050610653806101296000396000f300606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029000000000000000000000000c65e620a3a55451316168d57e268f5702ef56a11", - "output": "0x606060405260043610610083576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806305e4382a146100855780631c02708d146100ae5780632e1a7d4d146100c35780635114cb52146100e6578063a37dda2c146100fe578063ae200e7914610153578063b5769f70146101a8575b005b341561009057600080fd5b6100986101d1565b6040518082815260200191505060405180910390f35b34156100b957600080fd5b6100c16101d7565b005b34156100ce57600080fd5b6100e460048080359060200190919050506102eb565b005b6100fc6004808035906020019091905050610513565b005b341561010957600080fd5b6101116105d6565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561015e57600080fd5b6101666105fc565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156101b357600080fd5b6101bb610621565b6040518082815260200191505060405180910390f35b60025481565b60011515600460009054906101000a900460ff1615151415156101f957600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102a15750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b15156102ac57600080fd5b6000600460006101000a81548160ff0219169083151502179055506003543073ffffffffffffffffffffffffffffffffffffffff163103600281905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806103935750600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b151561039e57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561048357600060025411801561040757506002548111155b151561041257600080fd5b80600254036002819055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561047e57600080fd5b610510565b600060035411801561049757506003548111155b15156104a257600080fd5b8060035403600381905550600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561050f57600080fd5b5b50565b60011515600460009054906101000a900460ff16151514151561053557600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614801561059657506003548160035401115b80156105bd575080600354013073ffffffffffffffffffffffffffffffffffffffff163110155b15156105c857600080fd5b806003540160038190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600354815600a165627a7a72305820c3b849e8440987ce43eae3097b77672a69234d516351368b03fe5b7de03807910029", - "to": "0x7dc9c9730689ff0b0fd506c67db815f12d90a448", - "type": "CREATE", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json deleted file mode 100644 index 80fc0b0ada..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/deep_calls.json +++ /dev/null @@ -1,415 +0,0 @@ -{ - "context": { - "difficulty": "117066904", - "gasLimit": "4712384", - "miner": "0x1977c248e1014cc103929dd7f154199c916e39ec", - "number": "25001", - "timestamp": "1479891545" - }, - "genesis": { - "alloc": { - "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a600035046302d05d3f811461008a5780630accce061461009c5780631ab9075a146100c757806331ed274614610102578063645a3b7214610133578063772fdae314610155578063a7f4377914610180578063ae5f80801461019e578063c9bded21146101ea578063f905c15a14610231575b61023a610002565b61023c600054600160a060020a031681565b61023a600435602435604435606435608435600254600160a060020a03166000141561024657610002565b61023a600435600254600160a060020a03166000148015906100f8575060025433600160a060020a03908116911614155b156102f457610002565b61023a60043560243560443560643560843560a43560c435600254600160a060020a03166000141561031657610002565b61023a600435602435600254600160a060020a0316600014156103d057610002565b61023a600435602435604435606435608435600254600160a060020a03166000141561046157610002565b61023a60025433600160a060020a0390811691161461051657610002565b61023a6004356024356044356060828152600160a060020a0382169060ff8516907fa6c2f0913db6f79ff0a4365762c61718973b3413d6e40382e704782a9a5099f690602090a3505050565b61023a600435602435600160a060020a038116606090815260ff8316907fee6348a7ec70f74e3d6cba55a53e9f9110d180d7698e9117fc466ae29a43e34790602090a25050565b61023c60035481565b005b6060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061029d57610002565b60408051858152602081018390528151600160a060020a03858116939087169260ff8a16927f5a690ecd0cb15c1c1fd6b6f8a32df0d4f56cb41a54fea7e94020f013595de796929181900390910190a45050505050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061036d57610002565b6040805186815260208101869052808201859052606081018490529051600160a060020a03831691889160ff8b16917fd65d9ddafbad8824e2bbd6f56cc9f4ac27ba60737035c10a321ea2f681c94d47919081900360800190a450505050505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f115610002575050604051511515905061042757610002565b60408051828152905183917fa9c6cbc4bd352a6940479f6d802a1001550581858b310d7f68f7bea51218cda6919081900360200190a25050565b60025460e060020a6313bc6d4b02606090815233600160a060020a0390811660645291909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104b857610002565b80600160a060020a031684600160a060020a03168660ff167f69bdaf789251e1d3a0151259c0c715315496a7404bce9fd0b714674685c2cab78686604051808381526020018281526020019250505060405180910390a45050505050565b600254600160a060020a0316ff", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0x2cccf5e0538493c235d1c5ef6580f77d99e91396": { - "balance": "0x0", - "code": "0x606060405236156100775760e060020a600035046302d05d3f811461007f57806313bc6d4b146100915780633688a877146100b95780635188f9961461012f5780637eadc976146101545780638ad79680146101d3578063a43e04d814610238578063a7f437791461025e578063e16c7d981461027c575b61029f610002565b6102a1600054600160a060020a031681565b6102be600435600160a060020a03811660009081526002602052604090205460ff165b919050565b6102d26004356040805160208181018352600080835284815260038252835190849020805460026001821615610100026000190190911604601f8101849004840283018401909552848252929390929183018282801561037d5780601f106103525761010080835404028352916020019161037d565b61029f6004356024356000805433600160a060020a039081169116146104a957610002565b61034060043560008181526001602090815260408083205481517ff905c15a0000000000000000000000000000000000000000000000000000000081529151600160a060020a03909116928392839263f905c15a92600483810193919291829003018189876161da5a03f1156100025750506040515195945050505050565b60408051602060248035600481810135601f810185900485028601850190965285855261029f9581359591946044949293909201918190840183828082843750949650505050505050600054600160a060020a0390811633909116146104f657610002565b61029f6004355b600080548190600160a060020a0390811633909116146105a457610002565b61029f60005433600160a060020a0390811691161461072957610002565b6102a1600435600081815260016020526040902054600160a060020a03166100b4565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156103325780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161036057829003601f168201915b505050505090506100b4565b506000828152600160208181526040808420805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a038581168086526002909352818520805460ff191690941790935580517f1ab9075a0000000000000000000000000000000000000000000000000000000081523090931660048401525184939192631ab9075a926024828101939192829003018183876161da5a03f11561000257505060408051602081018690528082019290925243606083015260808083526003908301527f414444000000000000000000000000000000000000000000000000000000000060a0830152517f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d39181900360c00190a15b505050565b600083815260016020526040902054600160a060020a03838116911614156104d0576104a4565b600083815260016020526040812054600160a060020a031614610389576103898361023f565b600082815260036020908152604082208054845182855293839020919360026001831615610100026000190190921691909104601f90810184900483019391929186019083901061056a57805160ff19168380011785555b5061059a9291505b808211156105a05760008155600101610556565b8280016001018555821561054e579182015b8281111561054e57825182600050559160200191906001019061057c565b50505050565b5090565b600083815260016020526040812054600160a060020a031614156105c757610002565b50506000818152600160205260408082205481517fa7f437790000000000000000000000000000000000000000000000000000000081529151600160a060020a0391909116928392839263a7f4377992600483810193919291829003018183876161da5a03f11561000257505050600160005060008460001916815260200190815260200160002060006101000a815490600160a060020a0302191690556002600050600083600160a060020a0316815260200190815260200160002060006101000a81549060ff02191690557f8ac68d4e97d65912f220b4c5f87978b8186320a5e378c1369850b5b5f90323d383834360405180806020018560001916815260200184600160a060020a03168152602001838152602001828103825260038152602001807f44454c000000000000000000000000000000000000000000000000000000000081526020015060200194505050505060405180910390a1505050565b600054600160a060020a0316ff", - "nonce": "1", - "storage": { - "0x0684ac65a9fa32414dda56996f4183597d695987fdb82b145d722743891a6fe8": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "0x1cd76f78169a420d99346e3501dd3e541622c38a226f9b63e01cfebc69879dc7": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "0x8e54a4494fe5da016bfc01363f4f6cdc91013bb5434bd2a4a3359f13a23afa2f": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf", - "0x94edf7f600ba56655fd65fca1f1424334ce369326c1dc3e53151dcd1ad06bc13": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xbbee47108b275f55f98482c6800f6372165e88b0330d3f5dae6419df4734366c": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "0xd38c0c4e84de118cfdcc775130155d83b8bbaaf23dc7f3c83a626b10473213bd": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xfb3aa5c655c2ec9d40609401f88d505d1da61afaa550e36ef5da0509ada257ba": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113" - } - }, - "0x3e9286eafa2db8101246c2131c09b49080d00690": { - "balance": "0x0", - "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063056d4470146100e957806316c66cc61461010c5780631ab9075a146101935780633ae1005c146101ce57806358541662146101fe5780635ed61af014610231578063644e3b791461025457806384dbac3b146102db578063949ae479146102fd5780639859387b14610321578063a7f4377914610340578063ab03fc261461035e578063e8161b7814610385578063e964d4e114610395578063f905c15a146103a5578063f92eb774146103ae575b6103be610002565b6103c0600054600160a060020a031681565b6103be6004356002546000908190600160a060020a031681141561040357610002565b6103dd60043560006108365b6040805160025460e360020a631c2d8fb30282527f636f6e747261637464620000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435600254600160a060020a03166000148015906101c4575060025433600160a060020a03908116911614155b1561088d57610002565b6103be600435602435604435606435600254600090819081908190600160a060020a03168114156108af57610002565b6103c0600435602435604435606435608435600254600090819081908190600160a060020a03168114156110e857610002565b6103be6004356002546000908190600160a060020a03168114156115ec57610002565b6103c06004356000611b635b6040805160025460e360020a631c2d8fb30282527f6d61726b6574646200000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b6103be600435602435600254600160a060020a031660001415611bb557610002565b6103be600435602435600254600090600160a060020a0316811415611d2e57610002565b6103be600435600254600160a060020a031660001415611fc657610002565b6103be60025433600160a060020a0390811691161461207e57610002565b6103be600435602435604435600254600090600160a060020a031681141561208c57610002565b6103dd60043560006124b8610260565b6103c0600435600061250a610118565b6103f160035481565b6103f16004356000612561610260565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061046557610002565b8291506104e55b6040805160025460e360020a631c2d8fb30282527f63706f6f6c00000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f115610002575050604051519150505b90565b600160a060020a031663b2206e6d83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fb2206e6d0000000000000000000000000000000000000000000000000000000082526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f11561000257505060405151915061059b90506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f115610002575050506107355b6040805160025460e360020a631c2d8fb30282527f6c6f676d6772000000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b50826120ee5b6040805160025460e360020a631c2d8fb30282527f6163636f756e7463746c0000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316630accce06600684600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150866040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050505050565b600160a060020a03166316c66cc6836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150505b919050565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061091157610002565b87935061091c610260565b600160a060020a031663bdbdb08685600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fbdbdb0860000000000000000000000000000000000000000000000000000000082526004820152602481018a905290516044808301935060209282900301816000876161da5a03f1156100025750506040515193506109ca90506106ba565b600160a060020a03166381982a7a8885876040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610a3661046c565b600160a060020a03166308636bdb85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517f08636bdb000000000000000000000000000000000000000000000000000000008252600482015260248101889052604481019290925251606482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919450600160a060020a03871692506314baa1b6916024828101926000929190829003018183876161da5a03f11561000257505050610b3561046c565b600160a060020a0316630a3b6ede85600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038d16602482015290516044808301935060209282900301816000876161da5a03f115610002575050604051519150610bd590506106ba565b600160a060020a031663d5b205ce87838b6040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f11561000257505050610c41610118565b600160a060020a031663988db79c888a6040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050610ca5610260565b600160a060020a031663f4f2821b896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610d6f5b6040805160025460e360020a631c2d8fb30282527f747261646564620000000000000000000000000000000000000000000000000060048301529151600092600160a060020a03169163e16c7d98916024828101926020929190829003018187876161da5a03f1156100025750506040515191506104e29050565b600160a060020a0316635f539d69896040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050610dc2610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928e9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610ec5610639565b600160a060020a0316630accce06600386600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6315b1ea01028252915191928e928d9263ad8f500891600482810192602092919082900301816000876161da5a03f11561000257505050604051805190602001506040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050610fc8610639565b600160a060020a031663645a3b7285600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151905061101e610260565b600160a060020a031663f92eb77488600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f115610002575050505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061114a57610002565b604051600254600160a060020a0316908a908a908a908a908a90611579806125b38339018087600160a060020a0316815260200186600160a060020a03168152602001856000191681526020018481526020018381526020018281526020019650505050505050604051809103906000f092506111c5610118565b600160a060020a031663b9858a288a856040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611229610260565b600160a060020a0316635188f99689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611288610260565b600160a060020a031663bdbdb08689896040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515192506112e590506106ba565b600160a060020a03166346d88e7d8a858a6040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506000604051808303816000876161da5a03f115610002575050506113516106ba565b600160a060020a03166381982a7a8a84866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050506113bd61046c565b600160a060020a0316632b58469689856040518360e060020a028152600401808360001916815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f1156100025750505061141c61046c565b600160a060020a03166308636bdb8984866040518460e060020a028152600401808460001916815260200183815260200182600160a060020a0316815260200193505050506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630a5d50db028252600482018190529151919350600160a060020a03861692506314baa1b6916024828101926000929190829003018183876161da5a03f115610002575050506114d3610639565b6040805160e160020a630566670302815260016004820152602481018b9052600160a060020a0386811660448301528c811660648301526000608483018190529251931692630accce069260a480840193919291829003018183876161da5a03f11561000257505050611544610639565b600160a060020a031663645a3b728961155b610260565b600160a060020a031663f92eb7748c6040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448084019360009350829003018183876161da5a03f1156100025750939a9950505050505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061164e57610002565b82915061165961046c565b600160a060020a0316630a3b6ede83600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63051db76f0282526004820152600160a060020a038816602482015290516044808301935060209282900301816000876161da5a03f1156100025750506040515191506116f990506106ba565b600160a060020a031663d5b205ce83600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a636ad902e7028252600160a060020a0390811660048301526024820187905288166044820152905160648281019350600092829003018183876161da5a03f1156100025750505061179b6106ba565b600160a060020a031663d653078983600160a060020a03166336da44686040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517ff1ff78a0000000000000000000000000000000000000000000000000000000008252915191929163f1ff78a09160048181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150866040518460e060020a0281526004018084600160a060020a0316815260200183815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f1156100025750505061189f610260565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506118f2610118565b600160a060020a031663f4f2821b846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050611945610639565b600160a060020a0316630accce06600484600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d02825291519192899290916336da44689181870191602091908190038801816000876161da5a03f115610002575050506040518051906020015060006040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f11561000257505050611a48610639565b600160a060020a031663645a3b7283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611a9e610260565b600160a060020a031663f92eb77486600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b600160a060020a03166381738c59836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611c1757610002565b611c1f610260565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f11561000257505060405151159050611c7457610002565b611c7c610260565b600160a060020a0316632243118a836040518260e060020a02815260040180826000191681526020019150506000604051808303816000876161da5a03f11561000257505050611cca610639565b600160a060020a031663ae5f8080600184846040518460e060020a028152600401808481526020018360001916815260200182600160a060020a0316815260200193505050506000604051808303816000876161da5a03f115610002575050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f1156100025750506040515115159050611d9057610002565b5081611d9a610260565b600160a060020a031663581d5d6084846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506000604051808303816000876161da5a03f11561000257505050611df5610639565b600160a060020a0316630accce06600283600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a630566670302825260048201949094526024810193909352600160a060020a038816604484015260006064840181905260848401819052905160a4808501949293509091829003018183876161da5a03f11561000257505050611eab610639565b600160a060020a031663645a3b7282600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519050611f01610260565b600160a060020a031663f92eb77485600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a633e4baddd028252600482015290516024828101935060209282900301816000876161da5a03f11561000257505060408051805160e060020a86028252600482019490945260248101939093525160448381019360009350829003018183876161da5a03f11561000257505050505050565b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061202857610002565b612030610118565b600160a060020a0316639859387b826040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505050565b600254600160a060020a0316ff5b6040805160025460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f11561000257505060405151151590506106b457610002565b600160a060020a031663d65307898383600160a060020a031663f1ff78a06040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fd6530789000000000000000000000000000000000000000000000000000000008252600160a060020a039485166004830152602482015292891660448401525160648381019360009350829003018183876161da5a03f115610002575050506121a5610118565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506121f8610cf4565b600160a060020a031663f4f2821b856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f1156100025750505061224b610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e360020a6306db488d028252915191928a9290916336da446891600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f1156100025750505080600160a060020a031663ea71b02d6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a031660001490506124b25761239f610639565b600160a060020a0316630accce06600583600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fea71b02d000000000000000000000000000000000000000000000000000000008252915191928a92909163ea71b02d91600482810192602092919082900301816000876161da5a03f1156100025750505060405180519060200150886040518660e060020a028152600401808681526020018560001916815260200184600160a060020a0316815260200183600160a060020a03168152602001828152602001955050505050506000604051808303816000876161da5a03f115610002575050505b50505050565b600160a060020a03166338a699a4836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663213fe2b7836040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191506108889050565b600160a060020a031663f92eb774836040518260e060020a02815260040180826000191681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610888905056606060405260405160c08061157983396101206040819052825160805160a051935160e0516101005160008054600160a060020a03199081163317909155600180546005805484168817905560048a90556006869055600b8590556008849055909116861760a060020a60ff02191690554360038190556002558686526101408390526101608190529396929594919390929091600160a060020a033016917f76885d242fb71c6f74a7e717416e42eff4d96faf54f6de75c6a0a6bbd8890c6b91a230600160a060020a03167fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff600b600050546040518082815260200191505060405180910390a250505050505061145e8061011b6000396000f3606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "16", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0x70c9217d814985faef62b124420f8dfbddd96433": { - "balance": "0x4ef436dcbda6cd4a", - "code": "0x", - "nonce": "1634", - "storage": {} - }, - "0x7986bad81f4cbd9317f5a46861437dae58d69113": { - "balance": "0x0", - "code": "0x6060604052361561008d5760e060020a600035046302d05d3f811461009557806316c66cc6146100a75780631ab9075a146100d7578063213fe2b7146101125780639859387b1461013f578063988db79c1461015e578063a7f4377914610180578063b9858a281461019e578063c8e40fbf146101c0578063f4f2821b146101e8578063f905c15a14610209575b610212610002565b610214600054600160a060020a031681565b600160a060020a0360043581811660009081526005602052604081205461023193168114610257575060016101e3565b610212600435600254600160a060020a0316600014801590610108575060025433600160a060020a03908116911614155b1561025f57610002565b610214600435600160a060020a03811660009081526004602052604081205460ff16151561027557610002565b610212600435600254600160a060020a03166000141561029b57610002565b610212600435602435600254600160a060020a03166000141561050457610002565b61021260025433600160a060020a0390811691161461056757610002565b610212600435602435600254600160a060020a03166000141561057557610002565b610231600435600160a060020a03811660009081526004602052604090205460ff165b919050565b610212600435600254600090600160a060020a031681141561072057610002565b61024560035481565b005b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060006101e3565b60028054600160a060020a031916821790555b50565b50600160a060020a038181166000908152600460205260409020546101009004166101e3565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506102fe57610002565b600160a060020a03811660009081526004602052604090205460ff161515610272576040516104028061092e833901809050604051809103906000f06004600050600083600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600083600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555050565b600160a060020a03821660009081526004602052604090205460ff1615156104725760405161040280610d30833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a03811660009081526006602052604090208054600160a060020a031916831790555b5050565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506103b957610002565b600254600160a060020a0316ff5b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f11561000257505060405151151590506105d857610002565b600160a060020a03821660009081526004602052604090205460ff1615156106915760405161040280611132833901809050604051809103906000f06004600050600084600160a060020a0316815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555060016004600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff021916908302179055505b600160a060020a03828116600090815260046020819052604080518184205460e060020a630a3b0a4f02825286861693820193909352905161010090920490931692630a3b0a4f926024828101939192829003018183876161da5a03f11561000257505050600160a060020a031660009081526005602052604090208054600160a060020a0319169091179055565b6002546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602482810192602092919082900301816000876161da5a03f115610002575050604051511515905061078357610002565b50600160a060020a0381811660009081526005602090815260408083205490931680835260049091529190205460ff161561080f576040600081812054825160e260020a632e72bafd028152600160a060020a03868116600483015293516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260056020526040812054909116146108545760406000908120600160a060020a0384169091528054600160a060020a03191690555b50600160a060020a0381811660009081526006602090815260408083205490931680835260049091529190205460ff16156108e657600160a060020a038181166000908152604080518183205460e260020a632e72bafd028252868516600483015291516101009092049093169263b9caebf4926024828101939192829003018183876161da5a03f115610002575050505b600160a060020a03828116600090815260066020526040812054909116146105005760406000908120600160a060020a0384169091528054600160a060020a0319169055505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056", - "nonce": "7", - "storage": { - "0xffc4df2d4f3d2cffad590bed6296406ab7926ca9e74784f74a95191fa069a174": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433" - } - }, - "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f": { - "balance": "0x0", - "code": "0x606060405236156100ae5760e060020a600035046302d05d3f81146100b65780631ab9075a146100c85780632b68bb2d146101035780634cc927d7146101c557806351a34eb81461028e57806356ccb6f0146103545780635928d37f1461041d578063599efa6b146104e9578063759297bb146105b2578063771d50e11461067e578063a7f4377914610740578063f905c15a1461075e578063f92eb77414610767578063febf661214610836575b610902610002565b610904600054600160a060020a031681565b610902600435600254600160a060020a03166000148015906100f9575060025433600160a060020a03908116911614155b1561092057610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061094257610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610a0d57610002565b61090260043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ae957610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610bbc57610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610c9657610002565b61090260043560243560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610de057610002565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610ebb57610002565b60025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b02606452610902916000918291600160a060020a03169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f9e57610002565b61090260025433600160a060020a0390811691161461106957610002565b61090e60035481565b61090e60043560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750506040805180517ff92eb774000000000000000000000000000000000000000000000000000000008252600482018790529151919350600160a060020a038416925063f92eb774916024828101926020929190829003018188876161da5a03f11561000257505060405151949350505050565b61090260043560243560443560025460e360020a631c2d8fb302606090815260aa60020a6a18dbdb9d1c9858dd18dd1b026064526000918291600160a060020a039091169063e16c7d989060849060209060248187876161da5a03f1156100025750505060405180519060200150905080600160a060020a03166316c66cc6336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051511515905061107757610002565b005b6060908152602090f35b60408051918252519081900360200190f35b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5ed61af000000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152925190959286169350635ed61af092602483810193919291829003018183876161da5a03f115610002575050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fab03fc2600000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015260248301899052808816604484015292519095928616935063ab03fc2692606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f949ae47900000000000000000000000000000000000000000000000000000000825233600160a060020a0390811660048401526024830188905292519095928616935063949ae47992604483810193919291829003018183876161da5a03f11561000257505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f46d88e7d000000000000000000000000000000000000000000000000000000008252600160a060020a0380891660048401523381166024840152604483018890529251909592861693506346d88e7d92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5315cdde00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a16602484015260448301889052925190959286169350635315cdde92606483810193919291829003018183876161da5a03f115610002575050604080517f5928d37f00000000000000000000000000000000000000000000000000000000815233600160a060020a03908116600483015287166024820152604481018690529051635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517fe68e401c00000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015280891660248401526044830188905292519095928616935063e68e401c92606483810193919291829003018183876161da5a03f1156100025750505050505050565b6040805160025460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f5152f381000000000000000000000000000000000000000000000000000000008252600160a060020a03808a1660048401528089166024840152604483018890523381166064840152925190959286169350635152f38192608483810193919291829003018183876161da5a03f115610002575050505050505050565b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f056d447000000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015292519095928616935063056d447092602483810193919291829003018183876161da5a03f115610002575050505050565b600254600160a060020a0316ff5b6040805160025460e360020a631c2d8fb302825260aa60020a6a18dbdb9d1c9858dd18dd1b0260048301529151600160a060020a03929092169163e16c7d9891602481810192602092909190829003018188876161da5a03f1156100025750506040805180517f3ae1005c00000000000000000000000000000000000000000000000000000000825233600160a060020a039081166004840152808a166024840152808916604484015260648301889052925190959286169350633ae1005c92608483810193919291829003018183876161da5a03f11561000257505050505050505056", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396" - } - }, - "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": { - "balance": "0x0", - "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000006195", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5842545553440000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000" - } - }, - "0xcf00ffd997ad14939736f026006498e3f099baaf": { - "balance": "0x0", - "code": "0x606060405236156100cf5760e060020a600035046302d05d3f81146100d7578063031e7f5d146100e95780631ab9075a1461010b5780632243118a1461014657806327aad68a1461016557806338a699a4146101da5780635188f996146101f8578063581d5d601461021e57806381738c5914610246578063977da54014610269578063a07421ce14610288578063a7f43779146102be578063bdbdb086146102dc578063e1c7111914610303578063f4f2821b14610325578063f905c15a1461034a578063f92eb77414610353575b610387610002565b610389600054600160a060020a031681565b610387600435602435600254600160a060020a0316600014156103a857610002565b610387600435600254600160a060020a031660001480159061013c575060025433600160a060020a03908116911614155b1561042957610002565b610387600435600254600160a060020a03166000141561044b57610002565b6102ac60043560008181526004602081815260408320547f524d81d3000000000000000000000000000000000000000000000000000000006060908152610100909104600160a060020a031692839263524d81d3926064928188876161da5a03f1156100025750506040515192506103819050565b61039c60043560008181526004602052604090205460ff165b919050565b6103876004356024356002546000908190600160a060020a031681141561079457610002565b61038760043560243560025460009081908190600160a060020a031681141561080457610002565b61038960043560008181526004602052604081205460ff1615156109e357610002565b610387600435600254600160a060020a0316600014156109fb57610002565b600435600090815260096020526040902054670de0b6b3a764000090810360243502045b60408051918252519081900360200190f35b61038760025433600160a060020a03908116911614610a9257610002565b600435600090815260086020526040902054670de0b6b3a7640000602435909102046102ac565b610387600435602435600254600160a060020a031660001415610aa057610002565b61038760043560025460009081908190600160a060020a0316811415610b3657610002565b6102ac60035481565b6102ac600435600081815260076020908152604080832054600690925290912054670de0b6b3a76400000204805b50919050565b005b600160a060020a03166060908152602090f35b15156060908152602090f35b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506103fe57610002565b60008281526004602052604090205460ff16151561041b57610002565b600860205260406000205550565b6002805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f11561000257505060405151151590506104a157610002565b604080516000838152600460205291909120805460ff1916600117905561040280610de2833901809050604051809103906000f0600460005060008360001916815260200190815260200160002060005060000160016101000a815481600160a060020a030219169083021790555066470de4df8200006008600050600083600019168152602001908152602001600020600050819055506703782dace9d9000060096000506000836000191681526020019081526020016000206000508190555050565b600460005060008560001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151821415905061060057838152600660209081526040808320839055600790915281208190555b81600160a060020a0316630a3b0a4f846040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f11561000257505050600160a060020a038316808252600560209081526040808420879055805160e160020a6364a81ff102815290518694670de0b6b3a7640000949363c9503fe29360048181019492939183900301908290876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008660001916815260200190815260200160002060008282825054019250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000866000191681526020019081526020016000206000828282505401925050819055505b50505050565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f11561000257505060405151151590506107e957610002565b8381526004602052604081205460ff16151561056657610002565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f115610002575050604051511515905061085957610002565b849250670de0b6b3a764000083600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575060408051805160e160020a6364a81ff102825291519189028590049650600481810192602092909190829003018188876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b9391600481810192602092909190829003018189876161da5a03f115610002575050506040518051906020015002049050806006600050600085600160a060020a0316632e94420f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750604080518051855260208681528286208054989098039097557f2e94420f00000000000000000000000000000000000000000000000000000000815290518896600483810193919291829003018187876161da5a03f115610002575050604080515183526020939093525020805490910190555050505050565b60409020546101009004600160a060020a03166101f3565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610a5157610002565b60008181526004602052604090205460ff161515610a6e57610002565b6040600020805474ffffffffffffffffffffffffffffffffffffffffff1916905550565b600254600160a060020a0316ff5b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b906084906020906024816000876161da5a03f1156100025750506040515115159050610af657610002565b60008281526004602052604090205460ff161515610b1357610002565b670de0b6b3a7640000811115610b2857610002565b600960205260406000205550565b60025460e060020a6313bc6d4b02606090815233600160a060020a03908116606452909116906313bc6d4b9060849060209060248187876161da5a03f1156100025750506040515115159050610b8b57610002565b600160a060020a038416815260056020908152604080832054808452600490925282205490935060ff161515610bc057610002565b600460005060008460001916815260200190815260200160002060005060000160019054906101000a9004600160a060020a0316915081600160a060020a031663b9caebf4856040518260e060020a0281526004018082600160a060020a031681526020019150506000604051808303816000876161da5a03f115610002575050506005600050600085600160a060020a0316815260200190815260200160002060005060009055839050600082600160a060020a031663524d81d36040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519190911115905061078e57670de0b6b3a764000081600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e060020a636f265b930282529151919291636f265b939160048181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001500204600660005060008560001916815260200190815260200160002060008282825054039250508190555080600160a060020a031663c9503fe26040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050506040518051906020015060076000506000856000191681526020019081526020016000206000828282505403925050819055505050505056606060405260008054600160a060020a031916331790556103de806100246000396000f3606060405236156100615760e060020a600035046302d05d3f81146100695780630a3b0a4f1461007b5780630d327fa7146100f6578063524d81d314610109578063a7f4377914610114578063b9caebf414610132578063bbec3bae14610296575b6102ce610002565b6102d0600054600160a060020a031681565b6102ce600435600254600090600160a060020a03168114156102ed5760028054600160a060020a03199081168417808355600160a060020a03808616855260036020526040852060018101805493831694909316939093179091559154815461010060a860020a031916921661010002919091179055610372565b6102d0600254600160a060020a03165b90565b6102e3600154610106565b6102ce60005433600160a060020a039081169116146103c657610002565b6102ce600435600160a060020a038116600090815260036020526040812054819060ff16801561016457506001548190115b1561029157506040808220600180820154915461010090819004600160a060020a039081168087528587209093018054600160a060020a031916948216948517905583865293909420805461010060a860020a03191694820294909417909355600254909190811690841614156101e85760028054600160a060020a031916821790555b600254600160a060020a0390811690841614156102105760028054600160a060020a03191690555b6003600050600084600160a060020a0316815260200190815260200160002060006000820160006101000a81549060ff02191690556000820160016101000a815490600160a060020a0302191690556001820160006101000a815490600160a060020a03021916905550506001600081815054809291906001900391905055505b505050565b600160a060020a036004358181166000908152600360205260408120600101546002546102d09491821691168114156103d4576103d8565b005b600160a060020a03166060908152602090f35b6060908152602090f35b60028054600160a060020a03908116835260036020526040808420805461010060a860020a0319808216610100808a029190911790935590829004841680875283872060019081018054600160a060020a03199081168b179091559654868a168952949097209687018054949095169390951692909217909255835416908202179091555b60016003600050600084600160a060020a0316815260200190815260200160002060005060000160006101000a81548160ff0219169083021790555060016000818150548092919060010191905055505050565b600054600160a060020a0316ff5b8091505b5091905056", - "nonce": "3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x3571d73f14f31a1463bd0a2f92f7fde1653d4e1ead7aedf4b0a5df02f16092ab": "0x0000000000000000000000000000000000000000000007d634e4c55188be0000", - "0x4e64fe2d1b72d95a0a31945cc6e4f4e524ac5ad56d6bd44a85ec7bc9cc0462c0": "0x000000000000000000000000000000000000000000000002b5e3af16b1880000" - } - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "117124093", - "extraData": "0xd5830105008650617269747986312e31322e31826d61", - "gasLimit": "4707788", - "hash": "0xad325e4c49145fb7a4058a68ac741cc8607a71114e23fc88083c7e881dd653e7", - "miner": "0x00714b9ac97fd6bd9325a059a70c9b9fa94ce050", - "mixHash": "0x0af918f65cb4af04b608fc1f14a849707696986a0e7049e97ef3981808bcc65f", - "nonce": "0x38dee147326a8d40", - "number": "25000", - "stateRoot": "0xc5d6bbcd46236fcdcc80b332ffaaa5476b980b01608f9708408cfef01b58bd5b", - "timestamp": "1479891517", - "totalDifficulty": "1895410389427" - }, - "input": "0xf88b8206628504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb80000000000000000000000000000000000000000000000280faf689c35ac00002aa0a7ee5b7877811bf671d121b40569462e722657044808dc1d6c4f1e4233ec145ba0417e7543d52b65738d9df419cbe40a708424f4d54b0fc145c0a64545a2bb1065", - "result": { - "calls": [ - { - "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "gas": "0x31217", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e7472616374617069000000000000000000000000000000000000000000", - "output": "0x000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x2a68d", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x23ac9", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e7472616374646200000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000007986bad81f4cbd9317f5a46861437dae58d69113", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x23366", - "gasUsed": "0x273", - "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x7986bad81f4cbd9317f5a46861437dae58d69113", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x29f35", - "gasUsed": "0xf8d", - "input": "0x16c66cc6000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x28a9e", - "gasUsed": "0x334", - "input": "0xe16c7d98636f6e747261637463746c000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x21d79", - "gasUsed": "0x24d", - "input": "0x13bc6d4b000000000000000000000000b4fe7aa695b326c9d219158d2ca50db77b39f99f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x2165b", - "gasUsed": "0x334", - "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000", - "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1a8e8", - "gasUsed": "0x24d", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1a2c6", - "gasUsed": "0x3cb", - "input": "0xc9503fe2", - "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x19b72", - "gasUsed": "0x3cb", - "input": "0xc9503fe2", - "output": "0x0000000000000000000000000000000000000000000000008ac7230489e80000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x19428", - "gasUsed": "0x305", - "input": "0x6f265b93", - "output": "0x0000000000000000000000000000000000000000000000283c7b9181eca20000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x18d45", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "gas": "0x1734e", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x20ee1", - "gasUsed": "0x5374", - "input": "0x581d5d60000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000", - "output": "0x", - "to": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1b6c1", - "gasUsed": "0x334", - "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1af69", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "gas": "0x143a5", - "gasUsed": "0x24d", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1a91d", - "gasUsed": "0x12fa", - "input": "0x0accce0600000000000000000000000000000000000000000000000000000000000000025842545553440000000000000000000000000000000000000000000000000000000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x", - "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x19177", - "gasUsed": "0x334", - "input": "0xe16c7d986c6f676d67720000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000002a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x18a22", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x18341", - "gasUsed": "0x334", - "input": "0xe16c7d986d61726b65746462000000000000000000000000000000000000000000000000", - "output": "0x000000000000000000000000cf00ffd997ad14939736f026006498e3f099baaf", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x17bec", - "gasUsed": "0x229", - "input": "0x2e94420f", - "output": "0x5842545553440000000000000000000000000000000000000000000000000000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - }, - { - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x1764e", - "gasUsed": "0x45c", - "input": "0xf92eb7745842545553440000000000000000000000000000000000000000000000000000", - "output": "0x00000000000000000000000000000000000000000000002816d180e30c390000", - "to": "0xcf00ffd997ad14939736f026006498e3f099baaf", - "type": "CALL", - "value": "0x0" - }, - { - "calls": [ - { - "from": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "gas": "0x108ba", - "gasUsed": "0x24d", - "input": "0x13bc6d4b0000000000000000000000003e9286eafa2db8101246c2131c09b49080d00690", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x2cccf5e0538493c235d1c5ef6580f77d99e91396", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "gas": "0x16e62", - "gasUsed": "0xebb", - "input": "0x645a3b72584254555344000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002816d180e30c390000", - "output": "0x", - "to": "0x2a98c5f40bfa3dee83431103c535f6fae9a8ad38", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "gas": "0x283b9", - "gasUsed": "0xc51c", - "input": "0x949ae479000000000000000000000000c212e03b9e060e36facad5fd8f4435412ca22e6b0000000000000000000000000000000000000000000000280faf689c35ac0000", - "output": "0x", - "to": "0x3e9286eafa2db8101246c2131c09b49080d00690", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "gas": "0x30b4a", - "gasUsed": "0xedb7", - "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000", - "output": "0x", - "to": "0xb4fe7aa695b326c9d219158d2ca50db77b39f99f", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0x70c9217d814985faef62b124420f8dfbddd96433", - "gas": "0x3d090", - "gasUsed": "0x1810b", - "input": "0x51a34eb80000000000000000000000000000000000000000000000280faf689c35ac0000", - "output": "0x", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json deleted file mode 100644 index 2cd28bacc4..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/delegatecall.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "context": { - "difficulty": "31927752", - "gasLimit": "4707788", - "miner": "0x5659922ce141eedbc2733678f9806c77b4eebee8", - "number": "11495", - "timestamp": "1479735917" - }, - "genesis": { - "alloc": { - "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a60003504630a0313a981146100875780630a3b0a4f146101095780630cd40fea1461021257806329092d0e1461021f5780634cd06a5f146103295780635dbe47e8146103395780637a9e5410146103d9578063825db5f7146103e6578063a820b44d146103f3578063efa52fb31461047a575b610002565b34610002576104fc600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a26333556e849091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f415610002575050604051519150505b919050565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f21ce24d4000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926321ce24d49260448082019391829003018186803b156100025760325a03f415610002575050505b50565b3461000257610512600181565b346100025761051060043560006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a2637d65837a9091336000604051602001526040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515115905061008257604080517f89489a87000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a038416602483015291517342b02b5deeb78f34cd5ac896473b63e6c99a71a2926389489a879260448082019391829003018186803b156100025760325a03f4156100025750505061020f565b3461000257610528600435610403565b34610002576104fc600435604080516000602091820181905282517f7d65837a00000000000000000000000000000000000000000000000000000000815260048101829052600160a060020a0385166024820152925190927342b02b5deeb78f34cd5ac896473b63e6c99a71a292637d65837a92604480840193829003018186803b156100025760325a03f4156100025750506040515191506101049050565b3461000257610512600c81565b3461000257610512600081565b3461000257610528600061055660005b600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263685a1f3c9091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b346100025761053a600435600060006000507342b02b5deeb78f34cd5ac896473b63e6c99a71a263f775b6b59091846000604051602001526040518360e060020a028152600401808381526020018281526020019250505060206040518083038186803b156100025760325a03f4156100025750506040515191506101049050565b604080519115158252519081900360200190f35b005b6040805160ff9092168252519081900360200190f35b60408051918252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b90509056", - "nonce": "1", - "storage": { - "0x4d140b25abf3c71052885c66f73ce07cff141c1afabffdaf5cba04d625b7ebcc": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - }, - "0x269296dddce321a6bcbaa2f0181127593d732cba": { - "balance": "0x0", - "code": "0x606060405236156101275760e060020a60003504630cd40fea811461012c578063173825d9146101395780631849cb5a146101c7578063285791371461030f5780632a58b3301461033f5780632cb0d48a146103565780632f54bf6e1461036a578063332b9f061461039d5780633ca8b002146103c55780633df4ddf4146103d557806341c0e1b5146103f457806347799da81461040557806362a51eee1461042457806366907d13146104575780637065cb48146104825780637a9e541014610496578063825db5f7146104a3578063949d225d146104b0578063a51687df146104c7578063b4da4e37146104e6578063b4e6850b146104ff578063bd7474ca14610541578063e75623d814610541578063e9938e1114610555578063f5d241d314610643575b610002565b3461000257610682600181565b34610002576106986004356106ff335b60006001600a9054906101000a9004600160a060020a0316600160a060020a0316635dbe47e8836000604051602001526040518260e060020a0281526004018082600160a060020a03168152602001915050602060405180830381600087803b156100025760325a03f1156100025750506040515191506103989050565b3461000257604080516101008082018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a0360043581168752600586529589902089519788018a528054808816808a52605060020a91829004600160a060020a0316978a01889052600183015463ffffffff8082169d8c018e905264010000000082048116988c01899052604060020a90910416958a018690526002830154948a01859052600390920154808916938a01849052049096169690970186905293969495949293604080516001605060020a03998a16815297891660208901529590971686860152600160a060020a03909316606086015263ffffffff9182166080860152811660a08501521660c083015260e08201929092529051908190036101000190f35b346100025761069a60043560018054600091829160ff60f060020a909104161515141561063d5761072833610376565b34610002576106ae6004546001605060020a031681565b34610002576106986004356108b333610149565b346100025761069a6004355b600160a060020a03811660009081526002602052604090205460ff1615156001145b919050565b34610002576106986001805460ff60f060020a9091041615151415610913576108ed33610376565b346100025761069a600435610149565b34610002576106ae6003546001605060020a03605060020a9091041681565b346100025761069861091533610149565b34610002576106ae6003546001605060020a0360a060020a9091041681565b346100025761069a60043560243560018054600091829160ff60f060020a909104161515141561095e5761092633610376565b34610002576106986004356001805460ff60f060020a909104161515141561072557610a8b33610376565b3461000257610698600435610aa533610149565b3461000257610682600c81565b3461000257610682600081565b34610002576106ae6003546001605060020a031681565b34610002576106ca600154600160a060020a03605060020a9091041681565b346100025761069a60015460ff60f060020a9091041681565b346100025761069a60043560243560443560643560843560a43560c43560018054600091829160ff60f060020a9091041615151415610b5857610ad233610376565b3461000257610698600435610bd633610149565b34610002576106e6600435604080516101008181018352600080835260208084018290528385018290526060808501839052608080860184905260a080870185905260c080880186905260e09788018690526001605060020a03808b168752600586529589902089519788018a5280548088168952600160a060020a03605060020a918290041696890196909652600181015463ffffffff8082169b8a019b909b5264010000000081048b1695890195909552604060020a90940490981691860182905260028301549086015260039091015480841696850196909652940416918101919091525b50919050565b346100025761069a60043560243560443560643560843560a43560018054600091829160ff60f060020a9091041615151415610c8e57610bfb33610376565b6040805160ff9092168252519081900360200190f35b005b604080519115158252519081900360200190f35b604080516001605060020a039092168252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b6040805163ffffffff9092168252519081900360200190f35b1561012757600160a060020a0381166000908152600260205260409020805460ff191690555b50565b1561063d57506001605060020a0380831660009081526005602052604090208054909116151561075b576000915061063d565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610817905b8051600354600090819060016001605060020a0390911611610c995760038054605060020a60f060020a0319169055610ddf565b600380546001605060020a031981166000196001605060020a03928316011782558416600090815260056020526040812080547fffff000000000000000000000000000000000000000000000000000000000000168155600181810180546bffffffffffffffffffffffff191690556002820192909255909101805473ffffffffffffffffffffffffffffffffffffffff19169055915061063d565b1561012757600180547fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660f060020a8302179055610725565b1561091357600480546001605060020a031981166001605060020a039091166001011790555b565b156101275733600160a060020a0316ff5b1561095e57506001605060020a03808416600090815260056020526040902080549091161515610965576000915061095e565b600191505b5092915050565b60038101546001605060020a0384811691161415610986576001915061095e565b604080516101008101825282546001605060020a038082168352600160a060020a03605060020a92839004166020840152600185015463ffffffff80821695850195909552640100000000810485166060850152604060020a90049093166080830152600284015460a0830152600384015480841660c08401520490911660e0820152610a12906107e3565b61095983825b80546003546001605060020a0391821691600091161515610de55760038054605060020a60a060020a031916605060020a84021760a060020a69ffffffffffffffffffff02191660a060020a84021781558301805473ffffffffffffffffffffffffffffffffffffffff19169055610ddf565b1561072557600480546001605060020a0319168217905550565b1561012757600160a060020a0381166000908152600260205260409020805460ff19166001179055610725565b15610b5857506001605060020a038088166000908152600560205260409020805490911615610b645760009150610b58565b6004546001605060020a0390811690891610610b3057600480546001605060020a03191660018a011790555b6003805460016001605060020a03821681016001605060020a03199092169190911790915591505b50979650505050505050565b80546001605060020a0319168817605060020a60f060020a031916605060020a880217815560018101805463ffffffff1916871767ffffffff0000000019166401000000008702176bffffffff00000000000000001916604060020a860217905560028101839055610b048982610a18565b156101275760018054605060020a60f060020a031916605060020a8302179055610725565b15610c8e57506001605060020a03808816600090815260056020526040902080549091161515610c2e5760009150610c8e565b8054605060020a60f060020a031916605060020a88021781556001808201805463ffffffff1916881767ffffffff0000000019166401000000008802176bffffffff00000000000000001916604060020a87021790556002820184905591505b509695505050505050565b6003546001605060020a03848116605060020a909204161415610d095760e084015160038054605060020a928302605060020a60a060020a031990911617808255919091046001605060020a031660009081526005602052604090200180546001605060020a0319169055610ddf565b6003546001605060020a0384811660a060020a909204161415610d825760c08401516003805460a060020a92830260a060020a69ffffffffffffffffffff021990911617808255919091046001605060020a03166000908152600560205260409020018054605060020a60a060020a0319169055610ddf565b505060c082015160e08301516001605060020a0380831660009081526005602052604080822060039081018054605060020a60a060020a031916605060020a8702179055928416825290200180546001605060020a031916831790555b50505050565b6001605060020a0384161515610e6457600380546001605060020a03605060020a9182900481166000908152600560205260409020830180546001605060020a0319908116871790915583548785018054918590049093168402605060020a60a060020a03199182161790911690915582549185029116179055610ddf565b506001605060020a038381166000908152600560205260409020600390810180549185018054605060020a60a060020a0319908116605060020a94859004909516808502959095176001605060020a0319168817909155815416918402919091179055801515610ef4576003805460a060020a69ffffffffffffffffffff02191660a060020a8402179055610ddf565b6003808401546001605060020a03605060020a9091041660009081526005602052604090200180546001605060020a031916831790555050505056", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000113204f5d64c28326fd7bd05fd4ea855302d7f2ff00000000000000000000" - } - }, - "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2": { - "balance": "0x0", - "code": "0x6504032353da7150606060405236156100695760e060020a60003504631bf7509d811461006e57806321ce24d41461008157806333556e84146100ec578063685a1f3c146101035780637d65837a1461011757806389489a8714610140578063f775b6b5146101fc575b610007565b61023460043560006100fd82600061010d565b610246600435602435600160a060020a03811660009081526020839052604081205415156102cb57826001016000508054806001018281815481835581811511610278576000838152602090206102789181019083015b808211156102d057600081556001016100d8565b610248600435602435600182015481105b92915050565b6102346004356024355b60018101906100fd565b610248600435602435600160a060020a03811660009081526020839052604090205415156100fd565b61024660043560243580600160a060020a031632600160a060020a03161415156101f857600160a060020a038116600090815260208390526040902054156101f857600160a060020a038116600090815260208390526040902054600183018054909160001901908110156100075760009182526020808320909101805473ffffffffffffffffffffffffffffffffffffffff19169055600160a060020a038316825283905260408120556002820180546000190190555b5050565b61025c60043560243560008260010160005082815481101561000757600091825260209091200154600160a060020a03169392505050565b60408051918252519081900360200190f35b005b604080519115158252519081900360200190f35b60408051600160a060020a039092168252519081900360200190f35b50505060009283526020808420909201805473ffffffffffffffffffffffffffffffffffffffff191686179055600160a060020a0385168352908590526040909120819055600284018054600101905590505b505050565b509056", - "nonce": "1", - "storage": {} - }, - "0xa529806c67cc6486d4d62024471772f47f6fd672": { - "balance": "0x67820e39ac8fe9800", - "code": "0x", - "nonce": "68", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "31912170", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712388", - "hash": "0x0855914bdc581bccdc62591fd438498386ffb59ea4d5361ed5c3702e26e2c72f", - "miner": "0x334391aa808257952a462d1475562ee2106a6c90", - "mixHash": "0x64bb70b8ca883cadb8fbbda2c70a861612407864089ed87b98e5de20acceada6", - "nonce": "0x684129f283aaef18", - "number": "11494", - "stateRoot": "0x7057f31fe3dab1d620771adad35224aae43eb70e94861208bc84c557ff5b9d10", - "timestamp": "1479735912", - "totalDifficulty": "90744064339" - }, - "input": "0xf889448504a817c800832dc6c094269296dddce321a6bcbaa2f0181127593d732cba80a47065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e29a080ed81e4c5e9971a730efab4885566e2c868cd80bd4166d0ed8c287fdf181650a069d7c49215e3d4416ad239cd09dbb71b9f04c16b33b385d14f40b618a7a65115", - "result": { - "calls": [ - { - "calls": [ - { - "from": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff", - "gas": "0x2bf459", - "gasUsed": "0x2aa", - "input": "0x7d65837a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x42b02b5deeb78f34cd5ac896473b63e6c99a71a2", - "type": "DELEGATECALL" - } - ], - "from": "0x269296dddce321a6bcbaa2f0181127593d732cba", - "gas": "0x2cae73", - "gasUsed": "0xa9d", - "input": "0x5dbe47e8000000000000000000000000a529806c67cc6486d4d62024471772f47f6fd672", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x13204f5d64c28326fd7bd05fd4ea855302d7f2ff", - "type": "CALL", - "value": "0x0" - } - ], - "from": "0xa529806c67cc6486d4d62024471772f47f6fd672", - "gas": "0x2dc6c0", - "gasUsed": "0xbd55", - "input": "0x7065cb480000000000000000000000001523e55a1ca4efbae03355775ae89f8d7699ad9e", - "output": "0x", - "to": "0x269296dddce321a6bcbaa2f0181127593d732cba", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json deleted file mode 100644 index 07fda21d4b..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_create_oog_outer_throw.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "context": { - "difficulty": "3451177886", - "gasLimit": "4709286", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2290744", - "timestamp": "1513616439" - }, - "genesis": { - "alloc": { - "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a": { - "balance": "0x0", - "code": "0x606060405263ffffffff60e060020a6000350416633b91f50681146100505780635bb47808146100715780635f51fca01461008c578063bc7647a9146100ad578063f1bd0d7a146100c8575b610000565b346100005761006f600160a060020a03600435811690602435166100e9565b005b346100005761006f600160a060020a0360043516610152565b005b346100005761006f600160a060020a036004358116906024351661019c565b005b346100005761006f600160a060020a03600435166101fa565b005b346100005761006f600160a060020a0360043581169060243516610db8565b005b600160a060020a038083166000908152602081905260408120549091908116903316811461011657610000565b839150600160a060020a038316151561012d573392505b6101378284610e2e565b6101418284610db8565b61014a826101fa565b5b5b50505050565b600154600160a060020a03908116903316811461016e57610000565b6002805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0384161790555b5b5050565b600254600160a060020a0390811690331681146101b857610000565b600160a060020a038381166000908152602081905260409020805473ffffffffffffffffffffffffffffffffffffffff19169184169190911790555b5b505050565b6040805160e260020a631a481fc102815260016024820181905260026044830152606482015262093a8060848201819052600060a4830181905260c06004840152601e60c48401527f736574456e7469747953746174757328616464726573732c75696e743829000060e484015292519091600160a060020a038516916369207f049161010480820192879290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526000602482018190526001604483015260606004830152602360648301527f626567696e506f6c6c28616464726573732c75696e7436342c626f6f6c2c626f60848301527f6f6c29000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f61646453746f636b28616464726573732c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601960c48201527f697373756553746f636b2875696e74382c75696e74323536290000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602160648301527f6772616e7453746f636b2875696e74382c75696e743235362c61646472657373608483015260f860020a60290260a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f115610000575050604080517f010555b8000000000000000000000000000000000000000000000000000000008152600160a060020a03338116602483015260006044830181905260606004840152603c60648401527f6772616e7456657374656453746f636b2875696e74382c75696e743235362c6160848401527f6464726573732c75696e7436342c75696e7436342c75696e743634290000000060a48401529251908716935063010555b89260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152601260c48201527f626567696e53616c65286164647265737329000000000000000000000000000060e48201529051600160a060020a03861692506369207f04916101048082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601a60648301527f7472616e7366657253616c6546756e64732875696e743235362900000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260016024820181905260026044830152606482015267ffffffffffffffff8416608482015260ff851660a482015260c06004820152602d60c48201527f7365744163636f756e74696e6753657474696e67732875696e743235362c756960e48201527f6e7436342c75696e7432353629000000000000000000000000000000000000006101048201529051600160a060020a03861692506369207f04916101248082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152603460648301527f637265617465526563757272696e6752657761726428616464726573732c756960848301527f6e743235362c75696e7436342c737472696e672900000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152601b60648301527f72656d6f7665526563757272696e675265776172642875696e7429000000000060848301529151600160a060020a038716935063de64e15c9260a48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a63379938570281526002602482015260006044820181905260606004830152602360648301527f697373756552657761726428616464726573732c75696e743235362c7374726960848301527f6e6729000000000000000000000000000000000000000000000000000000000060a48301529151600160a060020a038716935063de64e15c9260c48084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f61737369676e53746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a6337993857028152600160248201819052604482015260606004820152602260648201527f72656d6f766553746f636b2875696e74382c616464726573732c75696e743235608482015260f060020a6136290260a48201529051600160a060020a038616925063de64e15c9160c48082019260009290919082900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc102815260026024808301919091526003604483015260006064830181905267ffffffffffffffff8616608484015260ff871660a484015260c0600484015260c48301919091527f7365744164647265737342796c617728737472696e672c616464726573732c6260e48301527f6f6f6c29000000000000000000000000000000000000000000000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152602160c48301527f73657453746174757342796c617728737472696e672c75696e74382c626f6f6c60e483015260f860020a6029026101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f1156100005750506040805160e260020a631a481fc1028152600260248201526003604482015260006064820181905267ffffffffffffffff8516608483015260ff861660a483015260c06004830152603860c48301527f736574566f74696e6742796c617728737472696e672c75696e743235362c756960e48301527f6e743235362c626f6f6c2c75696e7436342c75696e74382900000000000000006101048301529151600160a060020a03871693506369207f04926101248084019391929182900301818387803b156100005760325a03f115610000575050505b505050565b604080517f225553a4000000000000000000000000000000000000000000000000000000008152600160a060020a0383811660048301526002602483015291519184169163225553a49160448082019260009290919082900301818387803b156100005760325a03f115610000575050505b5050565b600082604051611fd280610f488339600160a060020a03909216910190815260405190819003602001906000f0801561000057905082600160a060020a03166308b027418260016040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b156100005760325a03f115610000575050604080517fa14e3ee300000000000000000000000000000000000000000000000000000000815260006004820181905260016024830152600160a060020a0386811660448401529251928716935063a14e3ee39260648084019382900301818387803b156100005760325a03f115610000575050505b5050505600606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029a165627a7a723058200e78a5f7e0f91739035d0fbf5eca02f79377210b722f63431f29a22e2880b3bd0029", - "nonce": "789", - "storage": { - "0xfe9ec0542a1c009be8b1f3acf43af97100ffff42eb736850fb038fa1151ad4d9": "0x000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8" - } - }, - "0x5cb4a6b902fcb21588c86c3517e797b07cdaadb9": { - "balance": "0x0", - "code": "0x", - "nonce": "0", - "storage": {} - }, - "0xe4a13bc304682a903e9472f469c33801dd18d9e8": { - "balance": "0x33c763c929f62c4f", - "code": "0x", - "nonce": "14", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3451177886", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4713874", - "hash": "0x5d52a672417cd1269bf4f7095e25dcbf837747bba908cd5ef809dc1bd06144b5", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x01a12845ed546b94a038a7a03e8df8d7952024ed41ccb3db7a7ade4abc290ce1", - "nonce": "0x28c446f1cb9748c1", - "number": "2290743", - "stateRoot": "0x4898aceede76739daef76448a367d10015a2c022c9e7909b99a10fbf6fb16708", - "timestamp": "1513616414", - "totalDifficulty": "7146523769022564" - }, - "input": "0xf8aa0e8509502f9000830493e0941d3ddf7caf024f253487e18bc4a15b1a360c170a80b8443b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e829a0524564944fa419f5c189b5074044f89210c6d6b2d77ee8f7f12a927d59b636dfa0015b28986807a424b18b186ee6642d76739df36cad802d20e8c00e79a61d7281", - "result": { - "calls": [ - { - "error": "internal failure", - "from": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a", - "gas": "0x39ff0", - "gasUsed": "0x39ff0", - "input": "0x606060405234620000005760405160208062001fd283398101604052515b805b600a8054600160a060020a031916600160a060020a0383161790555b506001600d819055600e81905560408051808201909152600c8082527f566f74696e672053746f636b00000000000000000000000000000000000000006020928301908152600b805460008290528251601860ff1990911617825590947f0175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9600291831615610100026000190190921604601f0193909304830192906200010c565b828001600101855582156200010c579182015b828111156200010c578251825591602001919060010190620000ef565b5b50620001309291505b808211156200012c576000815560010162000116565b5090565b50506040805180820190915260038082527f43565300000000000000000000000000000000000000000000000000000000006020928301908152600c805460008290528251600660ff1990911617825590937fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c760026001841615610100026000190190931692909204601f010481019291620001f7565b82800160010185558215620001f7579182015b82811115620001f7578251825591602001919060010190620001da565b5b506200021b9291505b808211156200012c576000815560010162000116565b5090565b50505b505b611da280620002306000396000f3006060604052361561019a5763ffffffff60e060020a600035041662e1986d811461019f57806302a72a4c146101d657806306eb4e421461020157806306fdde0314610220578063095ea7b3146102ad578063158ccb99146102dd57806318160ddd146102f85780631cf65a781461031757806323b872dd146103365780632c71e60a1461036c57806333148fd6146103ca578063435ebc2c146103f55780635eeb6e451461041e578063600e85b71461043c5780636103d70b146104a157806362c1e46a146104b05780636c182e99146104ba578063706dc87c146104f057806370a082311461052557806377174f851461055057806395d89b411461056f578063a7771ee3146105fc578063a9059cbb14610629578063ab377daa14610659578063b25dbb5e14610685578063b89a73cb14610699578063ca5eb5e1146106c6578063cbcf2e5a146106e1578063d21f05ba1461070e578063d347c2051461072d578063d96831e114610765578063dd62ed3e14610777578063df3c211b146107a8578063e2982c21146107d6578063eb944e4c14610801575b610000565b34610000576101d4600160a060020a036004351660243567ffffffffffffffff6044358116906064358116906084351661081f565b005b34610000576101ef600160a060020a0360043516610a30565b60408051918252519081900360200190f35b34610000576101ef610a4f565b60408051918252519081900360200190f35b346100005761022d610a55565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516602435610ae3565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516610b4e565b005b34610000576101ef610b89565b60408051918252519081900360200190f35b34610000576101ef610b8f565b60408051918252519081900360200190f35b34610000576102c9600160a060020a0360043581169060243516604435610b95565b604080519115158252519081900360200190f35b3461000057610388600160a060020a0360043516602435610bb7565b60408051600160a060020a039096168652602086019490945267ffffffffffffffff928316858501529082166060850152166080830152519081900360a00190f35b34610000576101ef600160a060020a0360043516610c21565b60408051918252519081900360200190f35b3461000057610402610c40565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d4600160a060020a0360043516602435610c4f565b005b3461000057610458600160a060020a0360043516602435610cc9565b60408051600160a060020a03909716875260208701959095528585019390935267ffffffffffffffff9182166060860152811660808501521660a0830152519081900360c00190f35b34610000576101d4610d9e565b005b6101d4610e1e565b005b34610000576104d3600160a060020a0360043516610e21565b6040805167ffffffffffffffff9092168252519081900360200190f35b3461000057610402600160a060020a0360043516610ead565b60408051600160a060020a039092168252519081900360200190f35b34610000576101ef600160a060020a0360043516610ef9565b60408051918252519081900360200190f35b34610000576101ef610f18565b60408051918252519081900360200190f35b346100005761022d610f1e565b604080516020808252835181830152835191928392908301918501908083838215610273575b80518252602083111561027357601f199092019160209182019101610253565b505050905090810190601f16801561029f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000576102c9600160a060020a0360043516610fac565b604080519115158252519081900360200190f35b34610000576102c9600160a060020a0360043516602435610fc2565b604080519115158252519081900360200190f35b3461000057610402600435610fe2565b60408051600160a060020a039092168252519081900360200190f35b34610000576101d46004351515610ffd565b005b34610000576102c9600160a060020a036004351661104c565b604080519115158252519081900360200190f35b34610000576101d4600160a060020a0360043516611062565b005b34610000576102c9600160a060020a0360043516611070565b604080519115158252519081900360200190f35b34610000576101ef6110f4565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351667ffffffffffffffff602435166110fa565b60408051918252519081900360200190f35b34610000576101d4600435611121565b005b34610000576101ef600160a060020a03600435811690602435166111c6565b60408051918252519081900360200190f35b34610000576101ef6004356024356044356064356084356111f3565b60408051918252519081900360200190f35b34610000576101ef600160a060020a036004351661128c565b60408051918252519081900360200190f35b34610000576101d4600160a060020a036004351660243561129e565b005b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915267ffffffffffffffff848116908416101561086457610000565b8367ffffffffffffffff168267ffffffffffffffff16101561088557610000565b8267ffffffffffffffff168267ffffffffffffffff1610156108a657610000565b506040805160a081018252600160a060020a033381168252602080830188905267ffffffffffffffff80871684860152858116606085015287166080840152908816600090815260039091529190912080546001810180835582818380158290116109615760030281600302836000526020600020918201910161096191905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050916000526020600020906003020160005b5082518154600160a060020a031916600160a060020a03909116178155602083015160018201556040830151600290910180546060850151608086015167ffffffffffffffff1990921667ffffffffffffffff948516176fffffffffffffffff00000000000000001916604060020a918516919091021777ffffffffffffffff000000000000000000000000000000001916608060020a939091169290920291909117905550610a268686610fc2565b505b505050505050565b600160a060020a0381166000908152600360205260409020545b919050565b60055481565b600b805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b600160a060020a03338116600081815260026020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b600a5433600160a060020a03908116911614610b6957610000565b600a8054600160a060020a031916600160a060020a0383161790555b5b50565b60005481565b60005b90565b6000610ba2848484611600565b610bad8484846116e2565b90505b9392505050565b600360205281600052604060002081815481101561000057906000526020600020906003020160005b5080546001820154600290920154600160a060020a03909116935090915067ffffffffffffffff80821691604060020a8104821691608060020a9091041685565b600160a060020a0381166000908152600860205260409020545b919050565b600a54600160a060020a031681565b600a5433600160a060020a03908116911614610c6a57610000565b610c7660005482611714565b6000908155600160a060020a038316815260016020526040902054610c9b9082611714565b600160a060020a038316600090815260016020526040812091909155610cc390839083611600565b5b5b5050565b6000600060006000600060006000600360008a600160a060020a0316600160a060020a0316815260200190815260200160002088815481101561000057906000526020600020906003020160005b508054600182015460028301546040805160a081018252600160a060020a039094168085526020850184905267ffffffffffffffff808416928601839052604060020a8404811660608701819052608060020a9094041660808601819052909c50929a509197509095509350909150610d90904261172d565b94505b509295509295509295565b33600160a060020a038116600090815260066020526040902054801515610dc457610000565b8030600160a060020a0316311015610ddb57610000565b600160a060020a0382166000818152600660205260408082208290555183156108fc0291849190818181858888f193505050501515610cc357610000565b5b5050565b5b565b600160a060020a03811660009081526003602052604081205442915b81811015610ea557600160a060020a03841660009081526003602052604090208054610e9a9190839081101561000057906000526020600020906003020160005b5060020154604060020a900467ffffffffffffffff168461177d565b92505b600101610e3d565b5b5050919050565b600160a060020a0380821660009081526007602052604081205490911615610eef57600160a060020a0380831660009081526007602052604090205416610ef1565b815b90505b919050565b600160a060020a0381166000908152600160205260409020545b919050565b600d5481565b600c805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610adb5780601f10610ab057610100808354040283529160200191610adb565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505050505081565b60006000610fb983610c21565b1190505b919050565b6000610fcf338484611600565b610fd983836117ac565b90505b92915050565b600460205260009081526040902054600160a060020a031681565b8015801561101a575061100f33610ef9565b61101833610c21565b115b1561102457610000565b33600160a060020a03166000908152600960205260409020805460ff19168215151790555b50565b60006000610fb983610ef9565b1190505b919050565b610b8533826117dc565b5b50565b600a54604080516000602091820181905282517fcbcf2e5a000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015293519194939093169263cbcf2e5a92602480830193919282900301818787803b156100005760325a03f115610000575050604051519150505b919050565b600e5481565b6000610fd961110984846118b2565b61111385856119b6565b611a05565b90505b92915050565b600a5433600160a060020a0390811691161461113c57610000565b61114860005482611a1f565b600055600554600190101561116c57600a5461116c90600160a060020a0316611a47565b5b600a54600160a060020a03166000908152600160205260409020546111929082611a1f565b600a8054600160a060020a039081166000908152600160205260408120939093559054610b8592911683611600565b5b5b50565b600160a060020a038083166000908152600260209081526040808320938516835292905220545b92915050565b6000600060008487101561120a5760009250611281565b8387111561121a57879250611281565b61123f6112308961122b888a611714565b611a90565b61123a8689611714565b611abc565b915081925061124e8883611714565b905061127e8361127961126a8461122b8c8b611714565b611a90565b61123a888b611714565b611abc565b611a1f565b92505b505095945050505050565b60066020526000908152604090205481565b600160a060020a03821660009081526003602052604081208054829190849081101561000057906000526020600020906003020160005b50805490925033600160a060020a039081169116146112f357610000565b6040805160a0810182528354600160a060020a0316815260018401546020820152600284015467ffffffffffffffff80821693830193909352604060020a810483166060830152608060020a900490911660808201526113539042611af9565b600160a060020a0385166000908152600360205260409020805491925090849081101561000057906000526020600020906003020160005b508054600160a060020a031916815560006001820181905560029091018054600160c060020a0319169055600160a060020a0385168152600360205260409020805460001981019081101561000057906000526020600020906003020160005b50600160a060020a03851660009081526003602052604090208054859081101561000057906000526020600020906003020160005b5081548154600160a060020a031916600160a060020a03918216178255600180840154908301556002928301805493909201805467ffffffffffffffff191667ffffffffffffffff948516178082558354604060020a908190048616026fffffffffffffffff000000000000000019909116178082559254608060020a9081900490941690930277ffffffffffffffff00000000000000000000000000000000199092169190911790915584166000908152600360205260409020805460001981018083559190829080158290116115485760030281600302836000526020600020918201910161154891905b8082111561095d578054600160a060020a031916815560006001820155600281018054600160c060020a0319169055600301610926565b5090565b5b505050600160a060020a033316600090815260016020526040902054611570915082611a1f565b600160a060020a03338116600090815260016020526040808220939093559086168152205461159f9082611714565b600160a060020a038086166000818152600160209081526040918290209490945580518581529051339093169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a35b50505050565b600160a060020a0383161561166e576116466008600061161f86610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611714565b6008600061165386610ead565b600160a060020a031681526020810191909152604001600020555b600160a060020a038216156116dc576116b46008600061168d85610ead565b600160a060020a0316600160a060020a031681526020019081526020016000205482611a1f565b600860006116c185610ead565b600160a060020a031681526020810191909152604001600020555b5b505050565b600083826116f082426110fa565b8111156116fc57610000565b611707868686611b1b565b92505b5b50509392505050565b600061172283831115611b4d565b508082035b92915050565b6000610fd983602001518367ffffffffffffffff16856080015167ffffffffffffffff16866040015167ffffffffffffffff16876060015167ffffffffffffffff166111f3565b90505b92915050565b60008167ffffffffffffffff168367ffffffffffffffff1610156117a15781610fd9565b825b90505b92915050565b600033826117ba82426110fa565b8111156117c657610000565b6117d08585611b5d565b92505b5b505092915050565b6117e582610ef9565b6117ee83610c21565b11156117f957610000565b600160a060020a03811660009081526009602052604090205460ff16158015611834575081600160a060020a031681600160a060020a031614155b1561183e57610000565b61184782611070565b1561185157610000565b611864828261185f85610ef9565b611600565b600160a060020a0382811660009081526007602052604090208054600160a060020a031916918316918217905561189a82610ead565b600160a060020a031614610cc357610000565b5b5050565b600160a060020a038216600090815260036020526040812054815b818110156119885761197d836112796003600089600160a060020a0316600160a060020a0316815260200190815260200160002084815481101561000057906000526020600020906003020160005b506040805160a0810182528254600160a060020a031681526001830154602082015260029092015467ffffffffffffffff80821692840192909252604060020a810482166060840152608060020a900416608082015287611af9565b611a1f565b92505b6001016118cd565b600160a060020a0385166000908152600160205260409020546117d09084611714565b92505b505092915050565b600060006119c384611070565b80156119d157506000600d54115b90506119fb816119e9576119e485610ef9565b6119ec565b60005b6111138686611b7b565b611a05565b91505b5092915050565b60008183106117a15781610fd9565b825b90505b92915050565b6000828201611a3c848210801590611a375750838210155b611b4d565b8091505b5092915050565b611a508161104c565b15611a5a57610b85565b6005805460009081526004602052604090208054600160a060020a031916600160a060020a038416179055805460010190555b50565b6000828202611a3c841580611a37575083858381156100005704145b611b4d565b8091505b5092915050565b60006000611acc60008411611b4d565b8284811561000057049050611a3c838581156100005706828502018514611b4d565b8091505b5092915050565b6000610fd98360200151611b0d858561172d565b611714565b90505b92915050565b60008382611b2982426110fa565b811115611b3557610000565b611707868686611b8f565b92505b5b50509392505050565b801515610b8557610000565b5b50565b6000611b6883611a47565b610fd98383611c92565b90505b92915050565b6000610fd983610ef9565b90505b92915050565b600160a060020a038084166000908152600260209081526040808320338516845282528083205493861683526001909152812054909190611bd09084611a1f565b600160a060020a038086166000908152600160205260408082209390935590871681522054611bff9084611714565b600160a060020a038616600090815260016020526040902055611c228184611714565b600160a060020a038087166000818152600260209081526040808320338616845282529182902094909455805187815290519288169391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a3600191505b509392505050565b60003382611ca082426110fa565b811115611cac57610000565b6117d08585611cc2565b92505b5b505092915050565b600160a060020a033316600090815260016020526040812054611ce59083611714565b600160a060020a033381166000908152600160205260408082209390935590851681522054611d149083611a1f565b600160a060020a038085166000818152600160209081526040918290209490945580518681529051919333909316927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35060015b929150505600a165627a7a72305820bfa5ddd3fecf3f43aed25385ec7ec3ef79638c2e58d99f85d9a3cc494183bf160029000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182", - "type": "CREATE", - "value": "0x0" - } - ], - "error": "invalid jump destination", - "from": "0xe4a13bc304682a903e9472f469c33801dd18d9e8", - "gas": "0x493e0", - "gasUsed": "0x493e0", - "input": "0x3b91f506000000000000000000000000a14bdd7e5666d784dcce98ad24d383a6b1cd4182000000000000000000000000e4a13bc304682a903e9472f469c33801dd18d9e8", - "to": "0x1d3ddf7caf024f253487e18bc4a15b1a360c170a", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json deleted file mode 100644 index 16e4136230..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_instafail.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "genesis": { - "difficulty": "117067574", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712380", - "hash": "0xe05db05eeb3f288041ecb10a787df121c0ed69499355716e17c307de313a4486", - "miner": "0x0c062b329265c965deef1eede55183b3acb8f611", - "mixHash": "0xb669ae39118a53d2c65fd3b1e1d3850dd3f8c6842030698ed846a2762d68b61d", - "nonce": "0x2b469722b8e28c45", - "number": "24973", - "stateRoot": "0x532a5c3f75453a696428db078e32ae283c85cb97e4d8560dbdf022adac6df369", - "timestamp": "1479891145", - "totalDifficulty": "1892250259406", - "alloc": { - "0x6c06b16512b332e6cd8293a2974872674716ce18": { - "balance": "0x0", - "nonce": "1", - "code": "0x60606040526000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d146036575b6000565b34600057604e60048080359060200190919050506050565b005b3373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051809050600060405180830381858888f19350505050505b5056", - "storage": {} - }, - "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31": { - "balance": "0x229ebbb36c3e0f20", - "nonce": "3", - "code": "0x", - "storage": {} - } - }, - "config": { - "chainId": 3, - "homesteadBlock": 0, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "byzantiumBlock": 1700000, - "constantinopleBlock": 4230000, - "petersburgBlock": 4939394, - "istanbulBlock": 6485846, - "muirGlacierBlock": 7117117, - "ethash": {} - } - }, - "context": { - "number": "24974", - "difficulty": "117067574", - "timestamp": "1479891162", - "gasLimit": "4712388", - "miner": "0xc822ef32e6d26e170b70cf761e204c1806265914" - }, - "input": "0xf889038504a81557008301f97e946c06b16512b332e6cd8293a2974872674716ce1880a42e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b1600002aa0e2a6558040c5d72bc59f2fb62a38993a314c849cd22fb393018d2c5af3112095a01bdb6d7ba32263ccc2ecc880d38c49d9f0c5a72d8b7908e3122b31356d349745", - "result": { - "type": "CALL", - "from": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", - "to": "0x6c06b16512b332e6cd8293a2974872674716ce18", - "value": "0x0", - "gas": "0x1f97e", - "gasUsed": "0x72de", - "input": "0x2e1a7d4d00000000000000000000000000000000000000000000000014d1120d7b160000", - "output": "0x", - "calls": [ - { - "type": "CALL", - "from": "0x6c06b16512b332e6cd8293a2974872674716ce18", - "to": "0x66fdfd05e46126a07465ad24e40cc0597bc1ef31", - "value": "0x14d1120d7b160000", - "error": "internal failure", - "input": "0x" - } - ] - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json deleted file mode 100644 index a023ed6d9b..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/inner_throw_outer_revert.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "context": { - "difficulty": "3956606365", - "gasLimit": "5413248", - "miner": "0x00d8ae40d9a06d0e7a2877b62e32eb959afbe16d", - "number": "2295104", - "timestamp": "1513681256" - }, - "genesis": { - "alloc": { - "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76": { - "balance": "0x0", - "code": "0x60606040526004361061015e576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680625b4487146101a257806311df9995146101cb578063278ecde11461022057806330adce0e146102435780633197cbb61461026c5780634bb278f3146102955780636103d70b146102aa57806363a599a4146102bf5780636a2d1cb8146102d457806375f12b21146102fd57806378e979251461032a578063801db9cc1461035357806386d1a69f1461037c5780638da5cb5b146103915780638ef26a71146103e65780639890220b1461040f5780639b39caef14610424578063b85dfb801461044d578063be9a6555146104a1578063ccb07cef146104b6578063d06c91e4146104e3578063d669e1d414610538578063df40503c14610561578063e2982c2114610576578063f02e030d146105c3578063f2fde38b146105d8578063f3283fba14610611575b600060149054906101000a900460ff1615151561017a57600080fd5b60075442108061018b575060085442115b15151561019757600080fd5b6101a03361064a565b005b34156101ad57600080fd5b6101b5610925565b6040518082815260200191505060405180910390f35b34156101d657600080fd5b6101de61092b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561022b57600080fd5b6102416004808035906020019091905050610951565b005b341561024e57600080fd5b610256610c48565b6040518082815260200191505060405180910390f35b341561027757600080fd5b61027f610c4e565b6040518082815260200191505060405180910390f35b34156102a057600080fd5b6102a8610c54565b005b34156102b557600080fd5b6102bd610f3e565b005b34156102ca57600080fd5b6102d261105d565b005b34156102df57600080fd5b6102e76110d5565b6040518082815260200191505060405180910390f35b341561030857600080fd5b6103106110e1565b604051808215151515815260200191505060405180910390f35b341561033557600080fd5b61033d6110f4565b6040518082815260200191505060405180910390f35b341561035e57600080fd5b6103666110fa565b6040518082815260200191505060405180910390f35b341561038757600080fd5b61038f611104565b005b341561039c57600080fd5b6103a4611196565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34156103f157600080fd5b6103f96111bb565b6040518082815260200191505060405180910390f35b341561041a57600080fd5b6104226111c1565b005b341561042f57600080fd5b610437611296565b6040518082815260200191505060405180910390f35b341561045857600080fd5b610484600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190505061129c565b604051808381526020018281526020019250505060405180910390f35b34156104ac57600080fd5b6104b46112c0565b005b34156104c157600080fd5b6104c9611341565b604051808215151515815260200191505060405180910390f35b34156104ee57600080fd5b6104f6611354565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561054357600080fd5b61054b61137a565b6040518082815260200191505060405180910390f35b341561056c57600080fd5b610574611385565b005b341561058157600080fd5b6105ad600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506116c3565b6040518082815260200191505060405180910390f35b34156105ce57600080fd5b6105d66116db565b005b34156105e357600080fd5b61060f600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050611829565b005b341561061c57600080fd5b610648600480803573ffffffffffffffffffffffffffffffffffffffff169060200190919050506118fe565b005b600080670de0b6b3a7640000341015151561066457600080fd5b61069b610696670de0b6b3a7640000610688610258346119d990919063ffffffff16565b611a0c90919063ffffffff16565b611a27565b9150660221b262dd80006106ba60065484611a7e90919063ffffffff16565b111515156106c757600080fd5b600a60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb84846000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15156107d557600080fd5b6102c65a03f115156107e657600080fd5b5050506040518051905050610808828260010154611a7e90919063ffffffff16565b8160010181905550610827348260000154611a7e90919063ffffffff16565b816000018190555061084434600554611a7e90919063ffffffff16565b60058190555061085f82600654611a7e90919063ffffffff16565b6006819055503373ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c836040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e8583600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60025481565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060085442108061096b5750651b48eb57e00060065410155b15151561097757600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154821415156109c757600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd3330856000604051602001526040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1515610ac857600080fd5b6102c65a03f11515610ad957600080fd5b5050506040518051905050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68836000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610b7d57600080fd5b6102c65a03f11515610b8e57600080fd5b505050604051805190501515610ba357600080fd5b600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001819055506000811115610c4457610c433382611a9c565b5b5050565b60055481565b60085481565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610cb157600080fd5b600854421015610cd357660221b262dd8000600654141515610cd257600080fd5b5b651b48eb57e000600654108015610cf057506213c6806008540142105b151515610cfc57600080fd5b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f193505050501515610d7557600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306000604051602001526040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1515610e3a57600080fd5b6102c65a03f11515610e4b57600080fd5b5050506040518051905090506000811115610f2057600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166342966c68826000604051602001526040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b1515610ef957600080fd5b6102c65a03f11515610f0a57600080fd5b505050604051805190501515610f1f57600080fd5b5b6001600960006101000a81548160ff02191690831515021790555050565b600080339150600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905060008114151515610f9657600080fd5b803073ffffffffffffffffffffffffffffffffffffffff163110151515610fbc57600080fd5b610fd181600254611b5090919063ffffffff16565b6002819055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561105957fe5b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156110b857600080fd5b6001600060146101000a81548160ff021916908315150217905550565b670de0b6b3a764000081565b600060149054906101000a900460ff1681565b60075481565b651b48eb57e00081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561115f57600080fd5b600060149054906101000a900460ff16151561117a57600080fd5b60008060146101000a81548160ff021916908315150217905550565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60065481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561121c57600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050151561129457600080fd5b565b61025881565b600a6020528060005260406000206000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561131b57600080fd5b600060075414151561132c57600080fd5b4260078190555062278d004201600881905550565b600960009054906101000a900460ff1681565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b660221b262dd800081565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113e557600080fd5b600654660221b262dd800003925061142b670de0b6b3a764000061141c610258670de0b6b3a76400006119d990919063ffffffff16565b81151561142557fe5b04611a27565b915081831115151561143c57600080fd5b600a60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856000604051602001526040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b151561158c57600080fd5b6102c65a03f1151561159d57600080fd5b50505060405180519050506115bf838260010154611a7e90919063ffffffff16565b81600101819055506115dc83600654611a7e90919063ffffffff16565b6006819055503073ffffffffffffffffffffffffffffffffffffffff167ff3c1c7c0eb1328ddc834c4c9e579c06d35f443bf1102b034653624a239c7a40c846040518082815260200191505060405180910390a27fd1dc370699ae69fb860ed754789a4327413ec1cd379b93f2cbedf449a26b0e856000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600554604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1505050565b60016020528060005260406000206000915090505481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561173657600080fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f2fde38b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b151561181357600080fd5b6102c65a03f1151561182457600080fd5b505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561188457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415156118fb57806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561195957600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561199557600080fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080828402905060008414806119fa57508284828115156119f757fe5b04145b1515611a0257fe5b8091505092915050565b6000808284811515611a1a57fe5b0490508091505092915050565b6000611a416202a300600754611a7e90919063ffffffff16565b421015611a7557611a6e611a5f600584611a0c90919063ffffffff16565b83611a7e90919063ffffffff16565b9050611a79565b8190505b919050565b6000808284019050838110151515611a9257fe5b8091505092915050565b611aee81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054611a7e90919063ffffffff16565b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550611b4681600254611a7e90919063ffffffff16565b6002819055505050565b6000828211151515611b5e57fe5b8183039050929150505600a165627a7a72305820ec0d82a406896ccf20989b3d6e650abe4dc104e400837f1f58e67ef499493ae90029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000008d69d00910d0b2afb2a99ed6c16c8129fa8e1751", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000e819f024b41358d2c08e3a868a5c5dd0566078d4", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000000000000000000000000000000000005a388981", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000005a3b38e6" - } - }, - "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826": { - "balance": "0x2a2dd979a35cf000", - "code": "0x", - "nonce": "0", - "storage": {} - }, - "0xe819f024b41358d2c08e3a868a5c5dd0566078d4": { - "balance": "0x0", - "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c681461027257806370a08231146102ad5780638da5cb5b146102fa57806395d89b411461034f578063a9059cbb146103dd578063dd62ed3e14610437578063f2fde38b146104a3575b600080fd5b34156100ca57600080fd5b6100d26104dc565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610515565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba61069c565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506106a2565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610952565b6040518082815260200191505060405180910390f35b341561027d57600080fd5b6102936004808035906020019091905050610957565b604051808215151515815260200191505060405180910390f35b34156102b857600080fd5b6102e4600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610abe565b6040518082815260200191505060405180910390f35b341561030557600080fd5b61030d610b07565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b341561035a57600080fd5b610362610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103a2578082015181840152602081019050610387565b50505050905090810190601f1680156103cf5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34156103e857600080fd5b61041d600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610b66565b604051808215151515815260200191505060405180910390f35b341561044257600080fd5b61048d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d01565b6040518082815260200191505060405180910390f35b34156104ae57600080fd5b6104da600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610d88565b005b6040805190810160405280600b81526020017f416c6c436f6465436f696e00000000000000000000000000000000000000000081525081565b6000808214806105a157506000600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054145b15156105ac57600080fd5b81600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60005481565b600080600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905061077683600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555061080b83600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506108618382610e7d90919063ffffffff16565b600260008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a360019150509392505050565b600681565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156109b557600080fd5b610a0782600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610a5f82600054610e7d90919063ffffffff16565b60008190555060003373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a360019050919050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6040805190810160405280600481526020017f414c4c430000000000000000000000000000000000000000000000000000000081525081565b6000610bba82600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e7d90919063ffffffff16565b600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c4f82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e5f90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a36001905092915050565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610de457600080fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515610e5c5780600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b6000808284019050838110151515610e7357fe5b8091505092915050565b6000828211151515610e8b57fe5b8183039050929150505600a165627a7a7230582059f3ea3df0b054e9ab711f37969684ba83fe38f255ffe2c8d850d951121c51100029", - "nonce": "1", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3956606365", - "extraData": "0x566961425443", - "gasLimit": "5418523", - "hash": "0x6f37eb930a25da673ea1bb80fd9e32ddac19cdf7cd4bb2eac62cc13598624077", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "mixHash": "0x10971cde68c587c750c23b8589ae868ce82c2c646636b97e7d9856470c5297c7", - "nonce": "0x810f923ff4b450a1", - "number": "2295103", - "stateRoot": "0xff403612573d76dfdaf4fea2429b77dbe9764021ae0e38dc8ac79a3cf551179e", - "timestamp": "1513681246", - "totalDifficulty": "7162347056825919" - }, - "input": "0xf86d808504e3b292008307dfa69433056b5dcac09a9b4becad0e1dcf92c19bd0af76880e92596fd62900008029a0e5f27bb66431f7081bb7f1f242003056d7f3f35414c352cd3d1848b52716dac2a07d0be78980edb0bd2a0678fc53aa90ea9558ce346b0d947967216918ac74ccea", - "result": { - "calls": [ - { - "error": "invalid opcode: INVALID", - "from": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76", - "gas": "0x75fe3", - "gasUsed": "0x75fe3", - "input": "0xa9059cbb000000000000000000000000d4fcab9f0a6dc0493af47c864f6f17a8a5e2e82600000000000000000000000000000000000000000000000000000000000002f4", - "to": "0xe819f024b41358d2c08e3a868a5c5dd0566078d4", - "type": "CALL", - "value": "0x0" - } - ], - "error": "execution reverted", - "from": "0xd4fcab9f0a6dc0493af47c864f6f17a8a5e2e826", - "gas": "0x7dfa6", - "gasUsed": "0x7c1c8", - "input": "0x", - "to": "0x33056b5dcac09a9b4becad0e1dcf92c19bd0af76", - "type": "CALL", - "value": "0xe92596fd6290000" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json deleted file mode 100644 index 333bdd038c..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/oog.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "context": { - "difficulty": "3699098917", - "gasLimit": "5258985", - "miner": "0xd049bfd667cb46aa3ef5df0da3e57db3be39e511", - "number": "2294631", - "timestamp": "1513675366" - }, - "genesis": { - "alloc": { - "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62": { - "balance": "0x0", - "code": "0x6060604052600436106100ba576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100bf578063095ea7b31461014d57806318160ddd146101a757806323b872dd146101d0578063313ce5671461024957806342966c68146102785780635a3b7e42146102b357806370a082311461034157806379cc67901461038e57806395d89b41146103e8578063a9059cbb14610476578063dd62ed3e146104b8575b600080fd5b34156100ca57600080fd5b6100d2610524565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101125780820151818401526020810190506100f7565b50505050905090810190601f16801561013f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015857600080fd5b61018d600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061055d565b604051808215151515815260200191505060405180910390f35b34156101b257600080fd5b6101ba6105ea565b6040518082815260200191505060405180910390f35b34156101db57600080fd5b61022f600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff169060200190919080359060200190919050506105f0565b604051808215151515815260200191505060405180910390f35b341561025457600080fd5b61025c610910565b604051808260ff1660ff16815260200191505060405180910390f35b341561028357600080fd5b6102996004808035906020019091905050610915565b604051808215151515815260200191505060405180910390f35b34156102be57600080fd5b6102c6610a18565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156103065780820151818401526020810190506102eb565b50505050905090810190601f1680156103335780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561034c57600080fd5b610378600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610a51565b6040518082815260200191505060405180910390f35b341561039957600080fd5b6103ce600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610a69565b604051808215151515815260200191505060405180910390f35b34156103f357600080fd5b6103fb610bf8565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561043b578082015181840152602081019050610420565b50505050905090810190601f1680156104685780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561048157600080fd5b6104b6600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610c31565b005b34156104c357600080fd5b61050e600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610e34565b6040518082815260200191505060405180910390f35b6040805190810160405280600881526020017f446f70616d696e6500000000000000000000000000000000000000000000000081525081565b600081600260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506001905092915050565b60005481565b6000808373ffffffffffffffffffffffffffffffffffffffff161415151561061757600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561066557600080fd5b600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205482600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205401101515156106f157fe5b600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054821115151561077c57600080fd5b81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555081600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b601281565b600081600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561096557600080fd5b81600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a260019050919050565b6040805190810160405280600981526020017f446f706d6e20302e32000000000000000000000000000000000000000000000081525081565b60016020528060005260406000206000915090505481565b600081600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ab957600080fd5b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548211151515610b4457600080fd5b81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055508160008082825403925050819055508273ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5836040518082815260200191505060405180910390a26001905092915050565b6040805190810160405280600581526020017f444f504d4e00000000000000000000000000000000000000000000000000000081525081565b60008273ffffffffffffffffffffffffffffffffffffffff1614151515610c5757600080fd5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610ca557600080fd5b600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020540110151515610d3157fe5b80600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b60026020528160005260406000206020528060005260406000206000915091505054815600a165627a7a723058206d93424f4e7b11929b8276a269038402c10c0ddf21800e999916ddd9dff4a7630029", - "nonce": "1", - "storage": { - "0x296b66049cc4f9c8bf3d4f14752add261d1a980b39bdd194a7897baf39ac7579": "0x0000000000000000000000000000000000000000033b2e3c9fc9653f9e72b1e0" - } - }, - "0x94194bc2aaf494501d7880b61274a169f6502a54": { - "balance": "0xea8c39a876d19888d", - "code": "0x", - "nonce": "265", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3699098917", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "5263953", - "hash": "0x03a0f62a8106793dafcfae7b75fd2654322062d585a19cea568314d7205790dc", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x15482cc64b7c00a947f5bf015dfc010db1a6a668c74df61974d6a7848c174408", - "nonce": "0xd1bdb150f6fd170e", - "number": "2294630", - "stateRoot": "0x1ab1a534e84cc787cda1db21e0d5920ab06017948075b759166cfea7274657a1", - "timestamp": "1513675347", - "totalDifficulty": "7160543502214733" - }, - "input": "0xf8ab820109855d21dba00082ca1d9443064693d3d38ad6a7cb579e0d6d9718c8aa6b6280b844a9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f90001ba0ce3ad83f5530136467b7c2bb225f406bd170f4ad59c254e5103c34eeabb5bd69a0455154527224a42ab405cacf0fe92918a75641ce4152f8db292019a5527aa956", - "result": { - "error": "out of gas", - "from": "0x94194bc2aaf494501d7880b61274a169f6502a54", - "gas": "0xca1d", - "gasUsed": "0xca1d", - "input": "0xa9059cbb000000000000000000000000e77b1ac803616503510bed0086e3a7be2627a69900000000000000000000000000000000000000000000000000000009502f9000", - "to": "0x43064693d3d38ad6a7cb579e0d6d9718c8aa6b62", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json deleted file mode 100644 index 3207a298a9..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "context": { - "difficulty": "3665057456", - "gasLimit": "5232723", - "miner": "0xf4d8e706cfb25c0decbbdd4d2e2cc10c66376a3f", - "number": "2294501", - "timestamp": "1513673601" - }, - "genesis": { - "alloc": { - "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9": { - "balance": "0x2a3fc32bcc019283", - "code": "0x", - "nonce": "10", - "storage": {} - }, - "0xabbcd5b340c80b5f1c0545c04c987b87310296ae": { - "balance": "0x0", - "code": "0x606060405236156100755763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d0335ab811461007a578063548db174146100ab5780637f649783146100fc578063b092145e1461014d578063c3f44c0a14610186578063c47cf5de14610203575b600080fd5b341561008557600080fd5b610099600160a060020a0360043516610270565b60405190815260200160405180910390f35b34156100b657600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061028f95505050505050565b005b341561010757600080fd5b6100fa600460248135818101908301358060208181020160405190810160405280939291908181526020018383602002808284375094965061029e95505050505050565b005b341561015857600080fd5b610172600160a060020a03600435811690602435166102ad565b604051901515815260200160405180910390f35b341561019157600080fd5b6100fa6004803560ff1690602480359160443591606435600160a060020a0316919060a49060843590810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965050509235600160a060020a031692506102cd915050565b005b341561020e57600080fd5b61025460046024813581810190830135806020601f8201819004810201604051908101604052818152929190602084018383808284375094965061056a95505050505050565b604051600160a060020a03909116815260200160405180910390f35b600160a060020a0381166000908152602081905260409020545b919050565b61029a816000610594565b5b50565b61029a816001610594565b5b50565b600160209081526000928352604080842090915290825290205460ff1681565b60008080600160a060020a038416158061030d5750600160a060020a038085166000908152600160209081526040808320339094168352929052205460ff165b151561031857600080fd5b6103218561056a565b600160a060020a038116600090815260208190526040808220549295507f19000000000000000000000000000000000000000000000000000000000000009230918891908b908b90517fff000000000000000000000000000000000000000000000000000000000000008089168252871660018201526c01000000000000000000000000600160a060020a038088168202600284015286811682026016840152602a8301869052841602604a820152605e810182805190602001908083835b6020831061040057805182525b601f1990920191602091820191016103e0565b6001836020036101000a0380198251168184511617909252505050919091019850604097505050505050505051809103902091506001828a8a8a6040516000815260200160405260006040516020015260405193845260ff90921660208085019190915260408085019290925260608401929092526080909201915160208103908084039060008661646e5a03f1151561049957600080fd5b5050602060405103519050600160a060020a03838116908216146104bc57600080fd5b600160a060020a0380841660009081526020819052604090819020805460010190559087169086905180828051906020019080838360005b8381101561050d5780820151818401525b6020016104f4565b50505050905090810190601f16801561053a5780820380516001836020036101000a031916815260200191505b5091505060006040518083038160008661646e5a03f1915050151561055e57600080fd5b5b505050505050505050565b600060248251101561057e5750600061028a565b600160a060020a0360248301511690505b919050565b60005b825181101561060157600160a060020a033316600090815260016020526040812083918584815181106105c657fe5b90602001906020020151600160a060020a031681526020810191909152604001600020805460ff19169115159190911790555b600101610597565b5b5050505600a165627a7a723058200027e8b695e9d2dea9f3629519022a69f3a1d23055ce86406e686ea54f31ee9c0029", - "nonce": "1", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3672229776", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "5227619", - "hash": "0xa07b3d6c6bf63f5f981016db9f2d1d93033833f2c17e8bf7209e85f1faf08076", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0x806e151ce2817be922e93e8d5921fa0f0d0fd213d6b2b9a3fa17458e74a163d0", - "nonce": "0xbc5d43adc2c30c7d", - "number": "2294500", - "stateRoot": "0xca645b335888352ef9d8b1ef083e9019648180b259026572e3139717270de97d", - "timestamp": "1513673552", - "totalDifficulty": "7160066586979149" - }, - "input": "0xf9018b0a8505d21dba00832dc6c094abbcd5b340c80b5f1c0545c04c987b87310296ae80b9012473b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988000000000000000000000000000000000000000000000000000000000000000000000000000000001ba0fd659d76a4edbd2a823e324c93f78ad6803b30ff4a9c8bce71ba82798975c70ca06571eecc0b765688ec6c78942c5ee8b585e00988c0141b518287e9be919bc48a", - "result": { - "error": "execution reverted", - "from": "0x0f6cef2b7fbb504782e35aa82a2207e816a2b7a9", - "gas": "0x2dc6c0", - "gasUsed": "0x719b", - "input": "0x73b40a5c000000000000000000000000400de2e016bda6577407dfc379faba9899bc73ef0000000000000000000000002cc31912b2b0f3075a87b3640923d45a26cef3ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000064d79d8e6c7265636f76657279416464726573730000000000000000000000000000000000000000000000000000000000383e3ec32dc0f66d8fe60dbdc2f6815bdf73a988383e3ec32dc0f66d8fe60dbdc2f6815bdf73a98800000000000000000000000000000000000000000000000000000000000000000000000000000000", - "to": "0xabbcd5b340c80b5f1c0545c04c987b87310296ae", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json deleted file mode 100644 index 5c7e5629e9..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/revert_reason.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "context": { - "difficulty": "2", - "gasLimit": "8000000", - "miner": "0x0000000000000000000000000000000000000000", - "number": "3212651", - "timestamp": "1597246515" - }, - "genesis": { - "alloc": { - "0xf58833cf0c791881b494eb79d461e08a1f043f52": { - "balance": "0x0", - "code": "0x608060405234801561001057600080fd5b50600436106100a5576000357c010000000000000000000000000000000000000000000000000000000090048063609ff1bd11610078578063609ff1bd146101af5780639e7b8d61146101cd578063a3ec138d14610211578063e2ba53f0146102ae576100a5565b80630121b93f146100aa578063013cf08b146100d85780632e4176cf146101215780635c19a95c1461016b575b600080fd5b6100d6600480360360208110156100c057600080fd5b81019080803590602001909291905050506102cc565b005b610104600480360360208110156100ee57600080fd5b8101908080359060200190929190505050610469565b604051808381526020018281526020019250505060405180910390f35b61012961049a565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101ad6004803603602081101561018157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506104bf565b005b6101b76108db565b6040518082815260200191505060405180910390f35b61020f600480360360208110156101e357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610952565b005b6102536004803603602081101561022757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b53565b60405180858152602001841515151581526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200194505050505060405180910390f35b6102b6610bb0565b6040518082815260200191505060405180910390f35b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561038a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f486173206e6f20726967687420746f20766f746500000000000000000000000081525060200191505060405180910390fd5b8060010160009054906101000a900460ff161561040f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f416c726561647920766f7465642e00000000000000000000000000000000000081525060200191505060405180910390fd5b60018160010160006101000a81548160ff02191690831515021790555081816002018190555080600001546002838154811061044757fe5b9060005260206000209060020201600101600082825401925050819055505050565b6002818154811061047657fe5b90600052602060002090600202016000915090508060000154908060010154905082565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff1615610587576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f596f7520616c726561647920766f7465642e000000000000000000000000000081525060200191505060405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e000081525060200191505060405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff16600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146107cc57600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691503373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156107c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f466f756e64206c6f6f7020696e2064656c65676174696f6e2e0000000000000081525060200191505060405180910390fd5b61062a565b60018160010160006101000a81548160ff021916908315150217905550818160010160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900460ff16156108bf578160000154600282600201548154811061089c57fe5b9060005260206000209060020201600101600082825401925050819055506108d6565b816000015481600001600082825401925050819055505b505050565b6000806000905060008090505b60028054905081101561094d57816002828154811061090357fe5b9060005260206000209060020201600101541115610940576002818154811061092857fe5b90600052602060002090600202016001015491508092505b80806001019150506108e8565b505090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109f7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180610bde6028913960400191505060405180910390fd5b600160008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900460ff1615610aba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f54686520766f74657220616c726561647920766f7465642e000000000000000081525060200191505060405180910390fd5b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015414610b0957600080fd5b60018060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555050565b60016020528060005260406000206000915090508060000154908060010160009054906101000a900460ff16908060010160019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154905084565b60006002610bbc6108db565b81548110610bc657fe5b90600052602060002090600202016000015490509056fe4f6e6c79206368616972706572736f6e2063616e206769766520726967687420746f20766f74652ea26469706673582212201d282819f8f06fed792100d60a8b08809b081a34a1ecd225e83a4b41122165ed64736f6c63430006060033", - "nonce": "1", - "storage": { - "0x6200beec95762de01ce05f2a0e58ce3299dbb53c68c9f3254a242121223cdf58": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1": { - "balance": "0x57af9d6b3df812900", - "code": "0x", - "nonce": "6", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "IstanbulBlock":1561651, - "chainId": 5, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf888068449504f80832dc6c094f58833cf0c791881b494eb79d461e08a1f043f5280a45c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf12da0264664db3e71fae1dbdaf2f53954be149ad3b7ba8a5054b4d89c70febfacc8b1a0212e8398757963f419681839ae8c5a54b411e252473c82d93dda68405ca63294", - "result": { - "error": "execution reverted", - "from": "0xf7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", - "gas": "0x2dc6c0", - "gasUsed": "0x5940", - "input": "0x5c19a95c000000000000000000000000f7579c3d8a669c89d5ed246a22eb6db8f6fedbf1", - "to": "0xf58833cf0c791881b494eb79d461e08a1f043f52", - "type": "CALL", - "value": "0x0", - "output": "0x08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001e53656c662d64656c65676174696f6e20697320646973616c6c6f7765642e0000" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json deleted file mode 100644 index 11b23a990e..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/selfdestruct.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x61deadff", - "nonce": "1", - "storage": {} - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "result": { - "calls": [ - { - "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "input": "0x", - "to": "0x000000000000000000000000000000000000dEaD", - "type": "SELFDESTRUCT", - "value": "0x4d87094125a369d9bd5" - } - ], - "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb", - "gas": "0x15f90", - "gasUsed": "0x6fcb", - "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "output": "0x", - "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json deleted file mode 100644 index 37723f17dd..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/simple.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "result": { - "calls": [ - { - "from": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "input": "0x", - "to": "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "type": "CALL", - "value": "0x6f05b59d3b20000" - } - ], - "from": "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb", - "gas": "0x15f90", - "gasUsed": "0x9751", - "input": "0x63e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c5", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "to": "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json b/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json deleted file mode 100644 index 499b449a6e..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_legacy/throw.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "context": { - "difficulty": "117009631", - "gasLimit": "4712388", - "miner": "0x294e5d6c39a36ce38af1dca70c1060f78dee8070", - "number": "25009", - "timestamp": "1479891666" - }, - "genesis": { - "alloc": { - "0x70c9217d814985faef62b124420f8dfbddd96433": { - "balance": "0x4ecd70668f5d854a", - "code": "0x", - "nonce": "1638", - "storage": {} - }, - "0xc212e03b9e060e36facad5fd8f4435412ca22e6b": { - "balance": "0x0", - "code": "0x606060405236156101745760e060020a600035046302d05d3f811461017c57806304a7fdbc1461018e5780630e90f957146101fb5780630fb5a6b41461021257806314baa1b61461021b57806317fc45e21461023a5780632b096926146102435780632e94420f1461025b578063325a19f11461026457806336da44681461026d5780633f81a2c01461027f5780633fc306821461029757806345ecd3d7146102d45780634665096d146102dd5780634e71d92d146102e657806351a34eb8146103085780636111bb951461032d5780636f265b93146103445780637e9014e11461034d57806390ba009114610360578063927df5e014610393578063a7f437791461046c578063ad8f50081461046e578063bc6d909414610477578063bdec3ad114610557578063c19d93fb1461059a578063c9503fe2146105ad578063e0a73a93146105b6578063ea71b02d146105bf578063ea8a1af0146105d1578063ee4a96f9146105f3578063f1ff78a01461065c575b61046c610002565b610665600054600160a060020a031681565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600554600090600160a060020a0390811633909116146106a857610002565b61068260015460a060020a900460ff166000145b90565b61069660085481565b61046c600435600154600160a060020a03166000141561072157610002565b610696600d5481565b610696600435600f8160068110156100025750015481565b61069660045481565b61069660035481565b610665600554600160a060020a031681565b61069660043560158160068110156100025750015481565b6106966004355b600b54600f5460009160028202808203928083039290810191018386101561078357601054840186900394505b50505050919050565b61069660025481565b61069660095481565b61046c600554600090600160a060020a03908116339091161461085857610002565b61046c600435600554600090600160a060020a03908116339091161461092e57610002565b6106826001805460a060020a900460ff161461020f565b610696600b5481565b61068260075460a060020a900460ff1681565b6106966004355b600b54601554600091600282028082039280830392908101910183861015610a6c5760165494506102cb565b61046c6004356024356044356040805160015460e360020a631c2d8fb302825260b260020a691858d8dbdd5b9d18dd1b02600483015291516000928392600160a060020a03919091169163e16c7d9891602481810192602092909190829003018187876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610b4657610002565b005b610696600a5481565b61046c60006000600060006000600160009054906101000a9004600160a060020a0316600160a060020a031663e16c7d986040518160e060020a028152600401808060b260020a691858d8dbdd5b9d18dd1b0281526020015060200190506020604051808303816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663c4b0c96a336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515115159050610f1757610002565b61046c5b60015b60058160ff16101561071e57600f6001820160ff166006811015610002578101549060ff83166006811015610002570154101561129057610002565b61069660015460a060020a900460ff1681565b61069660065481565b610696600c5481565b610665600754600160a060020a031681565b61046c600554600090600160a060020a0390811633909116146112c857610002565b6040805160c081810190925261046c9160049160c4918390600690839083908082843760408051808301909152929750909561018495509193509091908390839080828437509095505050505050600154600090600160a060020a03168114156113fb57610002565b610696600e5481565b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60408051918252519081900360200190f35b5060005b60068160ff16101561070857828160ff166006811015610002576020020151600f60ff831660068110156100025701558160ff82166006811015610002576020020151601560ff831660068110156100025701556001016106ac565b61071061055b565b505050565b600e8054820190555b50565b6040805160015460e060020a6313bc6d4b02825233600160a060020a03908116600484015292519216916313bc6d4b9160248181019260209290919082900301816000876161da5a03f115610002575050604051511515905061071557610002565b83861015801561079257508286105b156107b457600f546010546011548689039082030291909104900394506102cb565b8286101580156107c55750600b5486105b156107e757600f546011546012548589039082030291909104900394506102cb565b600b5486108015906107f857508186105b1561081d57600b54600f546012546013549289039281039290920204900394506102cb565b81861015801561082c57508086105b1561084e57600f546013546014548489039082030291909104900394506102cb565b60145494506102cb565b60015460a060020a900460ff1660001461087157610002565b600254600a01431161088257610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150905080600160a060020a031663771d50e16040518160e060020a0281526004018090506000604051808303816000876161da5a03f1156100025750505050565b60015460a060020a900460ff1660001461094757610002565b600254600a01431161095857610002565b6040805160015460e360020a631c2d8fb302825260a860020a6a636f6e74726163746170690260048301529151600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180517f51a34eb8000000000000000000000000000000000000000000000000000000008252600482018690529151919350600160a060020a03841692506351a34eb8916024808301926000929190829003018183876161da5a03f11561000257505050600b8290554360025560408051838152905130600160a060020a0316917fa609f6bd4ad0b4f419ddad4ac9f0d02c2b9295c5e6891469055cf73c2b568fff919081900360200190a25050565b838610158015610a7b57508286105b15610a9d576015546016546017548689039082900302919091040194506102cb565b828610158015610aae5750600b5486105b15610ad0576015546017546018548589039082900302919091040194506102cb565b600b548610801590610ae157508186105b15610b0657600b546015546018546019549289039281900392909202040194506102cb565b818610158015610b1557508086105b15610b3757601554601954601a548489039082900302919091040194506102cb565b601a54860181900394506102cb565b60015460a060020a900460ff16600014610b5f57610002565b6001805460a060020a60ff02191660a060020a17908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919450600160a060020a038516925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604080518051600a556005547ffebf661200000000000000000000000000000000000000000000000000000000825233600160a060020a03908116600484015216602482015260448101879052905163febf661291606480820192600092909190829003018183876161da5a03f115610002575050508215610cc7576007805473ffffffffffffffffffffffffffffffffffffffff191633179055610dbb565b6040805160055460065460e060020a63599efa6b028352600160a060020a039182166004840152602483015291519184169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050604080516006547f56ccb6f000000000000000000000000000000000000000000000000000000000825233600160a060020a03166004830152602482015290516356ccb6f091604480820192600092909190829003018183876161da5a03f115610002575050600580546007805473ffffffffffffffffffffffffffffffffffffffff19908116600160a060020a038416179091551633179055505b6007805460a060020a60ff02191660a060020a87810291909117918290556008544301600955900460ff1615610df757600a54610e039061029e565b600a54610e0b90610367565b600c55610e0f565b600c555b600c54670de0b6b3a7640000850204600d55600754600554604080517f759297bb000000000000000000000000000000000000000000000000000000008152600160a060020a039384166004820152918316602483015260448201879052519184169163759297bb91606481810192600092909190829003018183876161da5a03f11561000257505060408051600754600a54600d54600554600c5460a060020a850460ff161515865260208601929092528486019290925260608401529251600160a060020a0391821694509281169230909116917f3b3d1986083d191be01d28623dc19604728e29ae28bdb9ba52757fdee1a18de2919081900360800190a45050505050565b600954431015610f2657610002565b6001805460a060020a900460ff1614610f3e57610002565b6001805460a060020a60ff0219167402000000000000000000000000000000000000000017908190556040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f1156100025750506040805180516004805460e260020a633e4baddd028452908301529151919750600160a060020a038816925063f92eb77491602482810192602092919082900301816000876161da5a03f115610002575050604051516007549095506000945060a060020a900460ff1615905061105c57600a5484111561105757600a54600d54670de0b6b3a7640000918603020492505b61107e565b600a5484101561107e57600a54600d54670de0b6b3a764000091869003020492505b60065483111561108e5760065492505b6006548390039150600083111561111857604080516005546007547f5928d37f000000000000000000000000000000000000000000000000000000008352600160a060020a0391821660048401528116602483015260448201869052915191871691635928d37f91606481810192600092909190829003018183876161da5a03f115610002575050505b600082111561117a576040805160055460e060020a63599efa6b028252600160a060020a0390811660048301526024820185905291519187169163599efa6b91604481810192600092909190829003018183876161da5a03f115610002575050505b6040805185815260208101849052808201859052905130600160a060020a0316917f89e690b1d5aaae14f3e85f108dc92d9ab3763a58d45aed8b59daedbbae8fe794919081900360600190a260008311156112285784600160a060020a0316634cc927d785336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f11561000257505050611282565b84600160a060020a0316634cc927d7600a60005054336040518360e060020a0281526004018083815260200182600160a060020a03168152602001925050506000604051808303816000876161da5a03f115610002575050505b600054600160a060020a0316ff5b60156001820160ff166006811015610002578101549060ff8316600681101561000257015411156112c057610002565b60010161055e565b60015460a060020a900460ff166000146112e157610002565b600254600a0143116112f257610002565b6001546040805160e360020a631c2d8fb302815260a860020a6a636f6e74726163746170690260048201529051600160a060020a03929092169163e16c7d989160248181019260209290919082900301816000876161da5a03f11561000257505060408051805160055460065460e060020a63599efa6b028452600160a060020a03918216600485015260248401529251909450918416925063599efa6b916044808301926000929190829003018183876161da5a03f1156100025750505080600160a060020a0316632b68bb2d6040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050600054600160a060020a03169050ff5b6001546040805160e060020a6313bc6d4b02815233600160a060020a039081166004830152915191909216916313bc6d4b91602480830192602092919082900301816000876161da5a03f11561000257505060405151151590506106a85761000256", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000002cccf5e0538493c235d1c5ef6580f77d99e91396", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000061a9", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000070c9217d814985faef62b124420f8dfbddd96433" - } - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "117066792", - "extraData": "0xd783010502846765746887676f312e372e33856c696e7578", - "gasLimit": "4712388", - "hash": "0xe23e8d4562a1045b70cbc99fefb20c101a8f0fc8559a80d65fea8896e2f1d46e", - "miner": "0x71842f946b98800fe6feb49f0ae4e253259031c9", - "mixHash": "0x0aada9d6e93dd4db0d09c0488dc0a048fca2ccdc1f3fc7b83ba2a8d393a3a4ff", - "nonce": "0x70849d5838dee2e9", - "number": "25008", - "stateRoot": "0x1e01d2161794768c5b917069e73d86e8dca80cd7f3168c0597de420ab93a3b7b", - "timestamp": "1479891641", - "totalDifficulty": "1896347038589" - }, - "input": "0xf88b8206668504a817c8008303d09094c212e03b9e060e36facad5fd8f4435412ca22e6b80a451a34eb8000000000000000000000000000000000000000000000027fad02094277c000029a0692a3b4e7b2842f8dd7832e712c21e09f451f416c8976d5b8d02e8c0c2b4bea9a07645e90fc421b63dd755767fd93d3c03b4ec0c4d8fafa059558d08cf11d59750", - "result": { - "error": "invalid jump destination", - "from": "0x70c9217d814985faef62b124420f8dfbddd96433", - "gas": "0x3d090", - "gasUsed": "0x3d090", - "input": "0x51a34eb8000000000000000000000000000000000000000000000027fad02094277c0000", - "to": "0xc212e03b9e060e36facad5fd8f4435412ca22e6b", - "type": "CALL", - "value": "0x0" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json deleted file mode 100644 index dbece7229d..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/calldata.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "genesis": { - "difficulty": "11934798510088", - "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773", - "gasLimit": "3141592", - "hash": "0xfc543a4a551afbd4a6c5d6d49041371e6bb58b1108c12aaec7f487ce656bb97f", - "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069", - "mixHash": "0xa6a1e67fc68da76b8d9cc3ce1c45d5e1f4bbd96b5dcfddbe0017d7fa99903ead", - "nonce": "0x5f00c600268b4659", - "number": "995200", - "stateRoot": "0x3579328470dd2aef5b9da69f5480cbe0d375e653b530ab3c1aee0da5e1ff4c94", - "timestamp": "1455322761", - "totalDifficulty": "7077231809278509672", - "alloc": { - "0x200edd17f30485a8735878661960cd7a9a95733f": { - "balance": "0x0", - "code": "0x3660008037602060003660003473273930d21e01ee25e4c219b63259d214872220a261235a5a03f21560015760206000f3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000104": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf04": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf05": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf06": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xa611e7c895a426c0477bc9e280db9c3b1e456dc6310ffcf23926ef5186c1facc": "0x0000000000000000000000000000000000000000000000000000000000000002", - "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c4110": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x273930d21e01ee25e4c219b63259d214872220a2": { - "balance": "0x0", - "code": "0x606060405236156100da5760e060020a6000350463173825d9811461012c5780632f54bf6e146101875780634123cb6b146101af57806352375093146101b857806354fd4d50146101c25780635c52c2f5146101cc578063659010e7146101fd5780637065cb4814610207578063746c91711461023b578063797af62714610244578063b20d30a914610257578063b61d27f61461028b578063b75c7dc6146102ac578063ba51a6df146102db578063c2cf73261461030f578063cbf0b0c01461034d578063f00d4b5d14610381578063f1736d86146103ba575b6103c4600034111561012a5760408051600160a060020a033216815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b6103c46004356000600036436040518084848082843750505090910190815260405190819003602001902090506106c9815b600160a060020a03321660009081526101026020526040812054818082811415610c3f57610d97565b6103c66004355b600160a060020a03811660009081526101026020526040812054115b919050565b6103c660015481565b6103c66101075481565b6103c66101085481565b6103c46000364360405180848480828437505050909101908152604051908190036020019020905061081a8161015e565b6103c66101065481565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506106418161015e565b6103c660005481565b6103c66004355b600081610a7d8161015e565b6103c46004356000364360405180848480828437505050909101908152604051908190036020019020905061080e8161015e565b6103c66004803590602480359160443591820191013560006108393261018e565b6103c4600435600160a060020a033216600090815261010260205260408120549080828114156103d857610457565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506107888161015e565b6103c6600435602435600082815261010360209081526040808320600160a060020a038516845261010290925282205482818114156107e157610805565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506108288161015e565b6103c46004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104e28161015e565b6103c66101055481565b005b60408051918252519081900360200190f35b50506000828152610103602052604081206001810154600284900a9290831611156104575780546001828101805492909101835590839003905560408051600160a060020a03321681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b50505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a1505b505050565b15610457576104f08361018e565b156104fb57506104dd565b600160a060020a03841660009081526101026020526040812054925082141561052457506104dd565b61045d5b6101045460005b81811015610ee457610104805461010991600091849081101561000257600080516020610f9f83398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f6992601f9290920104810190610a65565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561063c5761064f8261018e565b1561065a575061063e565b610662610528565b60015460fa90106106775761067561068c565b505b60015460fa90106105a2575061063e565b6107465b600060015b600154811015610a79575b600154811080156106bc5750600281610100811015610002570154600014155b15610d9f5760010161069c565b156104dd57600160a060020a0383166000908152610102602052604081205492508214156106f7575061063c565b6001600160005054036000600050541115610712575061063c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610688610528565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561063c5760015482111561079d575061063e565b60008290556107aa610528565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001820154600282900a908116600014156108005760009350610805565b600193505b50505092915050565b1561063c575061010555565b1561063e5760006101065550565b1561063c5781600160a060020a0316ff5b15610a555761084d846000610e793261018e565b15610909577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00432858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a5592505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061093990508161024b565b15801561095c575060008181526101096020526040812054600160a060020a0316145b15610a555760008181526101096020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a5d579182015b82811115610a5d5782358260005055916020019190600101906109b1565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328132868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b506109cf9291505b80821115610a795760008155600101610a65565b5090565b15610c2c5760008381526101096020526040812054600160a060020a031614610c2c5760408051600091909120805460018201546002929092018054600160a060020a0392909216939091819083908015610afd57820191906000526020600020905b815481529060010190602001808311610ae057829003601f168201915b505091505060006040518083038185876185025a03f150505060008481526101096020908152604080519281902080546001820154600160a060020a033281811688529587018b905293860181905292166060850181905260a06080860181815260029390930180549187018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a975094958a959293909160c083019084908015610bcf57820191906000526020600020905b815481529060010190602001808311610bb257829003601f168201915b5050965050505050505060405180910390a160008381526101096020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c3292601f9290920104810190610a65565b50919050565b50505060019150506101aa565b60008581526101036020526040812080549093501415610cc7576000805483556001838101919091556101048054918201808255828015829011610c9657818360005260206000209182019101610c969190610a65565b50505060028301819055610104805487929081101561000257600091909152600080516020610f9f83398151915201555b506001810154600283900a90811660001415610d975760408051600160a060020a03321681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1815460019011610d84576000858152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f9f8339815191529290920181905580825560018083018290556002909201559450610d979050565b8154600019018255600182018054821790555b505050919050565b5b60018054118015610dc257506001546002906101008110156100025701546000145b15610dd65760018054600019019055610da0565b60015481108015610df95750600154600290610100811015610002570154600014155b8015610e1357506002816101008110156100025701546000145b15610e7457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b610691565b156101aa5761010754610e8f5b62015180420490565b1115610ea857600061010655610ea3610e86565b610107555b6101065480830110801590610ec65750610106546101055490830111155b15610edc575061010680548201905560016101aa565b5060006101aa565b61063c6101045460005b81811015610f745761010480548290811015610002576000918252600080516020610f9f833981519152015414610f6157610104805461010391600091849081101561000257600080516020610f9f83398151915201548252506020919091526040812081815560018101829055600201555b600101610eee565b50505060010161052f565b61010480546000808355919091526104dd90600080516020610f9f83398151915290810190610a6556004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe" - }, - "0x4f5777744b500616697cb655dcb02ee6cd51deb5": { - "balance": "0xb0983f1b83eec290", - "nonce": "2" - }, - "0xf8b483dba2c3b7176a3da549ad41a48bb3121069": { - "balance": "0x16969a0ba2c2d384d07", - "nonce": "67521" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "995201", - "difficulty": "11940626048551", - "timestamp": "1455322773", - "gasLimit": "3141592", - "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069" - }, - "input": "0xf89102850a954d522e8303308594200edd17f30485a8735878661960cd7a9a95733f888ac7230489e80000a4ba51a6df00000000000000000000000000000000000000000000000000000000000000001ca04f2cc45b96f965296382b2e9b657e90808301d5179035a5d91a2de7b912def20a056e19271ea4e19e4e034f38e925e312beed4d300c267160eeb2f565c42deb578", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0x4f5777744b500616697cb655dcb02ee6cd51deb5", - "gas": "0x33085", - "gasUsed": "0x1a9e5", - "to": "0x200edd17f30485a8735878661960cd7a9a95733f", - "input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000", - "output": "0xba51a6df00000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "from": "0x200edd17f30485a8735878661960cd7a9a95733f", - "gas": "0x2c263", - "gasUsed": "0x1b0e4", - "to": "0x273930d21e01ee25e4c219b63259d214872220a2", - "input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000", - "logs": [ - { - "address": "0x200edd17f30485a8735878661960cd7a9a95733f", - "topics": [ - "0xe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda" - ], - "data": "0x0000000000000000000000004f5777744b500616697cb655dcb02ee6cd51deb5be96016bb57376da7a6d296e0a405ee1501778227dfa604df0a81cb1ae018598", - "position": "0x0" - }, - { - "address": "0x200edd17f30485a8735878661960cd7a9a95733f", - "topics": [ - "0xacbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000", - "position": "0x0" - } - ], - "value": "0x8ac7230489e80000", - "type": "CALLCODE" - } - ], - "value": "0x8ac7230489e80000", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json deleted file mode 100644 index 2b03dbb8dd..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/delegatecall.json +++ /dev/null @@ -1,413 +0,0 @@ -{ - "genesis": { - "difficulty": "80344740444880", - "extraData": "0x7777772e62772e636f6d", - "gasLimit": "1498600", - "hash": "0xf5d85a80bdbc5d28a16b8eb0d1b9dd18316ddc3655c7d5c901b67acdb7700037", - "miner": "0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1", - "mixHash": "0x433ae590edf0e7ba9aac698bb7d3be2300e3e79d175db13528ff3e79a3f93910", - "nonce": "0x084adce0020c6fd8", - "number": "2340152", - "stateRoot": "0x38295a2634c9c62d48bcbf2ef2ae83768b9055c1f5e6469d17a5d1bcb052072e", - "timestamp": "1475034708", - "totalDifficulty": "66488249547380413902", - "alloc": { - "0x01e60b511fced1eb2b5b40991eb1dfd171a6df42": { - "balance": "0x0", - "code": "0x6060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100a557806318160ddd1461012457806323b872dd1461012f578063313ce567146101dc578063475a9fa9146101f057806370a0823114610215578063721a37d21461024357806395d89b411461008f578063a9059cbb14610268578063dd62ed3e146102e7575b005b61031d6040805160208101909152600081525b90565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db63c6605267600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b6102316003546100a2565b61038b60043560243560443560008054604080517fa00bfa1100000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038781166024830152868116604483015260648201869052929092166084830152517319ee743d2e356d5f0e4d97cc09b96d06e933d0db9163a00bfa119160a482810192602092919082900301818660325a03f4156100025750506040515195945050505050565b604080516000815290519081900360200190f35b61038b6004356024356000805433600160a060020a0390811691161461039f57610002565b600160a060020a03600435166000908152600160205260409020545b60408051918252519081900360200190f35b61038b6004356024356000805433600160a060020a039081169116146103ce57610002565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db6388d5fecb600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b610231600435602435600160a060020a038281166000908152600260209081526040808320938516835292905220545b92915050565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561037d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080519115158252519081900360200190f35b50600160a060020a03821660009081526001602081905260409091208054830190556003805483019055610317565b600160a060020a038316600090815260016020526040902054821161040a57506040600020805482900390556003805482900390556001610317565b50600061031756", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000012098a4651fb262f7", - "0xfae22198212900725daa5db635d1fda7b0fa195adaabdc806a7267959c3d8ae4": "0x00000000000000000000000000000000000000000000000026cbcbc35aaa62f7" - } - }, - "0x19ee743d2e356d5f0e4d97cc09b96d06e933d0db": { - "balance": "0x0", - "code": "0x6503060000000050606060405260e060020a600035046388d5fecb811461003c578063a00bfa11146100e3578063c6605267146102dc575b610007565b610356600435602435604435600160a060020a0333166000908152602084905260408120548290108015906100715750600082115b1561036a57600160a060020a0333811660008181526020878152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161034f565b610356600435602435604435606435608435600160a060020a03841660009081526020869052604081205483901080159061011e5750600083115b80156101bb5750600160a060020a0385811660009081526001880160209081526040808320339094168352929052205483901015806101bb575081600160a060020a0316631934d55a86336040518360e060020a0281526004018083600160a060020a0316815260200182600160a060020a03168152602001925050506020604051808303816000876161da5a03f1156100075750506040515190505b1561037257600160a060020a038481166000908152602088815260408083208054880190558884168084528184208054899003905581517f1934d55a00000000000000000000000000000000000000000000000000000000815260048101919091523385166024820152905193861693631934d55a936044838101949383900301908290876161da5a03f115610007575050604051511515905061028957600160a060020a038581166000908152600188016020908152604080832033909416835292905220805484900390555b83600160a060020a031685600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3506001610376565b610356600435602435604435600160a060020a033381166000818152600186016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b9392505050565b604080519115158252519081900360200190f35b50600061034f565b5060005b9594505050505056" - }, - "0x3de712784baf97260455ae25fb74f574ec9c1add": { - "balance": "0x23c8352f33854625", - "nonce": "80" - }, - "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd": { - "balance": "0x0", - "nonce": "29", - "code": "0x606060405236156100cf5760e060020a600035046307d5b82681146100d157806315e812ad146101775780631934d55a1461018d5780631d007f5f146101c65780631f0c1e0c146101ee5780633983d5c41461022b5780634025b29314610243578063428d64bd1461030f578063481b659d146104b557806357bcccb6146104f45780638c172fa21461052f5780639ba5b4e9146105ea578063a4a7cf5c146106ca578063b11e3b82146106ed578063c51cf179146107a6578063d6911046146107c2578063eff6be2f146109cb575b005b6109f2600435602435600082815260016020908152604080832060049081015482517f23b872dd00000000000000000000000000000000000000000000000000000000815233600160a060020a0390811693820193909352308316602482015260448101879052925185948594859493909316926323b872dd9260648281019392829003018187876161da5a03f1156100025750506040515115159050610a6d57610002565b6004545b60408051918252519081900360200190f35b6109f2600435602435600160a060020a0382811660009081526003602090815260408083209385168352929052205460ff165b92915050565b6109f2600435600080546101009004600160a060020a039081163390911614610be757610002565b610a066004356024356000828152600160205260408120600901805483908110156100025750815260209020810154600160a060020a03166101c0565b61017b6004355b600454620f4240908202045b919050565b6109f26004356024356000805b600084815260016020526040902060090154811015610c13576040600090812090859052600160205260090180548290811015610002576000918252604080516020808520909301547f721a37d2000000000000000000000000000000000000000000000000000000008252600160a060020a03338116600484015260248301899052925192169363721a37d293604483810194919391929183900301908290876161da5a03f1156100025750506040515115159050610c8d57610002565b604080516024803560048181013560208181028087018201909752818652610a2396833596939560449501929182919085019084908082843750949650505050505050604080516020818101835260008083528351918201909352828152909190819081905b8551831015610c9f57600091505b600160005060008785815181101561000257602090810290910181015182528101919091526040016000206009015460ff831610156104a957600060016000506000888681518110156100025760209081029091018101518252810191909152604001600020600901805460ff85169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231896040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191909111159050610f59576001600050600087858151811015610002576020908102909101810151825281019190915260400160002060090154909301600201925b60019290920191610375565b6109f260043533600160a060020a039081166000908152600360209081526040808320938516835292905220805460ff1916600190811790915561023e565b6109f260043533600160a060020a039081166000908152600360209081526040808320938516835292905220805460ff19169055600161023e565b60048035600090815260016020818152604092839020600981015481548551968301546002840154600385015460088601546005870154600688015499880154600790980154958c52600160a060020a03888116998d019990995260a060020a90970460ff90811615158c8c015260608c019390935260808b019190915260a08a019490945290851660c08901529290931660e087015261010086019390935216151561012084015261014083015251908190036101600190f35b60408051600480358082013560208181028086018201909652818552610a23959394602494909385019291829190850190849080828437509496505050505050506040805160208181018352600080835283519182019093528281529091908190815b8551831015610f93576000600260005060008886815181101561000257602090810290910181015182528101919091526040016000205411156106be576002600050600087858151811015610002576020908102909101810151825281019190915260400160002054909301600201925b6001929092019161064d565b61017b6004356000805481908190819081908190819060ff161561115757610002565b6040805160e4356004818101356020818102808601820190965281855261017b95833595602480359660443596606435966084359660a4359660c4359693956101049501929182919085019084908082843750949650505050505050600080808080808d81148061076657508c801561076657508a8c12155b80610774575060028a60ff16105b80610788575087600160a060020a03166000145b8061079c575088600160a060020a03166000145b1561177157611760565b61017b600435600454620f42409081039082020481900361023e565b60408051600480358082013560208181028086018201909652818552610a23959394602494909385019291829190850190849080828437509496505093359350506044359150506064356040805160208181018352600080835283519182019093528281529091908190815b8851831015611cee576000600102600160005060008b8681518110156100025760209081029091018101518252810191909152604001600020541180156108c7575087600160a060020a0316600014806108c7575087600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060050154600160a060020a0316145b8015610925575086600160a060020a031660001480610925575086600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b8015610983575085600160a060020a031660001480610983575085600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060010154600160a060020a0316145b156109bf57600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090154909301600c01925b6001929092019161082e565b6109f26004356000805433600160a060020a03908116610100909204161461234c57610002565b604080519115158252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f1509050019250505060405180910390f35b610a7685610232565b92508285039150600083118015610b00575060008681526001602090815260408083206004908101548251855460e060020a63a9059cbb0282526101009004600160a060020a039081169382019390935260248101899052925191169363a9059cbb936044848101949193929183900301908290876161da5a03f115610002575050604051511590505b15610b0a57610002565b5060005b60008681526001602052604090206009015460ff82161015610bd35760406000908120908790526001602052600901805460ff831690811015610002576000918252604080516020808520909301547f475a9fa9000000000000000000000000000000000000000000000000000000008252600160a060020a03338116600484015260248301889052925192169363475a9fa993604483810194919391929183900301908290876161da5a03f1156100025750506040515115159050610bdf57610002565b50600195945050505050565b600101610b0e565b506000805474ffffffffffffffffffffffffffffffffffffffff0019166101008302179055600161023e565b6000848152600160209081526040808320600490810154825160e060020a63a9059cbb028152600160a060020a033381169382019390935260248101899052925191169363a9059cbb936044848101949193929183900301908290876161da5a03f1156100025750506040515115159050610c9557610002565b600101610250565b5060019392505050565b83604051805910610cad5750595b908082528060200260200182016040528015610cc4575b506000945084935090505b8551831015610f6557600091505b600160005060008785815181101561000257602090810290910181015182528101919091526040016000206009015460ff83161015610f7b57600060016000506000888681518110156100025760209081029091018101518252810191909152604001600020600901805460ff85169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231896040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191909111159050610f8757858381518110156100025790602001906020020151600190048185815181101561000257602090810290910101528551600190600090889086908110156100025760209081029091018101518252810191909152604001600020600901548151829060018701908110156100025760209081029091010152600091505b600160005060008785815181101561000257602090810290910181015182528101919091526040016000206009015460ff83161015610f6f5760016000506000878581518110156100025760209081029091018101518252810191909152604001600020600901805460ff84169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231886040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051518251909150829060ff8516870160020190811015610002576020908102909101015260019190910190610e49565b60019190910190610383565b9695505050505050565b6002820160ff16909301925b60019290920191610ccf565b60019190910190610cdd565b83604051805910610fa15750595b908082528060200260200182016040528015610fb8575b506000945084935091505b85518310156111125760006002600050600088868151811015610002576020908102909101810151825281019190915260400160002054111561114b578583815181101561000257906020019060200201516001900482858151811015610002576020908102909101015285516002906000908890869081101561000257602090810290910181015182528101919091526040016000205482518390600187019081101561000257602090810290910101525060005b600260005060008785815181101561000257602090810290910181015182528101919091526040016000205481101561111b5760026000506000878581518110156100025760209081029091018101518252810191909152604001600020805482908110156100025760009182526020909120015482518390868401600201908110156100025760209081029091010152600101611079565b50949350505050565b60026000506000878581518110156100025750506020858102890181015182528290526040902054909401909301925b60019290920191610fc3565b6000805460ff191660019081178255898252602052604090206007015460ff1615156112e85760406000818120600581015483516006909201547f5101770200000000000000000000000000000000000000000000000000000000835260048301529251600160a060020a0393909316926351017702926024838101936020939290839003909101908290876161da5a03f115610002575050604051511515905061120457611338611347565b6000888152600160209081526040808320815160058201546006909201547f5d1a3b8200000000000000000000000000000000000000000000000000000000825260048201529151600160a060020a039190911693635d1a3b82936024808501949193929183900301908290876161da5a03f1156100025750505060405180519060200150600160005060008a600019168152602001908152602001600020600050600801600050819055506001600160005060008a60001916815260200190815260200160002060005060070160006101000a81548160ff021916908302179055505b6000888152600160208190526040909120015460a060020a900460ff16156113535760406000908120908990526001602052600281015460089091015412156115435760009450611598565b8596505b505050505050919050565b6113345b6000805460ff19169055565b6000888152600160205260409020600981018054600890920154909181101561000257600091825260208083206040805193909101547f70a08231000000000000000000000000000000000000000000000000000000008452600160a060020a03338116600486015291519116936370a082319360248181019493929183900301908290876161da5a03f115610002575050604051519650505b600091505b60008881526001602052604090206009015460ff831610156116d65760406000908120908990526001602052600901805460ff84169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604080515160008b81526001602052919091206009018054919350915060ff84169081101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a031663721a37d233836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061175057610002565b60008881526001602052604090206003810154600890910154131561156c576127109450611598565b600088815260016020526040902060028101546003820154600890920154918190039103612710020594505b6000888152600160208190526040909120600901805461271088810361ffff16975087810396509286929181101561000257906000526020600020900160009054906101000a9004600160a060020a0316600160a060020a03166370a08231336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604080515160008d815260016020529182206009018054919094029389935091908110156100025790815260208120909054906101000a9004600160a060020a0316600160a060020a03166370a08231336040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750505060405180519060200150020104955085506113ed565b6000888152600160209081526040808320600490810154825160e060020a63a9059cbb028152600160a060020a0333811693820193909352602481018c9052925191169363a9059cbb936044848101949193929183900301908290876161da5a03f115610002575050604051511515905061134357610002565b600191909101906113f2565b8495505b505050505098975050505050505050565b8d8d8d8d8d8d8d8d604051808960001916815260200188151560f860020a0281526001018781526020018681526020018560ff1660f860020a02815260010184600160a060020a03166c0100000000000000000000000002815260140183600160a060020a03166c010000000000000000000000000281526014018280519060200190602002808383829060006004602084601f0104600302600f01f1509050019850505050505050505060405180910390209450600060010260016000506000876000191681526020019081526020016000206000506000016000505460001916111561185e57611760565b87600160a060020a031663c91d7e9c886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f150905001925050506040604051808303816000876161da5a03f1156100025750506040518051602091909101519095509350506000841180156119bd575082600160a060020a03166323b872dd3330876040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506020604051808303816000876161da5a03f11561000257505060405151159050806119bd575082600160a060020a031663095ea7b389866040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511590505b156119c757610002565b87600160a060020a031663c1b06513886040518260e060020a02815260040180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f150905001925050506020604051808303816000876161da5a03f115610002575050604051519250506000821415611a5257610002565b60008e81526002602052604090208054600181018083558281838015829011611a9e57818360005260206000209182019101611a9e91905b80821115611c975760008155600101611a8a565b50505091909060005260206000209001600087909190915055508d60016000506000876000191681526020019081526020016000206000506000016000508190555087600160005060008760001916815260200190815260200160002060005060050160006101000a815481600160a060020a0302191690830217905550816001600050600087600019168152602001908152602001600020600050600601600050819055508c600160005060008760001916815260200190815260200160002060005060010160146101000a81548160ff021916908302179055508b6001600050600087600019168152602001908152602001600020600050600201600050819055508a60016000506000876000191681526020019081526020016000206000506003016000508190555088600160005060008760001916815260200190815260200160002060005060040160006101000a815481600160a060020a030219169083021790555033600160005060008760001916815260200190815260200160002060005060010160006101000a815481600160a060020a0302191690830217905550600090505b8960ff168160ff16101561175c57600085815260016020819052604090912060090180549182018082559091908281838015829011611c9b57600083815260209020611c9b918101908301611a8a565b5090565b5050509190906000526020600020900160006040516104368061236c833901809050604051809103906000f0825473ffffffffffffffffffffffffffffffffffffffff1916179091555050600101611c47565b83604051805910611cfc5750595b908082528060200260200182016040528015611d13575b506000945084935091505b8851831015611fa2576000600102600160005060008b868151811015610002576020908102909101810151825281019190915260400160002054118015611db7575087600160a060020a031660001480611db7575087600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060050154600160a060020a0316145b8015611e15575086600160a060020a031660001480611e15575086600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b8015611e73575085600160a060020a031660001480611e73575085600160a060020a0316600160005060008b868151811015610002576020908102909101810151825281019190915260400160002060010154600160a060020a0316145b15611fe5578883815181101561000257906020019060200201516001900482858151811015610002576020908102909101015288516001906000908b908690811015610002576020908102909101810151825281019190915260400160002054825183906001870190811015610002576020908102909101015288516001906000908b9086908110156100025760209081029091018101518252810191909152604001600020600101548251600160a060020a03919091169083906002870190811015610002576020908102909101015288516001906000908b90869081101561000257602090810290910181015182528101919091526040016000206001015460a060020a900460ff1615611ff157600182856003018151811015610002576020908102909101015261200c565b50979650505050505050565b600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090154909301600c01925b60019290920191611d1e565b60008285600301815181101561000257602090810290910101525b600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060020154825183906004870190811015610002576020908102909101015288516001906000908b908690811015610002576020908102909101810151825281019190915260400160002060030154825183906005870190811015610002576020908102909101015288516001906000908b9086908110156100025760209081029091018101518252810191909152604001600020600401548251600160a060020a03919091169083906006870190811015610002576020908102909101015288516001906000908b9086908110156100025760209081029091018101518252810191909152604001600020600501548251600160a060020a03919091169083906007870190811015610002576020908102909101015288516001906000908b908690811015610002576020908102909101810151825281019190915260400160002060060154825183906008870190811015610002576020908102909101015288516001906000908b90869081101561000257602090810290910181015182528101919091526040016000206007015460ff16156121ee576001828560090181518110156100025760209081029091010152612209565b60008285600901815181101561000257602090810290910101525b600160005060008a85815181101561000257602090810290910181015182528101919091526040016000206008015482518390600a870190811015610002576020908102909101015288516001906000908b90869081101561000257602090810290910181015182528101919091526040016000206009015482518390600b87019081101561000257602090810290910101525060005b600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090154811015611fae57600160005060008a858151811015610002576020908102909101810151825281019190915260400160002060090180548290811015610002576000918252602090912001548251600160a060020a0391909116908390868401600c019081101561000257602090810290910101526001016122a0565b620f424082101561236457506004819055600161023e565b50600061023e56606060405260008054600160a060020a03191633179055610412806100246000396000f36060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100a557806318160ddd1461012457806323b872dd1461012f578063313ce567146101dc578063475a9fa9146101f057806370a0823114610215578063721a37d21461024357806395d89b411461008f578063a9059cbb14610268578063dd62ed3e146102e7575b005b61031d6040805160208101909152600081525b90565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db63c6605267600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b6102316003546100a2565b61038b60043560243560443560008054604080517fa00bfa1100000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038781166024830152868116604483015260648201869052929092166084830152517319ee743d2e356d5f0e4d97cc09b96d06e933d0db9163a00bfa119160a482810192602092919082900301818660325a03f4156100025750506040515195945050505050565b604080516000815290519081900360200190f35b61038b6004356024356000805433600160a060020a0390811691161461039f57610002565b600160a060020a03600435166000908152600160205260409020545b60408051918252519081900360200190f35b61038b6004356024356000805433600160a060020a039081169116146103ce57610002565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db6388d5fecb600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b610231600435602435600160a060020a038281166000908152600260209081526040808320938516835292905220545b92915050565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561037d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080519115158252519081900360200190f35b50600160a060020a03821660009081526001602081905260409091208054830190556003805483019055610317565b600160a060020a038316600090815260016020526040902054821161040a57506040600020805482900390556003805482900390556001610317565b50600061031756", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a0600", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x00000000000000000000000000000000000000000000000000000000000007d0", - "0x6b8ad191d0fa8204d4eafca22ce4ec42425fde2eecf25ce484ecc76765b9a937": "0x00000000000000000000000001e60b511fced1eb2b5b40991eb1dfd171a6df42", - "0x6b8ad191d0fa8204d4eafca22ce4ec42425fde2eecf25ce484ecc76765b9a938": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e854": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d915", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e855": "0x00000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e856": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e857": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e858": "0x00000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e859": "0x000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85a": "0x846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f1", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x71dbd1e5cfc57324881ede454ea48ef3502c5c0b0454ccd622624a7061c2e85d": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - }, - "0x61c808d82a3ac53231750dadc13c777b59310bd9": { - "balance": "0x90a7af5d4755984561", - "nonce": "197408" - }, - "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5": { - "balance": "0x0", - "code": "0x606060405236156100a35760e060020a6000350463031d973e81146100a557806316181bb7146100da5780635aa97eeb146103b1578063674cc1f5146104f75780636da84ec0146105d7578063929e626e146105fe578063a0bde7e8146106ac578063bbd4f8541461078b578063c1fd43391461098e578063c3c95c7b14610a88578063db833e3a14610afe578063df6c13c314610cfe578063ebb7119414610d13575b005b610d4960043560008181526020819052604081206004015481908390600160a060020a039081163390911614610dcb57610002565b610d0160043560243560443560643560008481526020819052604080822054815160e160020a63460b97d1028152600481018290529151909183918291829182916000805160206123dd83398151915291638c172fa29160248181019261016092909190829003018187876161da5a03f1156100025750506040805160a081015160c08201517fc51cf179000000000000000000000000000000000000000000000000000000008352600483018d90529251909750919550600160a060020a038616926323b872dd92339230929163c51cf1799160248181019260209290919082900301818b876161da5a03f11561000257505060408051805160e060020a6323b872dd028252600160a060020a039586166004830152939094166024850152918d01604484015250516064828101926020929190829003018187876161da5a03f11561000257505060405151159050806102e8575082600160a060020a031663095ea7b36000805160206123dd8339815191526000805160206123dd833981519152600160a060020a031663c51cf1798c6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a63095ea7b30282526004820193909352918d0160248301525160448281019350602092829003018187876161da5a03f115610002575050604051511590505b806103a757506000805160206123dd833981519152600160a060020a03166307d5b826866000805160206123dd833981519152600160a060020a031663c51cf1798c6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e160020a6303eadc130282526004820194909452928d016024840152516044838101936020935082900301816000876161da5a03f115610002575050604051511590505b15610fcd57610002565b60408051600480358082013560208181028086018201909652818552610d5d9593946024949093850192918291908501908490808284375094965050933593505050506040805160208181018352600080835283519182019093528281529091908190815b86518310156112c757600060010260006000506000898681518110156100025760209081029091018101518252810191909152604001600020541180156104af575085600160a060020a0316600014806104af575085600160a060020a03166000600050600089868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b156104eb576000600050600088858151811015610002576020908102909101810151825281019190915260400160002060070154909301600901925b60019290920191610416565b60408051600480358082013560208181028086018201909652818552610d5d959394602494909385019291829190850190849080828437509496505050505050506040805160208181018352600080835283519182019093528281529091908190815b8551831015611713576000600160005060008886815181101561000257602090810290910181015182528101919091526040016000205411156105cb576001600050600087858151811015610002576020908102909101810151825281019190915260400160002054909301600201925b6001929092019161055a565b610d016004356024355b60009182526020829052604090912060010154620f424091020490565b610da760043561200060405190810160405280610100905b6000815260200190600190039081610616575050604080516120008101909152610100815b600081526020019060019003908161063b5750600090505b60008481526020819052604090206007015460ff821610156118d8576040600020600701805460ff8316908110156100025760009182526020909120810154908390610100811015610002576020020152600101610653565b610d5d600435604080516020818101835260008083528351808301855281815285825291819052835193812060070154929391929091600191909101908059106106f35750595b90808252806020026020018201604052801561070a575b509150428260008151811015610002576020919091019190915290505b60008481526020819052604090206007015460ff821610156118d8576040600020600701805460ff83169081101561000257906000526020600020900160005054828260010160ff1681518110156100025760209081029091010152600101610727565b610d0160043560243560443560643560008481526020819052604080822054815160e160020a63460b97d102815260048101919091529051829182918291829182916000805160206123dd83398151915291638c172fa29160248181019261016092909190829003018187876161da5a03f1156100025750505060405180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200150505050509a50505050505050600060005060008b60001916815260200190815260200160002060005060050160009054906101000a9004600160a060020a0316600160a060020a0316630439978d8b600060005060008e60001916815260200190815260200160002060005060030160005054600060005060008f6000191681526020019081526020016000206000506007016000508d8d6040518660e060020a0281526004018086600019168152602001858152602001806020018460ff168152602001838152602001828103825285818154815260200191508054801561095657602002820191906000526020600020905b81600050548152602001906001019080831161093f575b505096505050505050506020604051808303816000876161da5a03f1156100025750506040515194505060008414156118e357610fc0565b610d01600435602435604435606435600060006000600060006000805160206123dd833981519152600160a060020a0316638c172fa28a6040518260e060020a0281526004018082600019168152602001915050610160604051808303816000876161da5a03f1156100025750506040805160a081015160c08201518d83526c01000000000000000000000000600160a060020a033381168202602086810191909152908d16909102603485015284516048948190039490940190932080875292869052928520600301549097509195509350821415905080610a7357506207a12088115b80610a7e5750836000145b15611cc857611cbc565b60048035600090815260208181526040918290206002810154815484516001840154600385015497850154600586015460069096015493835295820152808601929092526060820195909552600160a060020a039283166080820152911660a082015260c0810192909252519081900360e00190f35b610d0160043560243560443560643560008481526020819052604080822054815160e160020a63460b97d10281526004810191909152905182918291829182916000805160206123dd83398151915291638c172fa291602482810192610160929190829003018187876161da5a03f1156100025750505060405180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200180519060200150505050509950505050505050600060005060008a60001916815260200190815260200160002060005060050160009054906101000a9004600160a060020a0316600160a060020a031663f47cd6718a600060005060008d60001916815260200190815260200160002060005060030160005054600060005060008e6000191681526020019081526020016000206000506007016000508c8c6040518660e060020a0281526004018086600019168152602001858152602001806020018460ff1681526020018381526020018281038252858181548152602001915080548015610cc657602002820191906000526020600020905b816000505481526020019060010190808311610caf575b505096505050505050506020604051808303816000876161da5a03f11561000257505060405151935050600083141561201957611cbc565b60005b60408051918252519081900360200190f35b610d0160043560008181526020819052604081206004015481908190849033600160a060020a039081169116146122df57610002565b604080519115158252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190602002808383829060006004602084601f0104600302600f01f1509050019250505060405180910390f35b6040518082612000808381846000600461030ff15090500191505060405180910390f35b600091505b60008481526020819052604090206007015460ff83161015610eed576040600081812086825260208281528351915460e260020a6307c30783028352600483015260ff8616602483015292516000805160206123dd83398151915293631f0c1e0c9360448481019492939283900301908290876161da5a03f115610002575050604080515160008781526020819052919091206007018054600160a060020a0392909216925063a9059cbb9133919060ff871690811015610002579060005260206000209001600050546040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f1156100025750506040515115159050610f7357610002565b60406000908120602082815282825560018201839055600282018390556003820183905560048201805473ffffffffffffffffffffffffffffffffffffffff19908116909155600583018054909116905560068201839055600782018054848255908452908320919291610fa7918101905b80821115610fb45760008155600101610f5f565b6000848152602081905260408120600701805460ff8516908110156100025790825260208220015560019190910190610dd0565b5060019695505050505050565b5090565b818385010195505b5050505050949350505050565b6040805160e260020a6307c307830281526004810187905260ff8b16602482015290516000805160206123dd83398151915291631f0c1e0c91604482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63095ea7b302825230600160a060020a039081166004840152602483018d905292519216925063095ea7b391604482810192602092919082900301816000876161da5a03f115610002575050604051511515905061108e57610002565b604080517fdb833e3a000000000000000000000000000000000000000000000000000000008152600481018c905260ff8b166024820152604481018a905260648101899052905130600160a060020a03169163db833e3a91608482810192602092919082900301816000876161da5a03f11561000257505060405151925050600082141561111b57610002565b5060005b838160ff1610156111f75760ff808a169082161461125b576040805160e260020a6307c307830281526004810187905260ff8316602482015290516000805160206123dd83398151915291631f0c1e0c91604482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600160a060020a033381166004840152602483018d905292519216925063a9059cbb91604482810192602092919082900301816000876161da5a03f115610002575050604051511515905061125b57610002565b82600160a060020a031663a9059cbb33846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061126357610002565b60010161111f565b816000805160206123dd833981519152600160a060020a031663c51cf1798a6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f115610002575050604051518a01919091039650610fc09050565b836040518059106112d55750595b9080825280602002602001820160405280156112ec575b506000945084935091505b86518310156116c65760006001026000600050600089868151811015610002576020908102909101810151825281019190915260400160002054118015611390575085600160a060020a031660001480611390575085600160a060020a03166000600050600089868151811015610002576020908102909101810151825281019190915260400160002060040154600160a060020a0316145b1561170757868381518110156100025790602001906020020151600190048285815181101561000257602090810290910101528651600090819089908690811015610002576020908102909101810151825281019190915260400160002054825183906001870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600101548251839060028701908110156100025760209081029091010152865160009081908990869081101561000257602090810290910181015182528101919091526040016000206002015482518390600387019081101561000257602090810290910101528651600090819089908690811015610002576020908102909101810151825281019190915260400160002060030154825183906004870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600401548251600160a060020a03919091169083906005870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600501548251600160a060020a03919091169083906006870190811015610002576020908102909101015286516000908190899086908110156100025760209081029091018101518252810191909152604001600020600601548251839060078701908110156100025760209081029091010152865160009081908990869081101561000257602090810290910181015182528101919091526040016000206007015482518390600887019081101561000257602090810290910101525060005b60006000506000888581518110156100025760209081029091018101518252810191909152604001600020600701548110156116d0576000600050600088858151811015610002576020908102909101810151825281019190915260400160002060070180548290811015610002579060005260206000209001600050548282866009010181518110156100025760209081029091010152600101611626565b5095945050505050565b6000600050600088858151811015610002576020908102909101810151825281019190915260400160002060070154909301600901925b600192909201916112f7565b836040518059106117215750595b908082528060200260200182016040528015611738575b506000945084935091505b8551831015611892576000600160005060008886815181101561000257602090810290910181015182528101919091526040016000205411156118cc578583815181101561000257906020019060200201516001900482858151811015610002576020908102909101015285516001906000908890869081101561000257602090810290910181015182528101919091526040016000205482518390600187019081101561000257602090810290910101525060005b600160005060008785815181101561000257602090810290910181015182528101919091526040016000205481101561189b57600160005060008785815181101561000257602090810290910181015182528101919091526040016000208054829081101561000257600091825260209091200154825183908684016002019081101561000257602090810290910101526001016117f9565b50949350505050565b6001600050600087858151811015610002575050602085810289018101518252919091526040902054909301600201925b60019290920191611743565b8192505b5050919050565b6118ed8a856105e1565b92506000805160206123dd833981519152600160a060020a031663c51cf179896040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f1156100025750506040515192505083830182018790111561195857610fc0565b84600160a060020a03166323b872dd333085878901016040518460e060020a0281526004018084600160a060020a0316815260200183600160a060020a0316815260200182815260200193505050506020604051808303816000876161da5a03f1156100025750506040515115905080611a3557506040805160e060020a63095ea7b30281526000805160206123dd833981519152600482015285840160248201529051600160a060020a0387169163095ea7b391604482810192602092919082900301816000876161da5a03f115610002575050604051511590505b80611aa9575060008a81526020818152604080832054815160e160020a6303eadc130281526004810191909152878601602482015290516000805160206123dd833981519152936307d5b826936044848101949193929183900301908290876161da5a03f115610002575050604051511590505b15611ab357610002565b5060005b60008a81526020819052604090206007015460ff82161015611b06576040600020600701805485919060ff84169081101561000257600091825260209091200180549091019055600101611ab7565b604060009081208b8252602091909152600701805460ff8b169081101561000257600091825260209091200154881115611b3f57610002565b60008a815260208190526040902060028101805485019055600701805489919060ff8c1690811015610002579060005260206000209001600050805491909103905560008a81526020818152604080832054815160e260020a6307c30783028152600481019190915260ff8d16602482015290516000805160206123dd83398151915293631f0c1e0c936044848101949193929183900301908290876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600160a060020a033381166004840152602483018d905292519216925063a9059cbb91604482810192602092919082900301816000876161da5a03f1156100025750506040515115159050610fb857610002565b505050600092835250602080832090910184905583825281905260409020600181018990556003810188905589815560048101805473ffffffffffffffffffffffffffffffffffffffff199081163317909155600582018054909116881790554360069091015590935083905b50505050949350505050565b82600160a060020a03166323b872dd33306000805160206123dd833981519152600160a060020a031663c51cf1798c6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a6323b872dd028252600160a060020a039586166004830152939094166024850152918c0160448401525051606482810192602092919082900301816000876161da5a03f1156100025750506040515115905080611e45575082600160a060020a031663095ea7b36000805160206123dd8339815191526000805160206123dd833981519152600160a060020a031663c51cf1798b6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e060020a63095ea7b30282526004820193909352918c016024830152516044828101935060209282900301816000876161da5a03f115610002575050604051511590505b80611f0457506000805160206123dd833981519152600160a060020a03166307d5b8268a6000805160206123dd833981519152600160a060020a031663c51cf1798b6040518260e060020a028152600401808281526020019150506020604051808303816000876161da5a03f11561000257505060408051805160e160020a6303eadc130282526004820194909452928c016024840152516044838101936020935082900301816000876161da5a03f115610002575050604051511590505b15611f0e57610002565b83604051805910611f1c5750595b908082528060200260200182016040528015611f33575b506000838152602081815260408220600701805484518083558285529383902091949082019392018215611f86579160200282015b82811115611f86578251826000505591602001919060010190611f68565b50611f92929150610f5f565b5050600090505b838160ff161015611fda576000828152602081905260409020600701805488919060ff84169081101561000257600091825260209091200155600101611f99565b600089815260016020819052604090912080549182018082559091908281838015829011611c4f57600083815260209020611c4f918101908301610f5f565b61202389846105e1565b915085828403101561203457611cbc565b60008981526020818152604080832054815160e260020a6307c30783028152600481019190915260ff8c16602482015290516000805160206123dd83398151915293631f0c1e0c936044848101949193929183900301908290876161da5a03f11561000257505060408051805160e060020a6323b872dd028252600160a060020a0333811660048401523081166024840152604483018c90529251921692506323b872dd91606482810192602092919082900301816000876161da5a03f115610002575050604051511590508061218d57506000805160206123dd833981519152600160a060020a0316634025b293600060005060008c60001916815260200190815260200160002060005060000160005054856040518360e060020a0281526004018083600019168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511590505b1561219757610002565b6000898152602081905260409020600701805488919060ff8b16908110156100025760009182526020822001805490920190915590505b60008981526020819052604090206007015460ff82161015612254576040600020600701805484919060ff84169081101561000257600091825260209091200154106122d0576000898152602081905260409020600701805484919060ff84169081101561000257906000526020600020900160005080549190910390556001016121ce565b600089815260208181526040808320600201805486019055805160e060020a63a9059cbb028152600160a060020a033381166004830152868803602483015291519188169363a9059cbb93604483810194919391929183900301908290876161da5a03f11561000257505060405151151590506122d557610002565b610002565b8183039450611cbc565b60008581526020819052604080822054815160e160020a63460b97d1028152600481019190915290516000805160206123dd83398151915292638c172fa292602481810193610160939092839003909101908290876161da5a03f1156100025750506040805160c001516000888152602081905291822060020180549083905590955093508311905080156123ca575082600160a060020a031663a9059cbb33846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511590505b156123d457610002565b819350506118dc560000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd", - "storage": { - "0x50ff25f5e9a51687bca1c50f3544d5eef8202f228d3de791691a137aecb6b360": "0x00000000000000000000000000000000000000000000000026566ea1ec2f6a9b", - "0x50ff25f5e9a51687bca1c50f3544d5eef8202f228d3de791691a137aecb6b361": "0x00000000000000000000000000000000000000000000000072aa5b7e04d56a9b", - "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86c": "0xd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", - "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed86f": "0x0000000000000000000000000000000000000000000000004563918244f40000", - "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed871": "0x0000000000000000000000008695e5e79dab06fbbb05f445316fa4edb0da30f0", - "0x642f3c12d3cd25d9b946d8c2ec97f080f4efcff18301a6dcade5a6be0c5ed873": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - }, - "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0": { - "balance": "0x0", - "code": "0x606060405260e060020a60003504630439978d811461003157806308f028d514610115578063f47cd6711461026e575b005b60408051604435600481810135602081810285810182019096528185526103509583359560248035966064959294910192829185019084908082843750949650509335935050608435915050600060006040604051908101604052806002905b60008152602001906001900390816100915790505060006000600061271073ef3487d24a0702703e04a26cef479e313c8fc7ae6324d4e90a604060020a8c51026040518260e060020a028152600401808281526020019150506020604051808303818660325a03f41561000257505060405151919091049550610398905089610157565b60408051600480358082013560208181028086018201909652818552610362959394602494909385019291829190850190849080828437509496505050505050505b6040604051908101604052806002905b6000815260200190600190039081610167575050604080518082019091526002815b600081526020019060019003908161018957905050600083600081518110156100025760209081029091010151825283518490600090811015610002576020908102909101810151908301525060005b83518160ff1610156104a7578351825190859060ff8416908110156100025790602001906020020151101561022357838160ff168151811015610002576020908102909101015182525b60208201518451859060ff8416908110156100025790602001906020020151111561026657838160ff168151811015610002576020908102909101810151908301525b6001016101d9565b60408051604435600481810135602081810285810182019096528185526103509583359560248035966064959294910192829185019084908082843750949650509335935050608435915050600060006040604051908101604052806002905b60008152602001906001900390816102ce579050506000600061271073ef3487d24a0702703e04a26cef479e313c8fc7ae6324d4e90a604060020a8b51026040518260e060020a028152600401808281526020019150506020604051808303818660325a03f415610002575050604051519190910494506104ae905088610157565b60408051918252519081900360200190f35b60408051908190839080838184600060046015f15090500191505060405180910390f35b8095505b505050505095945050505050565b935061044d85858b8d5b6000806127108304815b85518160ff16101561051d5773ef3487d24a0702703e04a26cef479e313c8fc7ae63872fb2b589848a6000909060200201518a8660ff1681518110156100025760209081029091010151038b600060200201518c600190906020020151030304026040518260e060020a028152600401808281526020019150506020604051808303818660325a03f4156100025750506040515190930192506001016103ac565b925086898960ff16815181101561000257602090810290910101805191909103905261047b85858b8d6103a2565b915050604060020a620186a0620186a28484036127108d0402020404868111156103865786955061038a565b5092915050565b6020810180518801905292506104c684848a8c6103a2565b915085888860ff16815181101561000257602090810290910101805190910190526104f384848a8c6103a2565b9050604060020a620186a06127108b04838503026201869e02040494505050505095945050505050565b87604060020a73ef3487d24a0702703e04a26cef479e313c8fc7ae6324d4e90a866040518260e060020a028152600401808281526020019150506020604051808303818660325a03f4156100025750506040515190910291909104999850505050505050505056" - }, - "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2": { - "balance": "0xa6e361612cc228000", - "code": "0x6060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100ed57806318160ddd1461016257806323b872dd1461016b578063313ce567146102565780636c11bcd31461026257806370a08231146102d057806395d89b41146102f5578063a9059cbb14610353578063d0febe4c146103f8578063dd62ed3e14610439575b005b6040805160038054602060026001831615610100026000190190921691909104601f810182900482028401820190945283835261046d939083018282801561052e5780601f106105035761010080835404028352916020019161052e565b61042560043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b6104db60025481565b610425600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101be575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101ca5750600082115b1561053657600160a060020a0383811660008181526020818152604080832080548801905588851680845281842080548990039055600183528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a350600161053a565b6104ed60055460ff1681565b61042560043533600160a060020a0316600090815260208190526040812054821161054157604081208054839003905560028054839003905580821180156102c6575060405133600160a060020a0316908290849082818181858883f19350505050155b1561054957610002565b6104db600435600160a060020a0381166000908152602081905260409020545b919050565b61046d6004805460408051602060026000196101006001871615020190941693909304601f8101849004840282018401909252818152929183018282801561052e5780601f106105035761010080835404028352916020019161052e565b61042560043560243533600160a060020a03166000908152602081905260408120548290108015906103855750600082115b156105515733600160a060020a0390811660008181526020818152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161015c565b33600160a060020a0316600090815260208190526040902080543490810190915560028054909101905560015b604080519115158252519081900360200190f35b6104db600435602435600160a060020a0382811660009081526001602090815260408083209385168352929052205461015c565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156104cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60408051918252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b81548152906001019060200180831161051157829003601f168201915b505050505081565b5060005b9392505050565b5060006102f0565b5060016102f0565b50600061015c56", - "storage": { - "0x3830062b39ca7888048a385f112e36aef7258a27d84eb6e31312c298e5954da3": "0x0000000000000000000000000000000000000000000000035fe3763f1973ab3b", - "0x527b1dd758d53f706730e0fb37a8de5c38d8b4cd17fbe1cfa285480a00f55bf4": "0x000000000000000000000000000000000000000000000003ab97b2fc29ad66c6", - "0x52cb6de4baff82acfb6977b64d52b9ac011f8af34631d933997b7649a84d716f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8f0cfa08792bcd3de052a3bb7bd54f8a62c44b02ba16ff336e9a881c348cca21": "0x000000000000000000000000000000000000000000046ba103abb9d1301f1b2e", - "0xa29249eda6f9f8d0c67b7a4f954f6ba7a9f1bb3f216b2fedc6db8def03c47746": "0x00000000000000000000000000000000000000000000000007a93ebd870d6684", - "0xbe1e23f4b08159a01ee61379749e9b484f5947aaeeb008ce7c97d1c56d3eeb8b": "0x0000000000000000000000000000000000000000000000000dfecc50c6f7d5cd" - } - }, - "0xef3487d24a0702703e04a26cef479e313c8fc7ae": { - "balance": "0x0", - "code": "0x6503060000000050606060405260e060020a600035046324d4e90a8114610031578063872fb2b514610078575b610007565b61013c6004356000680171547652b82fe177818080808061014e886000604060020a82048160bf605f5b6001830182146103c4578060020a8410156103ce579050806103d2565b61013c600435604060020a67b17217f7d1cf79ac81830281900482810460020a680100000016aee6e8ef67b172182739bc0e46858406908102869004673d7f78a624cfb9b582800288900490810288900491909101670e359bcfeb6e45319183028890049182028890040167027601df2fc048dc91830288900491820288900401665808a728816ee89183028890049182028890040166095dedef350bc991830288900491820297909704969096019190910182810295905b505050505050919050565b60408051918252519081900360200190f35b94508460020a88049350604060020a9250604060020a600a029150819050604060020a83680443b9c5adb08cc45f0204810390508050604060020a8484020492508250604060020a83680f0a52590f17c71a3f0204810190508050604060020a8484020492508250604060020a83682478f22e787502b0230204810390508050604060020a8484020492508250604060020a836848c6de1480526b8d4c0204810190508050604060020a8484020492508250604060020a836870c18cae824656408c0204810390508050604060020a8484020492508250604060020a8368883c81ec0ce7abebb20204810190508050604060020a8484020492508250604060020a836881814da94fe52ca9f50204810390508050604060020a8484020492508250604060020a8368616361924625d1acf50204810190508050604060020a8484020492508250604060020a836839f9a16fb9292a608d0204810390508050604060020a8484020492508250604060020a83681b3049a5740b21d65f0204810190508050604060020a8484020492508250604060020a836809ee1408bd5ad96f3e0204810390508050604060020a8484020492508250604060020a836802c465c91703b7a7f40204810190508050604060020a8484020492508250604060020a8367918d2d5f045a4d630204810390508050604060020a8484020492508250604060020a836714ca095145f44f780204810190508050604060020a8484020492508250604060020a836701d806fc412c1b990204810390508050604060020a8484020492508250604060020a836613950b4e1e89cc020481019050805085604060020a8383604060020a8902010302049650610131565b5090949350505050565b9150815b5060028282010461005b56" - }, - "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28": { - "balance": "0x0", - "code": "0x6060604052361561008d5760e060020a600035046306fdde03811461008f578063095ea7b3146100a557806318160ddd1461012457806323b872dd1461012f578063313ce567146101dc578063475a9fa9146101f057806370a0823114610215578063721a37d21461024357806395d89b411461008f578063a9059cbb14610268578063dd62ed3e146102e7575b005b61031d6040805160208101909152600081525b90565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db63c6605267600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b6102316003546100a2565b61038b60043560243560443560008054604080517fa00bfa1100000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a038781166024830152868116604483015260648201869052929092166084830152517319ee743d2e356d5f0e4d97cc09b96d06e933d0db9163a00bfa119160a482810192602092919082900301818660325a03f4156100025750506040515195945050505050565b604080516000815290519081900360200190f35b61038b6004356024356000805433600160a060020a0390811691161461039f57610002565b600160a060020a03600435166000908152600160205260409020545b60408051918252519081900360200190f35b61038b6004356024356000805433600160a060020a039081169116146103ce57610002565b61038b60043560243560007319ee743d2e356d5f0e4d97cc09b96d06e933d0db6388d5fecb600160005085856040518460e060020a0281526004018084815260200183600160a060020a0316815260200182815260200193505050506020604051808303818660325a03f4156100025750506040515191506103179050565b610231600435602435600160a060020a038281166000908152600260209081526040808320938516835292905220545b92915050565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f16801561037d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b604080519115158252519081900360200190f35b50600160a060020a03821660009081526001602081905260409091208054830190556003805483019055610317565b600160a060020a038316600090815260016020526040902054821161040a57506040600020805482900390556003805482900390556001610317565b50600061031756", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000012098a4651fb262f7", - "0xfae22198212900725daa5db635d1fda7b0fa195adaabdc806a7267959c3d8ae4": "0x000000000000000000000000000000000000000000000000731fb89f735062f7", - "0xfd73dc2251dc113619c6fcc1c142e797f06e77a178cc37fe300a56823b741ef7": "0x0000000000000000000000000000000000000000000000008ac7230489e80000" - } - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "2340153", - "difficulty": "80383973372327", - "timestamp": "1475034716", - "gasLimit": "1500062", - "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9" - }, - "input": "0xf8ea508504a817c80083084398946ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba580b884bbd4f854e9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000080d29fa5cccfadac1ba0690ce7a4cf8590c636a1799ebf2cc52229714c47da72ee406fb9bd7d29e52440a017b6ce39e8876965afa2a1c579a592eb1af146506ccdbfc2c9ea422b13dca438", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0x3de712784baf97260455ae25fb74f574ec9c1add", - "gas": "0x84398", - "gasUsed": "0x27ec3", - "to": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "input": "0xbbd4f854e9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000080d29fa5cccfadac", - "output": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "calls": [ - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x77e82", - "gasUsed": "0x54c", - "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "input": "0x8c172fa2d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac", - "output": "0x446374989d279847d0dbc6708a9c76a419fe9831d42c78bc89473f559a00d91500000000000000000000000061d76c05cd2aa9ed5135e21e52fff188b02089d4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000092f1dbea03ce08225e31e95cc926ddbe0198e6f2000000000000000000000000529c4cb814029b8bb32acb516ea3a4b07fdae350846fd373887ade3ab7703750294876afa61cf56303f5f014a4d80d04f508a1f100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x7737b", - "gasUsed": "0x3fe1", - "to": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "input": "0x0439978de9efd3ab89acad6a3edf9828c3b00ed1c4a74e974d05d32d3b2fb15aa16fc3770000000000000000000000000000000000000000000000004563918244f4000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000026566ea1ec2f6a9b00000000000000000000000000000000000000000000000072aa5b7e04d56a9b", - "output": "0x0000000000000000000000000000000000000000000000008060b57e2e0c99aa", - "calls": [ - { - "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "gas": "0x770ef", - "gasUsed": "0xc24", - "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", - "input": "0x24d4e90a0000000000000000000000000000000000000000000000020000000000000000", - "output": "0x000000000000000000000000000000000000000000000000b17217f7d1cf79ab", - "type": "DELEGATECALL", - "value": "0x0" - }, - { - "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "gas": "0x75eb2", - "gasUsed": "0x265", - "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", - "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", - "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", - "type": "DELEGATECALL", - "value": "0x0" - }, - { - "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "gas": "0x75aad", - "gasUsed": "0x25b", - "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", - "input": "0x872fb2b50000000000000000000000000000000000000000000000000000000000000000", - "output": "0x00000000000000000000000000000000000000000000000100000016aee6e8ef", - "type": "DELEGATECALL", - "value": "0x0" - }, - { - "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "gas": "0x75737", - "gasUsed": "0xc24", - "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", - "input": "0x24d4e90a00000000000000000000000000000000000000000000000324bf7e0976f5f167", - "output": "0x0000000000000000000000000000000000000000000000012535c5e5f87ee0d2", - "type": "DELEGATECALL", - "value": "0x0" - }, - { - "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "gas": "0x748c7", - "gasUsed": "0x265", - "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", - "input": "0x872fb2b5000000000000000000000000000000000000000000000000c330b3f7006420b8", - "output": "0x00000000000000000000000000000000000000000000000224bf7df2c80f0878", - "type": "DELEGATECALL", - "value": "0x0" - }, - { - "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "gas": "0x744c2", - "gasUsed": "0x265", - "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", - "input": "0x872fb2b500000000000000000000000000000000000000000000000237d37fe5d297a500", - "output": "0x0000000000000000000000000000000000000000000000093088c407fcbbce38", - "type": "DELEGATECALL", - "value": "0x0" - }, - { - "from": "0x8695e5e79dab06fbbb05f445316fa4edb0da30f0", - "gas": "0x74142", - "gasUsed": "0xc99", - "to": "0xef3487d24a0702703e04a26cef479e313c8fc7ae", - "input": "0x24d4e90a00000000000000000000000000000000000000000000000b554841fac4cad6b0", - "output": "0x0000000000000000000000000000000000000000000000026d7fc130d6a74cbe", - "type": "DELEGATECALL", - "value": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x731be", - "gasUsed": "0x241", - "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "input": "0xc51cf179000000000000000000000000000000000000000000000000de0b6b3a76400000", - "output": "0x0000000000000000000000000000000000000000000000000071ea279ec31402", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x72df4", - "gasUsed": "0x468b", - "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "input": "0x23b872dd0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba500000000000000000000000000000000000000000000000080d29fa5cccfadac", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add", - "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5" - ], - "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x6e627", - "gasUsed": "0x56d6", - "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "input": "0x095ea7b30000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "topics": [ - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd" - ], - "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x68dae", - "gasUsed": "0xd6f0", - "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "input": "0x07d5b826d9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "gas": "0x629ff", - "gasUsed": "0x468b", - "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "input": "0x23b872dd0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd" - ], - "data": "0x00000000000000000000000000000000000000000000000080d29fa5cccfadac", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "gas": "0x5e0df", - "gasUsed": "0x31af", - "to": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "input": "0xa9059cbb000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a060000000000000000000000000000000000000000000000000041f50e27d56848", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x92f1dbea03ce08225e31e95cc926ddbe0198e6f2", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000005aae5c59d642e5fd45b427df6ed478b49d55fefd", - "0x000000000000000000000000950ca4a06c78934a148b7a3ff3ea8fc366f77a06" - ], - "data": "0x0000000000000000000000000000000000000000000000000041f50e27d56848", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "gas": "0x5ac6b", - "gasUsed": "0x29ae", - "to": "0x01e60b511fced1eb2b5b40991eb1dfd171a6df42", - "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "gas": "0x57fed", - "gasUsed": "0x29ae", - "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "input": "0x475a9fa90000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba50000000000000000000000000000000000000000000000008090aa97a4fa4564", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x56030", - "gasUsed": "0x265", - "to": "0x5aae5c59d642e5fd45b427df6ed478b49d55fefd", - "input": "0x1f0c1e0cd9a4ffe21d19763887176173d08241e8393c1dfd208f29193dfecdf854b664ac0000000000000000000000000000000000000000000000000000000000000001", - "output": "0x000000000000000000000000f4cbd7e037b80c2e67b80512d482685f15b1fb28", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "gas": "0x55cc3", - "gasUsed": "0x339f", - "to": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "input": "0xa9059cbb0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "gas": "0x55a8a", - "gasUsed": "0x30f7", - "to": "0x19ee743d2e356d5f0e4d97cc09b96d06e933d0db", - "input": "0x88d5fecb00000000000000000000000000000000000000000000000000000000000000010000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add000000000000000000000000000000000000000000000000de0b6b3a76400000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0xf4cbd7e037b80c2e67b80512d482685f15b1fb28", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000006ca7f214ab2ddbb9a8e1a1e2c8550e3164e9dba5", - "0x0000000000000000000000003de712784baf97260455ae25fb74f574ec9c1add" - ], - "data": "0x000000000000000000000000000000000000000000000000de0b6b3a76400000", - "position": "0x0" - } - ], - "type": "DELEGATECALL", - "value": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json deleted file mode 100644 index 263e88d6e1..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multi_contracts.json +++ /dev/null @@ -1,2327 +0,0 @@ -{ - "genesis": { - "difficulty": "59917798787272", - "extraData": "0xe4b883e5bda9e7a59ee4bb99e9b1bc", - "gasLimit": "4712380", - "hash": "0xae82afe3630b001a34ad4c51695dacb17872ebee4dadd2de88b1a16671871da4", - "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9", - "mixHash": "0x23c2289cdee8a397cf36db9ffa3419503bed54eb09e988b3c7a3587a090e6fc1", - "nonce": "0x94dc83e0044f49c8", - "number": "1881283", - "stateRoot": "0x6e3832bc2e4e66170a1e716449083e08fbb70e7b2a9f1f34e0c57e66ce40c50f", - "timestamp": "1468467284", - "totalDifficulty": "37186898441932102239", - "alloc": { - "0x0000000000000000000000000000000000000004": { - "balance": "0x0" - }, - "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e": { - "balance": "0x0", - "code": "0x606060405236156100f05760e060020a600035046303afc23581146100f257806313af4035146101145780631838e26614610136578063186ef9621461014d57806327df8c501461016f578063295d5866146101915780634162169f146101b35780634dfc3db6146101c55780636637b882146101e8578063839d3f7f1461020a57806386c9b5361461021d5780638da5cb5b1461022f5780639093a5e714610241578063b199efb514610263578063b262b9ae14610275578063b9f34aa114610297578063be9a6555146102a9578063d1c3c84a146102c7578063e26fc92b146102d9578063e8d9f074146102eb575b005b6100f0600435600054600160a060020a03908116339091161461034057610002565b6100f0600435600054600160a060020a03908116339091161461035557610002565b6102fd60006000600060006000600061036a6101c9565b6100f0600435600054600160a060020a0390811633909116146108a157610002565b6100f0600435600054600160a060020a0390811633909116146108b657610002565b6100f0600435600054600160a060020a0390811633909116146108cb57610002565b61030f600154600160a060020a031681565b6102fd5b60008054600160a060020a0390811633909116146108e0575060015b90565b6100f0600435600054600160a060020a03908116339091161461098857610002565b61032c60075460a060020a900460ff1681565b61030f600454600160a060020a031681565b61030f600054600160a060020a031681565b6100f0600435600054600160a060020a03908116339091161461099d57610002565b61030f600254600160a060020a031681565b6100f0600435600054600160a060020a0390811633909116146109b257610002565b61030f600754600160a060020a031681565b6100f060005433600160a060020a03908116911614610a1a57610002565b61030f600354600160a060020a031681565b61030f600554600160a060020a031681565b61030f600654600160a060020a031681565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b604080519115158252519081900360200190f35b60048054600160a060020a0319168217905550565b60008054600160a060020a0319168217905550565b945060008514610380578495505b505050505090565b6002546040805160015460e060020a634162169f0282529151600160a060020a039283169390921691634162169f9160048181019260209290919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506103ef5760649550610378565b600260009054906101000a9004600160a060020a0316600160a060020a0316634dfc3db66040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519450506000841461045857836064019550610378565b6040805160015460035460e060020a634162169f0283529251600160a060020a039182169390911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506104c65760c89550610378565b600360009054906101000a9004600160a060020a0316600160a060020a0316634dfc3db66040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519350506000831461052f578260c8019550610378565b604080516001546004805460e060020a634162169f0284529351600160a060020a039283169490921692634162169f928183019260209282900301816000876161da5a03f11561000257505060405151600160a060020a0316909114905061059b5761012c9550610378565b60408051600480547f4dfc3db60000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692634dfc3db692808301926020929182900301816000876161da5a03f1156100025750506040515192505060008214610613578161012c019550610378565b6040805160015460055460e060020a634162169f0283529251600160a060020a039182169390911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a03169091149050610682576101909550610378565b600560009054906101000a9004600160a060020a0316600160a060020a0316634dfc3db66040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151915050600081146106ec5780610190019550610378565b6040805160015460065460e060020a634162169f0283529251600160a060020a039182169390911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a0316909114905061075b576101f49550610378565b6040805160065460e060020a638da5cb5b028252915130600160a060020a03908116931691638da5cb5b91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506107c6576101f59550610378565b6040805160075460015460e060020a634162169f0283529251600160a060020a03938416939190911691634162169f91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a03169091149050610836576102589550610378565b6040805160075460e060020a638da5cb5b028252915130600160a060020a03908116931691638da5cb5b91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a03169091149050610378576102599550610378565b60038054600160a060020a0319168217905550565b60058054600160a060020a0319168217905550565b60068054600160a060020a0319168217905550565b600154600160a060020a0316600014156108fc575060026101e5565b600654600160a060020a031660001415610918575060036101e5565b600754600160a060020a031660001415610934575060046101e5565b600254600160a060020a031660001415610950575060056101e5565b600354600160a060020a03166000141561096c575060066101e5565b600454600160a060020a0316600014156101e5575060076101e5565b60018054600160a060020a0319168217905550565b60078054600160a060020a0319168217905550565b60028054600160a060020a0319168217905550565b600260009054906101000a9004600160a060020a0316600160a060020a031663975057e76040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050505b565b610a8a600154604080517f4b6753bc0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a031691634b6753bc916004828101926020929190829003018187876161da5a03f11561000257505060405151421191506101e59050565b1515610a9557610a18565b60075460a060020a900460ff1615610e93576111556040805160015460065460e060020a6370a08231028352600160a060020a039081166004840152925160009384939216916370a08231916024808301926020929190829003018187876161da5a03f1156100025750506040515191909111159050610c61576040805160065460025460015460e060020a6370a08231028452600160a060020a0392831660048501819052945163a9059cbb949284169391909116916370a0823191602482810192602092919082900301818a876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019490945260248101939093525160448084019360209350829003018187876161da5a03f1156100025750506040805160025460e060020a63a8618f71028252600160a060020a031660048201819052915191925063a8618f71916024828101926020929190829003018187876161da5a03f11561000257505060405151159050610c6157600260009054906101000a9004600160a060020a0316600160a060020a031663975057e76040518160e060020a0281526004018090506000604051808303816000876161da5a03f11561000257506001925050505b6001546007546040805160e060020a6370a08231028152600160a060020a0392831660048201529051600093909216916370a0823191602481810192602092909190829003018187876161da5a03f1156100025750506040515191909111159050610e1b576040805160075460025460015460e060020a6370a08231028452600160a060020a0392831660048501819052945163a9059cbb949284169391909116916370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb02825260048201949094526024810193909352516044838101936020935082900301816000876161da5a03f1156100025750506040805160025460e060020a63a8618f71028252600160a060020a031660048201819052915191925063a8618f7191602482810192602092919082900301816000876161da5a03f11561000257505060405151159050610e1b57600260009054906101000a9004600160a060020a0316600160a060020a031663975057e76040518160e060020a0281526004018090506000604051808303816000876161da5a03f11561000257506001925050505b8015610e7257600260009054906101000a9004600160a060020a0316600160a060020a0316632e64cec16040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050505b6007805474ff00000000000000000000000000000000000000001916905550565b600260009054906101000a9004600160a060020a0316600160a060020a0316632e64cec16040518160e060020a0281526004018090506000604051808303816000876161da5a03f115610002575050505b60048054604080517ffc3407160000000000000000000000000000000000000000000000000000000081529051600160a060020a03929092169263fc340716928282019260009290829003018183876161da5a03f115610002575050600354604080517fd95f98ce0000000000000000000000000000000000000000000000000000000081529051600160a060020a0392909216925063d95f98ce916004828101926000929190829003018183876161da5a03f11561000257505050620f42405a11156109c7576109c76001546005546040805160e060020a6370a08231028152600160a060020a039283166004820152905192909116916370a082319160248181019260209290919082900301816000876161da5a03f1156100025750506040515160001415905061108357604080516002546005547fd0679d34000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015260016024840152925192169163d0679d349160448181019260209290919082900301816000876161da5a03f115610002575050505b5b600554604080517f400e39490000000000000000000000000000000000000000000000000000000081529051600a92600160a060020a03169163400e394991600482810192602092919082900301816000876161da5a03f1156100025750506040515191909110905080156110fb5750620aae605a115b15610a1857600560009054906101000a9004600160a060020a0316600160a060020a031663ff2f4bd26040518160e060020a0281526004018090506000604051808303816000876161da5a03f11561000257505050611084565b610ee456", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000001f835a0247b0063c04ef22006ebe57c5f11977cc4" - } - }, - "0x304a554a310c7e546dfe434669c62820b7d83490": { - "balance": "0x3034f5ca7d45e17df1d83", - "nonce": "3", - "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000b656b2a9c3b2416437a811e07466ca712f5a5b5a", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057870858", - "0x0000000000000000000000000000000000000000000000000000000000000011": "0x0000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c18941301", - "0x0000000000000000000000000000000000000000000000000000000000000016": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", - "0x0421a2c4dbea98e8df669bb77238b62677daa210c5fbc46600627f90c03d0f08": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e571": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e572": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e573": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e574": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e575": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e576": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e577": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e578": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e579": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e57e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e57f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e580": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e581": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e582": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e583": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e584": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e585": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e586": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e587": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e58f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e590": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e591": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e592": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e593": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e594": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e595": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e59f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a1": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a3": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5a9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5aa": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ab": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ac": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ad": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ae": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5af": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b1": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b6": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5b9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ba": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bb": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bc": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5be": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5bf": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c5": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c6": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5c9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ca": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5cb": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5cc": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5cd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d3": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d5": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d6": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5d9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5da": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5db": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e1": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e3": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e5": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e6": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5e9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ee": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5ef": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f1": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f3": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f5": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f6": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5f7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5fc": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x330b9432081afd3b64172d5df1f72ca72fc17e7e729ceb8b7529f91eee8b3f23": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x33f9bdb745e7edb1789dd1d68f40f693940aa8313b4f6bdc543be443dbc85e63": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4830270ad35536baba417a92ea24656430586a37c90999b53c4d72ef1090cc9d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4b16ba88f291613070529c10c8bdc41e973e2e2aa412ed92254cdca71ccfbc89": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", - "0x6546a4760869a51d07a75a31f00531836c32152c06dc88ac342da52fac5d939e": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", - "0x6796d25b854f17a11b940a9ff2822335f7d9bd1b85fbcd9d1f5cf742099d477a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x711886c99bc7a6e316551823dca012bd5b4381b57cec388f72c4b8105c1ed4ad": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x74024021ec74dc59b0fa1b66e9f430163a5e1128785ec9495f9686628ca7cc2b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x79a0e9ff42282e7cbcb539e164f024ab90021633de05f600fff6d16305888d26": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x81ffe0a69ee20c37e3f3ba834da8b20475846fcde1f4a39fdfc628a2560076aa": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8f85b96a91f601f62149f5dd6a35d6168f6de5bc047a18e3cf7b97a3843c6ffd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x946f68a04a200ebe87f2f896f7f6c08f4e22813db910c8a6d6abf17611ce3ffb": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x9c1ad2f16775f94ffd360e8bc716f86016a3fcf90992b5b4f3312353efd1bd61": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xa66ae63934365a757bf33d70ca0a28352da4c2fe6cb147bf29d69fbea3a706e0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xa7653edcf1403f7ce2f75784d5f34ca5f57ff110bd0c3abbdcc5a84f101dc83a": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", - "0xa87317e3ffd5ed16f357bd31427bd97cbb35fc51ad1e00feec89bdfe82c5dba4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xaa535eb427f7963e49601f9032ee6b62a9f72b6b3c610a5f11faf8dc68a97e2a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xaade287f2b81ac58dcc6ee0c381cde85b6aa7a9a769be73605f1af9453a340a0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xb56a086d82c3921c13c13d1d53f18bbbe36d9d1c4862be8339a5171feb94c164": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xb6ab9f1541f42dc4feba15ccd18bc3af7c8f99cafb184ab65539883a68c7a1a9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xbad9e5f7dc3001078ea6433993a2f145c2ef9af1c5137a35e9c173c208990249": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xc319152db8781ef1f12090aad94325d650e39c8a20285c7e02959817118f3f28": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xde65b6d76ea4a5547af9707e6e099bba6f16dbc7b5cf97fb8fedc82583b38de0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xdf71c8506c3cf85e2e677b60ec28fe60eb820775001bdce289e3253f304f22e8": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x4fd27b205895e698fa350f7ea57cec8a21927fcd": { - "balance": "0x0", - "nonce": "11", - "code": "0x606060405236156100f05760e060020a600035046303afc23581146100f257806313af403514610114578063186ef962146101365780632e64cec11461015857806331962cdc146101d2578063365a86fc146101f45780634162169f146102065780634dfc3db61461021857806365f13792146102585780636637b88214610441578063715d832f146104625780637452c2e61461048457806386c9b536146105005780638da5cb5b14610512578063975057e714610524578063a8618f711461059f578063d0679d341461061b578063d1c3c84a14610698578063d9d35966146106aa578063f3273907146106c9575b005b6100f0600435600054600160a060020a03908116339091161461072e57610002565b6100f0600435600054600160a060020a03908116339091161461074457610002565b6100f0600435600054600160a060020a03908116339091161461075957610002565b6100f06000805481908190600160a060020a0390811633909116148015906101905750600154600160a060020a039081163390911614155b80156101ac5750600254600160a060020a039081163390911614155b80156101c85750600354600160a060020a039081163390911614155b1561076e57610002565b6100f0600435600054600160a060020a039081163390911614610a5d57610002565b6106eb600154600160a060020a031681565b6106eb600454600160a060020a031681565b61070860008054600160a060020a03908116339091161480159061024c5750600154600160a060020a039081163390911614155b15610a72575060015b90565b6107086004355b600060006000600060006000600460009054906101000a9004600160a060020a0316600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150945084600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604080518051600480547f81f03fcb000000000000000000000000000000000000000000000000000000008452600160a060020a038d81169285019290925293519198509290921692506381f03fcb916024828101926020929190829003018187876161da5a03f115610002575050604080518051600480547f18160ddd0000000000000000000000000000000000000000000000000000000084529351919750600160a060020a039390931693506318160ddd92828101926020929190829003018187876161da5a03f1156100025750506040805180516004805460e060020a6370a08231028452600160a060020a038d81169285019290925293519196509290921692506370a08231916024828101926020929190829003018187876161da5a03f11561000257505060405151909402919091049695505050505050565b6100f060043560005433600160a060020a03908116911614610ad957610002565b6100f06004356000805433600160a060020a03908116911614610aff57610002565b61071a600435600080548190819033600160a060020a039081169116148015906104be5750600154600160a060020a039081163390911614155b80156104da5750600254600160a060020a039081163390911614155b80156104f65750600354600160a060020a039081163390911614155b15610be657610002565b6106eb600354600160a060020a031681565b6106eb600054600160a060020a031681565b6100f06000805481908190819033600160a060020a0390811691161480159061055d5750600154600160a060020a039081163390911614155b80156105795750600254600160a060020a039081163390911614155b80156105955750600354600160a060020a039081163390911614155b15610c4457610002565b61071a6004355b60006000600460009054906101000a9004600160a060020a0316600160a060020a03166381f03fcb846040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519150610da490508361025f565b61071a60043560243560008054819033600160a060020a039081169116148015906106565750600154600160a060020a039081163390911614155b80156106725750600254600160a060020a039081163390911614155b801561068e5750600354600160a060020a039081163390911614155b15610dac57610002565b6106eb600254600160a060020a031681565b6100f06000805433600160a060020a03908116911614610ec457610002565b6106eb6004356000805433600160a060020a03908116911614610fd357610002565b60408051600160a060020a03929092168252519081900360200190f35b60408051918252519081900360200190f35b604080519115158252519081900360200190f35b60038054600160a060020a031916821790555b50565b60008054600160a060020a0319168217905550565b60028054600160a060020a0319168217905550565b30925061077a836105a6565b1561082557600480546006546040805160e060020a6370a08231028152600160a060020a038881169582019590955290519284169363a9059cbb9392169184916370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb02825260048201949094526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b600091505b6005548210156108f45760058054600454600160a060020a0316916370a0823191859081101561000257600091825260408051600080516020611089833981519152929092015460e060020a6370a08231028352600160a060020a0316600483015251602482810193602093839003909101908290876161da5a03f115610002575050604051519150506000811115610a51576108f96005600050838154811015610002576000919091526000805160206110898339815191520154600160a060020a03166105a6565b505050565b15156109c25760058054600454600160a060020a0316916323b872dd918590811015610002575060009081526040805160008051602061108983398151915287015460e060020a6323b872dd028252600160a060020a03908116600483015230166024820152604481018690529051606482810193602093839003909101908290876161da5a03f1156100025750506040805183815290517f92da44f6982cd1ca7a9c851f8c39b26c80c235d7bb9fd59bce334fa634a1728b92509081900360200190a1610a51565b60058054600454600160a060020a0316916323b872dd918590811015610002575060009081526006546040805160008051602061108983398151915288015460e060020a6323b872dd028252600160a060020a0390811660048301529290921660248301526044820186905251606482810193602093839003909101908290876161da5a03f115610002575050505b6001919091019061082a565b60018054600160a060020a0319168217905550565b600454600160a060020a031660001415610a8e57506002610255565b600354600160a060020a031660001415610aaa57506003610255565b600254600160a060020a031660001415610ac657506004610255565b6005546000141561025557506005610255565b6005546000901115610aea57610002565b60048054600160a060020a0319168217905550565b5060005b81811015610b5a57600580546001818101808455930192909190828015829011610b5e576000839052610b5e906000805160206110898339815191529081019083015b80821115610bd65760008155600101610b46565b5050565b5050604051600454600160a060020a0316925090506082806110078339018082600160a060020a03168152602001915050604051809103906000f06005805460001981019081101561000257600091909152600080516020611089833981519152018054600160a060020a0319169091179055610b03565b5090565b600092505b5050919050565b600091505b600554821015610bda57600580548390811015610002576000919091526000805160206110898339815191520154600160a060020a0390811691508416811415610c385760019250610bdf565b60019190910190610beb565b600460009054906101000a9004600160a060020a0316600160a060020a03166370a08231306040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519450506000841415610cbb575b50505050565b600554600093506004900460010191505b81831015610cb557506005805460045442850182900692600160a060020a03919091169163a9059cbb9190849081101561000257600091825260408051600080516020611089833981519152929092015460e060020a63a9059cbb028352600160a060020a03166004830152868904602483015251604482810193602093839003909101908290876161da5a03f11561000257505060408051848704815290517fc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b92509081900360200190a160019290920191610ccc565b901192915050565b600460009054906101000a9004600160a060020a0316600160a060020a03166370a08231306040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f1156100025750506040515191505082811015610e5f57604080516020810185905281517f703690365b2d63b5b9ec4471a919cdd5924f745170399a5d24927fd07d81a04d929181900390910190a1600091505b5092915050565b604080516004805460e060020a63a9059cbb028352600160a060020a038881169284019290925260248301879052925192169163a9059cbb9160448082019260209290919082900301816000876161da5a03f115610002575060019350610e58915050565b600480546006546040805160e060020a6370a08231028152600160a060020a0392831694810194909452519116916370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060405151915050600081111561074157604080516004805460065460e060020a6323b872dd028452600160a060020a039081169284019290925230821660248401526044830185905292519216916323b872dd9160648181019260209290919082900301816000876161da5a03f1156100025750505060405180519060200150507f32e95f921f72e9e736ccad1cc1c0ef6e3c3c08204eb74e9ee4ae8f98e195e3f0816040518082815260200191505060405180910390a150565b600580548390811015610002576000919091526000805160206110898339815191520154600160a060020a03169291505056006060604052604051602080608283396080604081905291517f095ea7b3000000000000000000000000000000000000000000000000000000008352600160a060020a0333811660845260001960a4819052919384939184169163095ea7b39160c491906044816000876161da5a03f115600257505033600160a060020a03169050ff036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db6": "0x0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf30", - "0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db7": "0x0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a2", - "0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db8": "0x000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b" - } - }, - "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f": { - "balance": "0x0", - "code": "0x606060405236156100da5760e060020a600035046303afc23581146100dc57806309f180f9146100fe5780630a39ce021461016c57806310aa1caa146101a057806313af40351461021e57806331962cdc14610240578063365a86fc146102625780634162169f146102745780634dfc3db6146102865780636637b882146102c65780636de45dee146102e85780638da5cb5b146103285780639137c1a71461033a578063b199efb51461035c578063b3a69f861461036e578063d5d7ff3c1461040b578063d95f98ce1461044b578063fe39084c146104b5575b005b6100da600435600054600160a060020a0390811633909116146104f657610002565b6104c76004355b6002546040805160e060020a6381f03fcb028152600160a060020a0384811660048301529151600093849384939116916381f03fcb91602481810192602092909190829003018187876161da5a03f1156100025750506040515192506105199050846101a7565b6104d960043560068054829081101561000257506000526000805160206110cf8339815191520154600160a060020a031681565b6104c76004355b604080516003547f65f13792000000000000000000000000000000000000000000000000000000008252600160a060020a038481166004840152925160009391909116916365f13792916024828101926020929190829003018187876161da5a03f115610002575050604051516001019392505050565b6100da600435600054600160a060020a03908116339091161461052c57610002565b6100da600435600054600160a060020a03908116339091161461054157610002565b6104d9600154600160a060020a031681565b6104d9600254600160a060020a031681565b6104c760008054600160a060020a0390811633909116148015906102ba5750600154600160a060020a039081163390911614155b15610556575060015b90565b6100da600435600054600160a060020a03908116339091161461063c57610002565b6100da600435600054600160a060020a03908116339091161480159061031e5750600154600160a060020a039081163390911614155b1561065157610002565b6104d9600054600160a060020a031681565b6100da600435600054600160a060020a03908116339091161461081b57610002565b6104d9600354600160a060020a031681565b6104c75b6000805b6006548110156108175760068054600254600160a060020a0316916370a08231918490811015610002576000918252604080516000805160206110cf833981519152929092015460e060020a6370a08231028352600160a060020a0316600483015251602482810193602093839003909101908290876161da5a03f11561000257505060405151929092019150600101610376565b6100da6004356000805433600160a060020a039081169116148015906104415750600154600160a060020a039081163390911614155b1561083057610002565b6100da60006000600060006000600060006000600060006000600060009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a0316141580156104ab5750600154600160a060020a039081163390911614155b1561092d57610002565b6104d9600454600160a060020a031681565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60048054600160a060020a031916821790555b50565b81810392505b5050919050565b90508082111561050c5760009250610512565b60008054600160a060020a0319168217905550565b60018054600160a060020a0319168217905550565b600254600160a060020a031660001415610572575060026102c3565b600354600160a060020a03166000141561058e575060036102c3565b600354604080517fd1c3c84a000000000000000000000000000000000000000000000000000000008152905130600160a060020a0390811693169163d1c3c84a91600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a0316909114905061060d575060046102c3565b60065460001415610620575060056102c3565b600454600160a060020a0316600014156102c3575060066102c3565b60028054600160a060020a0319168217905550565b6106ab816000805b6006548110156110bc5782600160a060020a03166006600050828154811015610002576000919091526000805160206110cf8339815191520154600160a060020a031614156110c757600191506110c1565b156106b557610509565b600354604080517f7452c2e6000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291519290911691637452c2e69160248181019260209290919082900301816000876161da5a03f1156100025750506040515115905061072d57610509565b30600160a060020a031681600160a060020a0316148061075b5750600354600160a060020a03908116908216145b806107745750600154600160a060020a03908116908216145b1561077e57610509565b60068054600181018083559091908280158290116107bf578183600052602060002091820191016107bf91905b8082111561081757600081556001016107ab565b505060068054849350909150600019810190811015610002575080546000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3e018054600160a060020a031916909117905550565b5090565b60038054600160a060020a0319168217905550565b5060005b6006548110156109215781600160a060020a03166006600050828154811015610002576000919091526000805160206110cf8339815191520154600160a060020a0316141561092557600680546000198101908110156100025760009182526000805160206110cf83398151915201909054906101000a9004600160a060020a03166006600050828154811015610002576000805160206110cf833981519152018054600160a060020a0319169092179091558054600019810180835590919082801582901161091c5761091c906000805160206110cf8339815191529081019083016107ab565b505050505b5050565b600101610834565b6002546040805160e060020a6381f03fcb02815230600160a060020a0381811660048401529251909e5092909116916381f03fcb9160248181019260209290919082900301816000876161da5a03f115610002575050604051519a505060008a14156109c1576040517f044c61dab36644651a1f82d87d6494a3a6450a6edde20b9baf45e374fb2d0bb990600090a1610e04565b6109c9610372565b6040805160025460e060020a6370a08231028252600160a060020a038f811660048401529251939c50909116916370a082319160248181019260209290919082900301816000876161da5a03f115610002575050604051519850606497505086881015610ade57604080516003547fd0679d34000000000000000000000000000000000000000000000000000000008252600160a060020a038e811660048401528b8b036024840152925192169163d0679d349160448082019260209290919082900301816000876161da5a03f1156100025750506040515115159050610ad8576040517f044c61dab36644651a1f82d87d6494a3a6450a6edde20b9baf45e374fb2d0bb990600090a1610e04565b86975087505b600095505b600654861015610b2457610d8e6006600050878154811015610002576000919091526000805160206110cf8339815191520154600160a060020a0316610105565b6040805160025460e060020a6381f03fcb028252600160a060020a038e8116600484015292519216916381f03fcb9160248181019260209290919082900301816000876161da5a03f11561000257505050604051805190602001509250600260009054906101000a9004600160a060020a0316600160a060020a03166370a082318c6040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f11561000257505060405151600097509250505b600654861015610e045760068054600254600160a060020a0316916370a082319189908110156100025760009182526000805160206110cf83398151915201546040805160e060020a6370a08231028152600160a060020a0392909216600483015251602482810193602093839003909101908290876161da5a03f115610002575050604051518084028b900495509150506000841115610d82577ff340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b86666006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252602082018790528386048c900482820152519081900360600190a160025460068054600160a060020a03929092169163a9059cbb919089908110156100025760009182526000805160206110cf83398151915201546040805160e060020a63a9059cbb028152600160a060020a039290921660048301526024820189905251604482810193602093839003909101908290876161da5a03f115610002575050505b60019590950194610bed565b9450898589020493508760001415610e11577fdb0f19c627ca59a2db73b1e1e8c4853f34a58afa92b29331e56c75144fa0c84c6006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252519081900360200190a15b5050505050505050505050565b87841115610e84577f211d59fc569e166e12f7ca82135d85b1f178f636fefe40d168f0113cf07f818f6006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252519081900360200190a1879350610ee8565b7f4b0bc4f25f8d0b92d2e12b686ba96cd75e4e69325e6cf7b1f3119d14eaf2cbdf6006600050878154811015610002576000919091526000805160206110cf833981519152015460408051600160a060020a03929092168252519081900360200190a15b60008411156110b05760068054998501997ff340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b86669190889081101561000257600091909152604080516000805160206110cf8339815191529290920154600160a060020a0316825260208201879052818101889052519081900360600190a160025460068054600160a060020a03929092169163a9059cbb91908990811015610002576000918252604080516000805160206110cf833981519152929092015460e060020a63a9059cbb028352600160a060020a031660048301526024820189905251604482810193602093839003909101908290876161da5a03f1156100025750506040805160025460e060020a6370a08231028252600160a060020a038f811660048401529251921692506370a0823191602482810192602092919082900301816000876161da5a03f115610002575050506040518051906020015097508750600260009054906101000a9004600160a060020a0316600160a060020a03166381f03fcb8c6040518260e060020a0281526004018082600160a060020a031681526020019150506020604051808303816000876161da5a03f115610002575050604051519a50505b60019590950194610ae3565b600091505b50919050565b60010161065956f652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xf652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" - } - }, - "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc": { - "balance": "0x4563918244f400000", - "code": "0x606060405236156100da5760e060020a600035046313af40358114610145578063186ef9621461016757806331962cdc14610189578063365a86fc146101ab5780634162169f146101bd57806348c981e2146101cf5780634dfc3db61461020f57806361bc221a146102505780636637b882146102595780636c0e29601461027b5780638da5cb5b146104795780638f2b29a71461048b5780639137c1a714610602578063b199efb514610624578063b826c4fd14610636578063d1c3c84a1461063f578063d2f0ad9214610651578063fc340716146106bf575b6107236002546040805160e060020a630e7082030281529051600092600160a060020a031691630e708203916004828101926020929190829003018187876161da5a03f1156100025750506040515133600160a060020a039081169116149050610737575060015b90565b610861600435600054600160a060020a03908116339091161461089257610002565b610861600435600054600160a060020a0390811633909116146108a757610002565b610861600435600054600160a060020a0390811633909116146108bc57610002565b610863600154600160a060020a031681565b610863600254600160a060020a031681565b610861600435600054600160a060020a0390811633909116148015906102055750600154600160a060020a039081163390911614155b156108d157610002565b61088060008054600160a060020a0390811633909116148015906102435750600154600160a060020a039081163390911614155b156108fa57506001610142565b61088060055481565b610861600435600054600160a060020a0390811633909116146109e857610002565b6108805b6000600060006000600060006000600060006000600260009054906101000a9004600160a060020a0316600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150985088600160a060020a03163130600160a060020a03163101975088600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160025460035460e060020a6381f03fcb028452600160a060020a0390811660048501529351919b5090921692506381f03fcb916024828101926020929190829003018187876161da5a03f11561000257505060408051805160025460e060020a6318160ddd0283529251909950600160a060020a039290921692506318160ddd916004828101926020929190829003018187876161da5a03f11561000257505060408051805160025460035460e060020a6370a08231028452600160a060020a039081166004850152935191995090921692506370a08231916024828101926020929190829003018187876161da5a03f115610002575050506040518051906020015093508784860202925088600160a060020a03163188880103840291508585029050808210156109fd57610a05565b610863600054600160a060020a031681565b61088060043560006000600060006000600260009054906101000a9004600160a060020a0316600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750505060405180519060200150935083600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051600254815160035460e060020a6381f03fcb028452600160a060020a0390811660048501529351909750921692506381f03fcb916024808301926020929190829003018187876161da5a03f11561000257505060408051805160025460e060020a6318160ddd0283529251909550600160a060020a039290921692506318160ddd916004828101926020929190829003018187876161da5a03f115610002575050506040518051906020015090508581038183020486820387850204039450845084945050505050919050565b610861600435600054600160a060020a039081163390911614610a1157610002565b610863600354600160a060020a031681565b61088060065481565b610863600454600160a060020a031681565b6108806004355b6040805160025460035460e060020a6370a08231028352600160a060020a039081166004840152925160009384939216916370a08231916024828101926020929190829003018187876161da5a03f115610002575050604051519093046001019392505050565b61086160006000600060006000600060006000600060009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a0316141580156107195750600154600160a060020a039081163390911614155b15610cbc57610002565b604080519115158252519081900360200190f35b600654600554600019909101901115610803576040805160025460035460e060020a6370a0823102835230600160a060020a03908116600485015293519184169363a9059cbb9391169160019185916370a082319160248082019260209290919082900301816000876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019590955260001994909401602485015251604480850194602094509192509082900301816000876161da5a03f115610002575060019250610142915050565b6005805460010190556040805160025460e160020a63664d71fb0282529151600160a060020a03929092169163cc9ae3f69160048181019260209290919082900301816000876161da5a03f115610002575060019250610142915050565b005b60408051600160a060020a03929092168252519081900360200190f35b60408051918252519081900360200190f35b60008054600160a060020a0319168217905550565b60048054600160a060020a0319168217905550565b60018054600160a060020a0319168217905550565b604051600160a060020a0382811691309091163190600081818185876185025a03f15050505050565b600254600160a060020a03166000141561091657506002610142565b600354600160a060020a03166000141561093257506003610142565b600454600160a060020a03166000141561094e57506004610142565b600354604080517f86c9b536000000000000000000000000000000000000000000000000000000008152905130600160a060020a039081169316916386c9b53691600482810192602092919082900301816000876161da5a03f11561000257505060405151600160a060020a031690911490506109cd57506005610142565b30600160a060020a0316316000141561014257506006610142565b60028054600160a060020a0319168217905550565b808203830499505b50505050505050505090565b60038054600160a060020a0319168217905550565b6006819055600354604080517fd0679d34000000000000000000000000000000000000000000000000000000008152600160a060020a038981166004830152938b04602482018190529151919750919092169163d0679d349160448181019260209290919082900301816000876161da5a03f11561000257505060408051600160055530600160a060020a031631815290517f7027eecbd2a688fc1fa281702b311ed7168571514adfd17014a55d828cb4338292509081900360200190a1604051600160a060020a0389811691309091163190600081818185876185025a03f15050604080517fd2cc718f000000000000000000000000000000000000000000000000000000008152905163d2cc718f9250600482810192602092919082900301816000876161da5a03f11561000257505060408051805160025460e060020a6370a08231028352600160a060020a038a81166004850152935191975090921692506370a0823191602482810192602092919082900301816000876161da5a03f11561000257505060408051805160025460e060020a6381f03fcb028352600160a060020a038a81166004850152935191965090921692506381f03fcb91602482810192602092919082900301816000876161da5a03f11561000257505060408051805160025460e160020a63664d71fb0283529251909450600160a060020a0392909216925063cc9ae3f691600482810192602092919082900301816000876161da5a03f115610002575050604080516002546004805460e060020a63a9059cbb028452600160a060020a03908116918401919091526001602484015292519216925063a9059cbb91604482810192602092919082900301816000876161da5a03f115610002575050505b5050505050505050565b6002546040805160e060020a630e7082030281529051600160a060020a0390921691630e7082039160048181019260209290919082900301816000876161da5a03f115610002575050604051519850610d15905061027f565b60408051600160a060020a038b1631815290519198507f07cf7e805770612a8b2ee8e0bcbba8aa908df5f85fbc4f9e2ef384cf75315038919081900360200190a187600160a060020a03163130600160a060020a0316310195508660001480610d7e5750856000145b15610db1576040517f30090d86c52e12fbc1213c1ecf7e193d6ce4a5c838c8c41d06c1a9daea8a2cec90600090a1610cb2565b309450610a268761065856", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b": { - "balance": "0x0", - "code": "0x606060405236156100985760e060020a6000350463013cf08b811461009a57806313af4035146100d757806331962cdc146100f9578063365a86fc1461011b578063400e39491461012d5780634162169f146101375780634dfc3db6146101495780636637b8821461018a5780638da5cb5b146101ac578063e66f53b7146101be578063e90956cf146101d0578063ff2f4bd2146101f2575b005b61024460043560048054829081101561000257506000527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b015481565b610098600435600054600160a060020a03908116339091161461026157610002565b610098600435600054600160a060020a03908116339091161461027657610002565b61024e600154600160a060020a031681565b6102446004545b90565b61024e600254600160a060020a031681565b61024460008054600160a060020a03908116339091161480159061017d5750600154600160a060020a039081163390911614155b1561028b57506001610134565b610098600435600054600160a060020a0390811633909116146102c157610002565b61024e600054600160a060020a031681565b61024e600354600160a060020a031681565b610098600435600054600160a060020a0390811633909116146102d657610002565b6100986000606081815260a06040526080828152825491929091819033600160a060020a0390811691161480159061023a5750600154600160a060020a039081163390911614155b1561031857610002565b6060908152602090f35b600160a060020a03166060908152602090f35b60008054600160a060020a0319168217905550565b60018054600160a060020a0319168217905550565b600254600160a060020a03168114156102a657506002610134565b600354600160a060020a031681141561013457506003610134565b60028054600160a060020a0319168217905550565b60038054600160a060020a0319168217905550565b50508054839250600019810190811015610002579060005260206000209001600050819055505b50505050565b6002547f70a082310000000000000000000000000000000000000000000000000000000060a090815230600160a060020a0390811660a45291909116906370a082319060c49060209060248187876161da5a03f11561000257505060405151821415905061038557610312565b60006040518059106103945750595b9080825280602002602001820160405250935062093a809150600260009054906101000a9004600160a060020a0316600160a060020a031663612e45a3600360009054906101000a9004600160a060020a0316600086888760016040518760e060020a0281526004018087600160a060020a03168152602001868152602001806020018060200185815260200184151581526020018381038352878181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156104815780820380516001836020036101000a031916815260200191505b508381038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156104da5780820380516001836020036101000a031916815260200191505b50985050505050505050506020604051808303816000876161da5a03f1156100025750506040515160048054600181018083559294509250908280158290116102eb578183600052602060002091820191016102eb91905b808211156105465760008155600101610532565b509056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a1": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a3": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd1a4": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0xad3ecf23c0c8983b07163708be6d763b5f056193": { - "balance": "0x0", - "code": "0x606060405236156100405760e060020a60003504630221038a811461004d57806318bdc79a146100aa5780638da5cb5b146100be578063d2cc718f146100d0575b6100d96001805434019055565b6100db6004356024356000805433600160a060020a0390811691161415806100755750600034115b806100a05750805460a060020a900460ff1680156100a057508054600160a060020a03848116911614155b156100f757610002565b6100db60005460ff60a060020a9091041681565b6100ed600054600160a060020a031681565b6100db60015481565b005b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a0383168260608381818185876185025a03f1925050501561015c57604080518381529051600160a060020a038516917f9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc919081900360200190a25060015b9291505056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b": { - "balance": "0x167d285b38143c04f", - "nonce": "68" - }, - "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89": { - "balance": "0x9651c71936", - "code": "0x606060405236156100b95760e060020a600035046313af4035811461019e57806326f5a8c9146101c1578063371fa854146101ca5780634162169f146101d35780634c8fe526146101e55780635970c915146101f757806361bc221a14610209578063625e847d146102125780636637b882146102325780637f9f519f146102555780638da5cb5b14610278578063a9059cbb1461028a578063c4463c80146102b0578063c9d27afe146102df578063e66f53b714610305575b6103176002547f0e708203000000000000000000000000000000000000000000000000000000006060908152600091600160a060020a031690630e7082039060649060209060048187876161da5a03f1156100025750506040515133600160a060020a039081169116149050610329576040805133600160a060020a03166020820152818152600f818301527f636f6e73747563746f72206661696c0000000000000000000000000000000000606082015290517fa6af7265d7ede5fbf0ee375956b52b362800d4f92e268809bef5fdf2a57924b89181900360800190a15060015b90565b61031760043560008054600160a060020a03908116339091161461049257610002565b61047560055481565b61047560045481565b61047f600254600160a060020a031681565b61047f600654600160a060020a031681565b61047f600754600160a060020a031681565b61047560035481565b61031760008054600160a060020a0390811633909116146104ef57610002565b61031760043560008054600160a060020a03908116339091161461057a57610002565b61031760043560008054600160a060020a0390811633909116146105d757610002565b61047f600054600160a060020a031681565b61031760043560243560008054600160a060020a03908116339091161461060f57610002565b61031760043560243560443560643560843560008054600160a060020a0390811633909116146106a657610002565b61031760043560243560008054600160a060020a0390811633909116146107bb57610002565b61047f600154600160a060020a031681565b60408051918252519081900360200190f35b60055460035460001990910190111561040257604080516002546006547f70a0823100000000000000000000000000000000000000000000000000000000835230600160a060020a03908116600485015293519184169363a9059cbb9391169184916370a0823191602480830192602092919082900301818a876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019490945260248101939093525160448084019360209350829003018187876161da5a03f11561000257505060016003819055915061019b9050565b6040805160038054600190810190915560025460048054925460e260020a632099877102855290840192909252600160a060020a03918216602484015292519216916382661dc491604480820192602092909190829003018187876161da5a03f11561000257506001925061019b915050565b6060908152602090f35b600160a060020a03166060908152602090f35b600160a060020a03821660609081527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc90602090a181600060006101000a815481600160a060020a0302191690830217905550600190505b919050565b6001600355600754600160a060020a03908116908290301631606082818181858883f15050604080516002546001546004805460e260020a632099877102855290840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257506001925061019b915050565b6002805473ffffffffffffffffffffffffffffffffffffffff1916831790819055600160a060020a031660609081527fce6a5015a40a2ec38ce912a63bca374d85386207c6927d284292449f1431082290602090a15060016104ea565b600582905560608281527fbab6859bc098da798dbdc4860f0fee7467d703dadd975799e8c258b46a37d3de90602090a15060016104ea565b60025460e060020a63a9059cbb026060908152600160a060020a0385811660645260848590529091169063a9059cbb9060a49060209060448187876161da5a03f11561000257505060408051600160a060020a03861681526020810185905281517f69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de293509081900390910190a15060015b92915050565b6006805473ffffffffffffffffffffffffffffffffffffffff1990811686179091556001600381905580548216871790556004879055600584905560078054909116831790819055600160a060020a03908116908290301631606082818181858883f15050604080516002546004805460015460e260020a632099877102855291840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257505060408051600454600654908252600160a060020a0316602082015281517fa1ab731770d71027cd294cc0af5c8f5ec3c2ff5dbe6b75d68963d17192f8377b93509081900390910190a150600195945050505050565b6002547fc9d27afe0000000000000000000000000000000000000000000000000000000060609081526064859052831515608452600160a060020a039091169063c9d27afe9060a49060209060448187876161da5a03f11561000257505060408051858152841515602082015281517f8bfa1f40665434b48e7becc865cc0586ce3d6d2388521c05d4db87536ac8279993509081900390910190a15060016106a056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490" - } - }, - "0xea674fdde714fd979de3edf0f56aa9716b898ec8": { - "balance": "0x4ab3566739e7b24371", - "nonce": "286339" - }, - "0xf835a0247b0063c04ef22006ebe57c5f11977cc4": { - "balance": "0x9645db5736", - "code": "0x606060405236156100b95760e060020a600035046313af4035811461019e57806326f5a8c9146101c1578063371fa854146101ca5780634162169f146101d35780634c8fe526146101e55780635970c915146101f757806361bc221a14610209578063625e847d146102125780636637b882146102325780637f9f519f146102555780638da5cb5b14610278578063a9059cbb1461028a578063c4463c80146102b0578063c9d27afe146102df578063e66f53b714610305575b6103176002547f0e708203000000000000000000000000000000000000000000000000000000006060908152600091600160a060020a031690630e7082039060649060209060048187876161da5a03f1156100025750506040515133600160a060020a039081169116149050610329576040805133600160a060020a03166020820152818152600f818301527f636f6e73747563746f72206661696c0000000000000000000000000000000000606082015290517fa6af7265d7ede5fbf0ee375956b52b362800d4f92e268809bef5fdf2a57924b89181900360800190a15060015b90565b61031760043560008054600160a060020a03908116339091161461049257610002565b61047560055481565b61047560045481565b61047f600254600160a060020a031681565b61047f600654600160a060020a031681565b61047f600754600160a060020a031681565b61047560035481565b61031760008054600160a060020a0390811633909116146104ef57610002565b61031760043560008054600160a060020a03908116339091161461057a57610002565b61031760043560008054600160a060020a0390811633909116146105d757610002565b61047f600054600160a060020a031681565b61031760043560243560008054600160a060020a03908116339091161461060f57610002565b61031760043560243560443560643560843560008054600160a060020a0390811633909116146106a657610002565b61031760043560243560008054600160a060020a0390811633909116146107bb57610002565b61047f600154600160a060020a031681565b60408051918252519081900360200190f35b60055460035460001990910190111561040257604080516002546006547f70a0823100000000000000000000000000000000000000000000000000000000835230600160a060020a03908116600485015293519184169363a9059cbb9391169184916370a0823191602480830192602092919082900301818a876161da5a03f11561000257505060408051805160e060020a63a9059cbb028252600482019490945260248101939093525160448084019360209350829003018187876161da5a03f11561000257505060016003819055915061019b9050565b6040805160038054600190810190915560025460048054925460e260020a632099877102855290840192909252600160a060020a03918216602484015292519216916382661dc491604480820192602092909190829003018187876161da5a03f11561000257506001925061019b915050565b6060908152602090f35b600160a060020a03166060908152602090f35b600160a060020a03821660609081527f3edd90e7770f06fafde38004653b33870066c33bfc923ff6102acd601f85dfbc90602090a181600060006101000a815481600160a060020a0302191690830217905550600190505b919050565b6001600355600754600160a060020a03908116908290301631606082818181858883f15050604080516002546001546004805460e260020a632099877102855290840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257506001925061019b915050565b6002805473ffffffffffffffffffffffffffffffffffffffff1916831790819055600160a060020a031660609081527fce6a5015a40a2ec38ce912a63bca374d85386207c6927d284292449f1431082290602090a15060016104ea565b600582905560608281527fbab6859bc098da798dbdc4860f0fee7467d703dadd975799e8c258b46a37d3de90602090a15060016104ea565b60025460e060020a63a9059cbb026060908152600160a060020a0385811660645260848590529091169063a9059cbb9060a49060209060448187876161da5a03f11561000257505060408051600160a060020a03861681526020810185905281517f69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de293509081900390910190a15060015b92915050565b6006805473ffffffffffffffffffffffffffffffffffffffff1990811686179091556001600381905580548216871790556004879055600584905560078054909116831790819055600160a060020a03908116908290301631606082818181858883f15050604080516002546004805460015460e260020a632099877102855291840152600160a060020a0390811660248401529251921694506382661dc493506044808201935060209291829003018187876161da5a03f11561000257505060408051600454600654908252600160a060020a0316602082015281517fa1ab731770d71027cd294cc0af5c8f5ec3c2ff5dbe6b75d68963d17192f8377b93509081900390910190a150600195945050505050565b6002547fc9d27afe0000000000000000000000000000000000000000000000000000000060609081526064859052831515608452600160a060020a039091169063c9d27afe9060a49060209060448187876161da5a03f11561000257505060408051858152841515602082015281517f8bfa1f40665434b48e7becc865cc0586ce3d6d2388521c05d4db87536ac8279993509081900390910190a15060016106a056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000003e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000304a554a310c7e546dfe434669c62820b7d83490" - } - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "1881284", - "difficulty": "59917798852808", - "timestamp": "1468467296", - "gasLimit": "4712388", - "miner": "0xea674fdde714fd979de3edf0f56aa9716b898ec8" - }, - "input": "0xf869448505d21dba00833567e09403e3d4561a8f8e975fdcd798d32857a20cf25e7e8084be9a65551ba0d4dd5fff30e83fbe630bb0fd67eeefe9e3aad0c3ee870a2b6e80fc40191bc7d4a074f93b546bfad60f3cae8e4aafef835237095d6618334154a24df4b4d49d9359", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0xbe3ae5cb97c253dda67181c6e34e43f5c275e08b", - "gas": "0x3567e0", - "gasUsed": "0x26e1ef", - "to": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "input": "0xbe9a6555", - "calls": [ - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x34affa", - "gasUsed": "0x1ef", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x4b6753bc", - "output": "0x0000000000000000000000000000000000000000000000000000000057870858", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x34abef", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x34a705", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a08231000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x34a31a", - "gasUsed": "0xa2f3", - "to": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "gas": "0x343e8c", - "gasUsed": "0x9a62", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000c0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" - ], - "data": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0xc0ee9db1a9e07ca63e4ff0d5fb6f86bf68d47b89", - "topics": [ - "0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2" - ], - "data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa93", - "position": "0x1" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x33ff04", - "gasUsed": "0x168e", - "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "input": "0xa8618f710000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x339a3b", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x3395a4", - "gasUsed": "0x15f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x339363", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x339129", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x338cfa", - "gasUsed": "0x13f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x338a75", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa93", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x33e6f2", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x33e208", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a08231000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", - "output": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x33de20", - "gasUsed": "0x685b", - "to": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", - "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", - "gas": "0x337992", - "gasUsed": "0x5fca", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000f835a0247b0063c04ef22006ebe57c5f11977cc4", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" - ], - "data": "0x00000000000000000000000000000000000000000001819451f999d617dafa76", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0xf835a0247b0063c04ef22006ebe57c5f11977cc4", - "topics": [ - "0x69ca02dd4edd7bf0a4abb9ed3b7af3f14778db5d61921c7dc7cd545266326de2" - ], - "data": "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd00000000000000000000000000000000000000000001819451f999d617dafa76", - "position": "0x1" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x3374a2", - "gasUsed": "0x168e", - "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "input": "0xa8618f710000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x330fd9", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x330b42", - "gasUsed": "0x15f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x330901", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x3306c7", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x330298", - "gasUsed": "0x13f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x330013", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x33490b", - "gasUsed": "0x3f781", - "to": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "input": "0xfc340716", - "calls": [ - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x32e30d", - "gasUsed": "0x15f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x32e037", - "gasUsed": "0x15f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x32dd7b", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x32daf9", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x32d6ab", - "gasUsed": "0x13f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x32d400", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x32c975", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x3276d3", - "gasUsed": "0xa49d", - "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "input": "0xd0679d340000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x320fe1", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f509", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x320b5b", - "gasUsed": "0x9a62", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" - ], - "data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x3164e1", - "gasUsed": "0x4e91", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0x", - "value": "0x4563918244f400000", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x3115cc", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x311382", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x310f37", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x310ae9", - "gasUsed": "0x1446e", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xcc9ae3f6", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x30a397", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x309fc1", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x309c45", - "gasUsed": "0x122af", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0x0221038a0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000000022b1c8c12279fffff", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "gas": "0x301e6f", - "gasUsed": "0x10068", - "to": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "input": "0x", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x2fbb97", - "gasUsed": "0x15f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x2fa477", - "gasUsed": "0xe7b6", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xcc9ae3f6", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x2f3d25", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x2f394f", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x2f35d3", - "gasUsed": "0x8b5f", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0x0221038a0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc0000000000000000000000000000000000000000000000022b1c8c12279fffff", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "gas": "0x2eb7fd", - "gasUsed": "0x6918", - "to": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "input": "0x", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x2e5525", - "gasUsed": "0x15f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x2e5168", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "output": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccd", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x2e4d69", - "gasUsed": "0x5fca", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd" - ], - "data": "0x0000000000000000000000000000000000000000000181a7ae53ea2f0bef8ccc", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x22b1c8c12279fffff", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "topics": [ - "0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc", - "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" - ], - "data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff", - "position": "0x1" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x22b1c8c12279fffff", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "topics": [ - "0x9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc", - "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc" - ], - "data": "0x0000000000000000000000000000000000000000000000022b1c8c12279fffff", - "position": "0x1" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "gas": "0x2fc505", - "gasUsed": "0xd4fa", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000001", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000006e715ab4f598eacf0016b9b35ef33e4141844ccc", - "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "topics": [ - "0x07cf7e805770612a8b2ee8e0bcbba8aa908df5f85fbc4f9e2ef384cf75315038" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000000", - "position": "0x6" - }, - { - "address": "0x6e715ab4f598eacf0016b9b35ef33e4141844ccc", - "topics": [ - "0x7027eecbd2a688fc1fa281702b311ed7168571514adfd17014a55d828cb43382" - ], - "data": "0x000000000000000000000000000000000000000000000004563918244f400000", - "position": "0x8" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x2f5092", - "gasUsed": "0x14e37", - "to": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "input": "0xd95f98ce", - "calls": [ - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2eea7c", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2ee4cb", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2edfff", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2edb9a", - "gasUsed": "0x6994", - "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "input": "0xd0679d340000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000063", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2e7519", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f508", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2e7093", - "gasUsed": "0x5fca", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f0000000000000000000000000000000000000000000000000000000000000063", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000063", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2e6f59", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2e6afa", - "gasUsed": "0x1113", - "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "input": "0x65f13792000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x0000000000000000000000000000000000000000000000000037bc5737aa7ba8", - "calls": [ - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2e06f9", - "gasUsed": "0x15f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x0e708203", - "output": "0x000000000000000000000000ad3ecf23c0c8983b07163708be6d763b5f056193", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2e04b8", - "gasUsed": "0x113", - "to": "0xad3ecf23c0c8983b07163708be6d763b5f056193", - "input": "0xd2cc718f", - "output": "0x000000000000000000000000000000000000000000000004563918244f400000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2e027b", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2dfe4c", - "gasUsed": "0x13f", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x18160ddd", - "output": "0x00000000000000000000000000000000000000000003034f5ca7d45e17df199b", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2dfbc7", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2e5281", - "gasUsed": "0x329", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x81f03fcb0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x000000000000000000000000000000000000000000000004563918244f3ffffe", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2e4dcc", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "output": "0x0000000000000000000000000000000000000000000000000000000000000064", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2e4857", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a08231000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "output": "0x000000000000000000000000000000000000000000000026b8b4a0b1e8292492", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "gas": "0x2e3bae", - "gasUsed": "0x9a62", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb000000000000000000000000da4a4626d3e16e094de3225a751aab7128e965260000000000000000000000000000000000000000000000000000000000000064", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000006dbfc63479ffc031f23e94dc91befa38bec2c25f", - "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000064", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "topics": [ - "0x4b0bc4f25f8d0b92d2e12b686ba96cd75e4e69325e6cf7b1f3119d14eaf2cbdf" - ], - "data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e96526", - "position": "0x6" - }, - { - "address": "0x6dbfc63479ffc031f23e94dc91befa38bec2c25f", - "topics": [ - "0xf340c079d598119636d42046c6a2d2faf7a68c04aecee516f0e0b8a9e79b8666" - ], - "data": "0x000000000000000000000000da4a4626d3e16e094de3225a751aab7128e9652600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000", - "position": "0x9" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x2e00dc", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x2dfc58", - "gasUsed": "0xa3bb", - "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "input": "0xd0679d340000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b0000000000000000000000000000000000000000000000000000000000000001", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2d9648", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a5", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0x2d91c2", - "gasUsed": "0x9a62", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b0000000000000000000000000000000000000000000000000000000000000001", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000001", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x2d57a6", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x2d5515", - "gasUsed": "0x3478d", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x2ceffb", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x2ce86e", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000001" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x2a0c87", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x2a09f6", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x29a4dc", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x299d4f", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000002", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000002" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x26fc00", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000002", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x26f96f", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x269455", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x268cc8", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000003", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000003" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x23eb79", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000003", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x23e8e8", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x2383ce", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x237c41", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000004", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000004" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x20daf2", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000004", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x20d861", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x207347", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x206bba", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000005", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000005" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x1dca6b", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000005", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x1dc7da", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x1d62c0", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x1d5b33", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000006", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000006" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x1ab9e4", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000006", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x1ab753", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x1a5239", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x1a4aac", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000007", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000007" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x17a95d", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000007", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x17a6cc", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x1741b2", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x173a25", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000008", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000008" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x1498d6", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000008", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x149645", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x14312b", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x14299e", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000009", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x0000000000000000000000000000000000000000000000000000000000000009" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x11884f", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x0000000000000000000000000000000000000000000000000000000000000009", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0x1185be", - "gasUsed": "0x30cf5", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0xff2f4bd2", - "calls": [ - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x1120a4", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000007498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "gas": "0x111917", - "gasUsed": "0x29e8d", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x612e45a3000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000093a80000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "output": "0x000000000000000000000000000000000000000000000000000000000000000a", - "calls": [ - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x304a554a310c7e546dfe434669c62820b7d83490", - "gas": "0x3", - "gasUsed": "0x3", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x", - "error": "out of gas", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0x5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f", - "0x000000000000000000000000000000000000000000000000000000000000000a" - ], - "data": "0x000000000000000000000000be3ae5cb97c253dda67181c6e34e43f5c275e08b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", - "position": "0x2" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0xe77c8", - "gasUsed": "0x112", - "to": "0x7498bb5749c9801f1f7e490baf5f966dbfe4e97b", - "input": "0x400e3949", - "output": "0x000000000000000000000000000000000000000000000000000000000000000a", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x03e3d4561a8f8e975fdcd798d32857a20cf25e7e", - "gas": "0xe7537", - "gasUsed": "0x1eafd", - "to": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "input": "0x975057e7", - "calls": [ - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0xe0f53", - "gasUsed": "0x314", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0x70a082310000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "output": "0x000000000000000000000000000000000000000000030328a3f333ac2fb5f4a4", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0xe096d", - "gasUsed": "0x9a62", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf3000000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000007ccbc69292c7a6d7b538c91f3b283de97906cf30" - ], - "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0xd6871", - "gasUsed": "0x9a62", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a200000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x0000000000000000000000001b9ec8ba24630b75a7a958153ffff56dd6d4b6a2" - ], - "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "gas": "0xcc775", - "gasUsed": "0x9a62", - "to": "0x304a554a310c7e546dfe434669c62820b7d83490", - "input": "0xa9059cbb000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x304a554a310c7e546dfe434669c62820b7d83490", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x0000000000000000000000004fd27b205895e698fa350f7ea57cec8a21927fcd", - "0x000000000000000000000000c3a2c744ad1f5253c736875b93bacce5b01b060b" - ], - "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "topics": [ - "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b" - ], - "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "position": "0x2" - }, - { - "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "topics": [ - "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b" - ], - "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "position": "0x3" - }, - { - "address": "0x4fd27b205895e698fa350f7ea57cec8a21927fcd", - "topics": [ - "0xc6d8c0af6d21f291e7c359603aa97e0ed500f04db6e983b9fce75a91c6b8da6b" - ], - "data": "0x00000000000000000000000000000000000000000001010d8bfbbbe40fe7518c", - "position": "0x4" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json deleted file mode 100644 index 66d4582008..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/multilogs.json +++ /dev/null @@ -1,580 +0,0 @@ -{ - "genesis": { - "difficulty": "7507253814130", - "extraData": "0xd783010400844765746887676f312e352e31856c696e7578", - "gasLimit": "3141592", - "hash": "0x3d9d19618f67bbb7708403fe9bda131fbade0449d2ac12bf3b140b4269112826", - "miner": "0x63a9975ba31b0b9626b34300f7f627147df1f526", - "mixHash": "0x50aaa8973eadd4bbfc7f5b59d5be52f6a1be2d38f40b5a0786a24b90257520da", - "nonce": "0x3547956c62c256b9", - "number": "595531", - "stateRoot": "0x79d00dd270bffc48d89fa55842f63f840981121378da8c6de4d479535f25ed6a", - "timestamp": "1448471472", - "totalDifficulty": "3448100174991667199", - "alloc": { - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x44dc051cccdfd2e132", - "nonce": "39602" - }, - "0x350e0ffc780a6a75b44cc52e1ff9092870668945": { - "balance": "0xe37111b7c79406c0", - "code": "0x606060405236156100f05760e060020a60003504631ff6c70581146100f257806347980c0d146100fd57806353ba9c2f146101085780635ea8cd12146101c957806369d640fd146101f05780637ce3489b146102405780637d1bb97a1461026b5780637fd6f15c146103e55780638bf50628146103f057806390a248f814610411578063a8f37bb214610438578063b019e0171461046a578063b4c70cea1461059b578063cf955f34146106a1578063d229b54b146106bd578063d54b4a04146106e4578063e021fadb146106f1578063e45be8eb14610858578063eddfa7c814610863578063f2a75fe41461095d575b005b6109a5621e84845481565b6109a5621e84865481565b6109b76004356024356000808080806003876103e881101561000257506107d0880201866103e8811015610002579090600202016000505461ffff168152602081019190915260400160002054600160a060020a031692506003856103e881101561000257506107d0860201846103e88110156100025790906002020160005054620100009004600390810b9250856103e881101561000257506107d0860201846103e8811015610002579090600202016000506001015490509250925092565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e848755565b6109e36004356024356003826103e881101561000257506107d0830201816103e88110156100025790906002020160005080546001919091015461ffff821693506201000090910460030b915083565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e84858190555b50565b610a0a600435617d00604051908101604052806103e8905b600081526020019060019003908161028357505060408051617d0081019091526103e8815b60008152602001906001900390816102a857505060408051617d0081019091526103e8815b60008152602001906001900390816102cd5750600090505b6103e861ffff82161015610d09576000806003836103e8811015610002576107d002018150876103e881101561000257600202016000505461ffff168152602081019190915260400160002054600160a060020a031684826103e8811015610002575050602082028501526003816103e8811015610002576107d00201600050856103e8811015610002579090600202016000505462010000900460030b83826103e8811015610002575050600390810b60208302850152816103e8811015610002576107d00201600050856103e8811015610002579090600202016000506001015482826103e8811015610002575050602082028301526001016102e5565b6109a5621e84855481565b610a59600435600060208190529081526040902054600160a060020a031681565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e848655565b6100f060043560243560443560643560843560a435610a8e868684866101000288620100000286607f02010101610870565b604080516004803580820135602081810280860182019096528185526100f09593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a996044999398509190910195509350839250850190849080828437505060408051606435808a013560208181028085018201909552818452989a9935999860849850929650602491909101945092508291908501908490808284375050604080519635808901356020818102808b018201909452818a5297999860a4989097506024929092019550935083925085019084908082843750949650505050505050621e848354600090600160a060020a03908116339091161415610a8e575b8551811015610a8e57606060405190810160405280610d1186610ebc565b60408051602060248035600481810135601f81018590048502860185019096528585526109a5958135959194604494929390920191819084018382808284375094965050933593505050505b6000831515610699577ffd33e90d0eac940755277aa91045b95664988beeeafc4ed7d1281a6d83afbc003384846040518084600160a060020a03168152602001806020018381526020018281038252848181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156106895780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a15b509192915050565b610a7660043560016020526000908152604090205461ffff1681565b6100f0600435621e848354600160a060020a0390811633909116141561026857621e848455565b610a7660025461ffff1681565b604080516004803580820135602081810280860182019096528185526109a59593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a9960449993985091909101955093508392508501908490808284375050604080519635808901356020818102808b018201909452818a529799986064989097506024929092019550935083925085019084908082843750506040805196358089013560208181028a81018201909452818a5297999860849890975060249290920195509350839250850190849080828437509496505050505050506000600060006000610ad68751895114606060405190810160405280602381526020017f446966666572656e74206e756d626572206f66207856616c732061732079566181526020017f6c732e00000000000000000000000000000000000000000000000000000000008152602001508a516105e7565b6109a5621e84875481565b6100f06004356024356044355b6000610a96848484345b6000808080808060038a6103e8811015610002576107d00201896103e88110156100025760020201805461ffff16825260208290526040822054621e8484546001830154621e848654939850600160a060020a03928316975060649181028290049650929092029190910492503316841415610f4d57610fbc82341015606060405190810160405280602e81526020017f4368616e67696e6720796f7572206f776e20706978656c20636f73747320313081526020017f25206f66206974732076616c7565000000000000000000000000000000000000815260200150846105e7565b6100f0621e848354600160a060020a039081163390911614156109a357604051621e848354600160a060020a03908116916000913016319082818181858883f150505050505b565b60408051918252519081900360200190f35b60408051600160a060020a0394909416845260039290920b602084015282820152519081900360600190f35b6040805161ffff94909416845260039290920b602084015282820152519081900360600190f35b6040518084617d008083818460006004610bc7f150918201918591508083818460006004610bc7f15061fa00840192508491508083818460006004610bc7f15062017700965092945050505050f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b505050505050565b90506000811115610ac25760405133600160a060020a031690600090839082818181858883f150505050505b50505050565b93505b505050949350505050565b1580610b4e5750610b4c8651895114606060405190810160405280602481526020017f446966666572656e74206e756d626572206f66207856616c7320617320636f6c81526020017f6f72732e000000000000000000000000000000000000000000000000000000008152602001508a516105e7565b155b80610bc55750610bc38551895114606060405190810160405280602481526020017f446966666572656e74206e756d626572206f66207856616c732061732070726981526020017f6365732e000000000000000000000000000000000000000000000000000000008152602001508a516105e7565b155b15610bd35760009350610acb565b5034915060009050805b8751811015610c63578481815181101561000257602090810290910101519092039160008310610d0157610cfb88828151811015610002579060200190602002015188838151811015610002579060200190602002015188848151811015610002579060200190602002015188858151811015610002579060200190602002015161087a565b6000821115610c8d5760405133600160a060020a031690600090849082818181858883f150505050505b610ac86000841015606060405190810160405280602181526020017f56616c756520776173206c657373207468616e2073756d206f6620707269636581526020017f7300000000000000000000000000000000000000000000000000000000000000815260200150856105e7565b91909101905b600101610bdd565b509193909250565b8152602001848381518110156100025790602001906020020151815260200183838151811015610002579060200190602002015181526020015060036000508783815181101561000257906020019060200201516103e8811015610002576107d002016000508683815181101561000257906020019060200201516103e8811015610002576002020160005081518154602084015160e060020a90810204620100000261ffff199190911690911765ffffffff00001916178155604091909101516001919091015560010161057d565b8454600061ffff919091161115610e225750604051621e84855460649088020490600160a060020a03851690600090838a039082818181858883f150505050505b845460018601546040805161ffff8e811682528d166020820152600160a060020a038881168284015262010000909404600390810b810b606083015260808201939093523390931660a0840152908a900b60c083015260e08201899052517fcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42918190036101000190a1606060405190810160405280611143335b600160a060020a03811660009081526001602052604081205461ffff1690811415610f485750604060008181206002805461ffff1981811661ffff928316600190810191821790945591821685526020858152958520805473ffffffffffffffffffffffffffffffffffffffff191688179055600160a060020a03871690945293528054909116821790555b919050565b60408051621e848754606082018352602182527f4d696e696d756d20706978656c2070726963652069732035302066696e6e657960208301527f2e00000000000000000000000000000000000000000000000000000000000000928201929092526110c29134101590896105e7565b1515610fca578695506110b5565b33600160a060020a031684600160a060020a03161415610de157604080518654600188015461ffff8e811684528d166020840152600160a060020a03881683850181905262010000909204600390810b810b60608501526080840182905260a0840192909252908b900b60c083015260e082015290517fcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42918190036101000190a18760038b6103e8811015610002576107d002018a6103e88110156100025760020201805465ffffffff0000191660e060020a92830292909204620100000291909117905581870395505b5050505050949350505050565b15806111365750610fbc83341015606060405190810160405280603281526020017f56616c7565206d7573742062652031302520686967686572207468616e20637581526020017f7272656e7420706978656c2070726963652e0000000000000000000000000000815260200150856105e7565b15610fca578695506110b5565b8152602081018a905260400188905260038b6103e8811015610002576107d002018a6103e8811015610002576002020160005081518154602084015160e060020a90810204620100000261ffff199190911690911765ffffffff000019161781556040919091015160019190910155600095506110b556", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000175901": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000175902": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000175903": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000175904": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760c7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760c8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760c9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760ca": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760cb": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760cc": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760cd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760ce": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760cf": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d1": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d3": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d5": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d6": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760d9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760da": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760db": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760dc": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760dd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760de": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760df": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001760e0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000176897": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000176898": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000176899": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000017689a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000017689b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000017689c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000017689d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000017689e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000017689f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768a0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768a7": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768a8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768a9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768aa": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768ab": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768ac": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768ad": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768ae": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768af": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001768b0": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c37": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c38": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c39": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c3a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c3b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c3c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c3d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c3e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c3f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c40": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c45": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c46": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c47": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c48": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c49": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c4a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c4b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c4c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c4d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c4e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c4f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000196c50": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197407": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197408": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197409": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019740a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019740b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019740c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019740d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019740e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019740f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197410": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197411": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197412": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197413": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197414": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197415": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197416": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197417": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197418": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197419": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019741a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019741b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019741c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019741d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019741e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000019741f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197420": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197be3": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000197be4": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x00000000000000000000000000000000000000000000000000000000001e8484": "0x000000000000000000000000000000000000000000000000000000000000006e", - "0x00000000000000000000000000000000000000000000000000000000001e8486": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x00000000000000000000000000000000000000000000000000000000001e8487": "0x0000000000000000000000000000000000000000000000000011c37937e08000", - "0xad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xe1723559c995b1804c0512df6fe6d061eeb47aff37a3ced3b93f0c1bef247540": "0x0000000000000000000000000000000000000000000000000000000000000007" - } - }, - "0x3fcb0342353c541e210013aaddc2e740b9a33d08": { - "balance": "0x6a0e4be198f18400", - "nonce": "17" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "595532", - "difficulty": "7503588162862", - "timestamp": "1448471495", - "gasLimit": "3141592", - "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226" - }, - "input": "0xf91a7311850ba43b7400832dc6c094350e0ffc780a6a75b44cc52e1ff90928706689458803782dace9d90000b91a04e021fadb000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000013a00000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fd000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000002fd0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000032fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebebffffffffffffffffffffffffffffffffffffffffffffffffffffffffff888888ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff636363fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e53ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080001ca0e8a879dd98a39d735b866ff64d84e9c144a17bcab106cf2f1327b1272db06aaca02ab279a2459b5e30dfea0bc8a888c7d2a190740090352b4a7aded30c45490af9", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0x3fcb0342353c541e210013aaddc2e740b9a33d08", - "gas": "0x2dc6c0", - "gasUsed": "0x2570bf", - "to": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "input": "0xe021fadb000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000006e00000000000000000000000000000000000000000000000000000000000000d4000000000000000000000000000000000000000000000000000000000000013a00000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000002fd000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000002fd0000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003700000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003900000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000035000000000000000000000000000000000000000000000000000000000000003b000000000000000000000000000000000000000000000000000000000000003b00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000003c00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000000000003d000000000000000000000000000000000000000000000000000000000000003d00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000032000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000032fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebebffffffffffffffffffffffffffffffffffffffffffffffffffffffffff888888ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f4fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5bffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b9fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfbfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff636363fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaeaffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f8fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfcfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e53ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000000011c37937e08000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "logs": [ - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffebebeb0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8888880000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb3b3b30000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe3e3e30000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3e3e3e0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdbdbdb0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f4f40000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034100000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002ff000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000341000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0b0b00000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0a0a00000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b5b5b0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000390000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9a9a90000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb9b9b90000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfbfb0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000350000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffefefe0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbababa0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6363630000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9f9f90000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeaeaea0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9c9c9c0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8f8f80000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034200000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcfcfc0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fe000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfdfd0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000000342000000000000000000000000000000000000000000000000000000000000003e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4d4e530000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x000000000000000000000000000000000000000000000000000000000000034300000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - }, - { - "address": "0x350e0ffc780a6a75b44cc52e1ff9092870668945", - "topics": [ - "0xcacb62d8acea4678658eb5dc4aaa889b34d893b967c96a5f8c066e6549fa3f42" - ], - "data": "0x00000000000000000000000000000000000000000000000000000000000002fd00000000000000000000000000000000000000000000000000000000000000370000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003fcb0342353c541e210013aaddc2e740b9a33d08ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f494b0000000000000000000000000000000000000000000000000011c37937e08000", - "position": "0x0" - } - ], - "value": "0x3782dace9d90000", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json deleted file mode 100644 index 762ccbe58f..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/notopic.json +++ /dev/null @@ -1,288 +0,0 @@ -{ - "genesis": { - "difficulty": "45944156141275", - "extraData": "0xd783010406844765746887676f312e342e32856c696e7578", - "gasLimit": "4714680", - "hash": "0x3c41811ab60f232565db6cfafb939d96255b9f678a203181c6f537d6c22d7e6f", - "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", - "mixHash": "0x8b736c63e05d381ae593d584b63fef5c31b04a3cea72bd5a3c92f95f4f7040e8", - "nonce": "0xce8ffb5c1ad942ec", - "number": "1725115", - "stateRoot": "0xca08a341c1f95fcba0821c4a27662ef162d39e1f9f5722717531f510d54112b0", - "timestamp": "1466232982", - "totalDifficulty": "28554024908214037524", - "alloc": { - "0x0000000000000000000000000000000000000004": { - "balance": "0x0" - }, - "0x1d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed": { - "balance": "0x0", - "code": "0x606060405260e060020a600035046338cc483181146038578063767800de14604f578063a6f9dae1146060578063d1d80fdf14607e575b005b600054600160a060020a03165b6060908152602090f35b6045600054600160a060020a031681565b603660043560015433600160a060020a03908116911614609c576002565b603660043560015433600160a060020a0390811691161460be576002565b6001805473ffffffffffffffffffffffffffffffffffffffff19168217905550565b6000805473ffffffffffffffffffffffffffffffffffffffff1916821790555056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713" - } - }, - "0x50739060a2c32dc076e507ae1a893aab28ecfe68": { - "balance": "0x6a8ecefb09f7c4141", - "code": "0x606060405236156101745760e060020a6000350463058aace1811461017f578063061e494f146101905780630d1fce421461021e57806311610c251461029157806312253a6c146102b5578063132ae5e9146102d357806316d190e3146102dc57806329e206bd146102e5578063337b68ba1461030a57806338bbfa50146103135780633f683b6a146104115780634dc6b523146104245780634e69d5601461042d57806366d16cc31461044a578063724ae9d014610453578063758971e81461046f5780637cf0ffcb146104965780638ca17995146104a35780639619367d146104b7578063a96a5a5b146104c0578063adc2c98a146104c9578063b70d0b3b146104d2578063bc99cc37146104db578063c4bc5da5146104e4578063cafb220214610502578063d28442ef1461050b578063d4c80edf14610514578063df06f9061461051d578063e8b5e51f14610527578063f738e5ca14610546578063f8b2cb4f14610553578063fa968eea14610594575b610661610663610295565b6106616000341115610eab57610002565b61066560043560006000600060006000600f6000508054905086101561021657600f8054879081101561000257505050507f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80284015490819052600e602052604090912080546001820154600283015460039390930154600160a060020a03929092169450925b509193509193565b6106965b601254601354601154600c5460009391019091010330600160a060020a0316318190101561028957604080517f62616e6b726f6c6c5f6d69736d61746368000000000000000000000000000000815290519081900360110190a05030600160a060020a0316315b8091505b5090565b6106615b600060006000600d60149054906101000a900460ff16156106ef57610002565b610661600d5433600160a060020a03908116911614610fd657610002565b610696600a5481565b61069660045481565b6106616004355b600d5460009033600160a060020a0390811691161461101c57610002565b61069660125481565b60408051602060248035600481810135601f81018590048502860185019096528585526106619581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505050505050506000600060006000610a18600080546040805160e060020a6338cc483102815290518392600160a060020a0316916338cc4831916004828101926020929190829003018187876161da5a03f11561000257505060405151915050600160a060020a0381168214156114635761140b6000610939565b610696600d5460a060020a900460ff1681565b61069660085481565b6106a8600060006000600060006000600060006000610f8d610222565b61069660115481565b6106965b600a54600654600091829182911015610ef857610f33565b6106616004355b600d54600090819033600160a060020a0390811691161461108657610002565b61066161066360006102ec565b6106616004356000341115610e7957610002565b61069660055481565b61069660025481565b61069660035481565b61069660075481565b61069660065481565b610661600d5433600160a060020a03908116911614610ffc57610002565b610696600c5481565b61069660135481565b61069660105481565b610696600f545b90565b610661600d54600090819060a060020a900460ff1615610c8057610002565b6106616106636000610476565b6106966004355b600160a060020a0381166000908152600b602052604081205481901180156105845750600c548190115b15610ebd57600c54610ec6610222565b610696600080546040805160e060020a6338cc483102815290518392600160a060020a0316916338cc4831916004828101926020929190829003018187876161da5a03f11561000257505060408051805160e260020a630bbceb33028252620249f06024830152600482018390526003604483015260ea60020a621554930260648301529151600160a060020a03929092169250632ef3accc916084828101926020929190829003018187876161da5a03f1156100025750506040515160055481019350915061028d9050565b005b565b60408051600160a060020a039590951685526020850193909352838301919091526060830152519081900360800190f35b60408051918252519081900360200190f35b60408051998a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e084015261010083015251908190036101200190f35b600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e260020a630bbceb33028252620249f06024830152600482018390526003604483015260ea60020a621554930260648301529151600160a060020a03929092169250632ef3accc91608480830192602092919082900301816000876161da5a03f1156100025750506040515193505034839010156107c257610002565b82340391506127106107d2610222565b600460005054020460026000505460026000505460036000505461271003038402041115801561080457506005548210155b1561095a576040805180820182526003815260ea60020a62155493026020828101919091528251608081018452604381527f6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e818301527f2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174818501527f612e30000000000000000000000000000000000000000000000000000000000060608201528351610160810190945261012c80855261095f94919261175690830139620249f0600060006000600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151915050600160a060020a03811682141561118c5761113460005b600060006115ef731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed5b3b90565b610002565b6040805160808101825233815260208181018681526000838501818152606085018a8152878352600e90945293519490208054600160a060020a031916909417845551600184810191909155915160028401555160039290920191909155600f8054918201808255929350918281838015829011610a0057818360005260206000209182019101610a0091905b8082111561028d57600081556001016109ec565b5050506000928352506020909120018190555b505050565b600160a060020a031633600160a060020a0316141515610a3757610002565b6000878152600e6020526040812060018101549095501115610c5257600d5460a060020a900460ff166000148015610aa15750612710610a75610222565b600460005054020460026000505460026000505460036000505461271003038660010160005054020411155b15610b4957610b968660006114e28260006040805160208101909152600090819052828180805b8351811015610b3e57603060f860020a02848281518110156100025790602001015160f860020a900460f860020a0210158015610b295750603960f860020a02848281518110156100025790602001015160f860020a900460f860020a0211155b156116cb578115611722578560001415611719575b509095945050505050565b60018401548454610c5291600160a060020a0391909116905b604051600160a060020a038316906161a89083906000818181858888f193505050501515610d005760138054820190555050565b92506001831080610ba8575061271083115b15610bc75783546001850154610c5291600160a060020a031690610b62565b6000878152600e6020526040902060029081018490555460001984011015610c5b57506002546003546001850154855461271092909203029190910490610c7190600160a060020a031682610b62565b60018401546000190191505b601380546007546127109085020590810190915560118054918403909101905560018401546010805490910190555b50505050505050565b8354610c1790600160a060020a03166001610b62565b60018401548190039150610c23565b33600160a060020a03166000908152600b60205260408120541115610ca757610cc5610cab565b610d045b6011546012546000918291829114610a13576114e9610222565b33600160a060020a03166000908152600b6020908152604080832054835260099091529020600101805434908101909155600c805490910190555b5050565b600a5460065460009350901015610d6557600a80546001019081905591505b600082111561095a576000828152600960205260408120600101541115610deb576040600020805460019190910154610dc591600160a060020a031690610e7f565b5060015b600a548111610d23576000818152600960205260409020600101543490108015610db457508160001480610db457506040600081812060019081015485835292822001549083905290105b15610dbd579050805b600101610d69565b600082815260096020908152604080832054600160a060020a03168352600b9091528120555b600082815260096020526040812060010154148015610e2357506040600081812054600160a060020a03168152600b60205290812054145b1561095a5760008281526009602090815260408083208054600160a060020a03191633908117825534600192909201829055600c8054909201909155600160a060020a03168352600b9091529020829055610d00565b610ea833825b600160a060020a0382166000908152600b602052604081205481901115610a1357611578610cab565b50565b61066333610eb83361055a565b610e7f565b5060005b919050565b600160a060020a0384166000908152600b60209081526040808320548352600990915290206001015402049050610ec1565b5060015b600a548111610f38578160001480610f5b5750600082815260096020526040902054610f6c90600160a060020a031661055a565b92505b505090565b600082815260096020526040902054610f3090600160a060020a031661055a565b105b15610f64579050805b600101610efc565b600082815260096020526040902054610f5990600160a060020a031661055a565b601154600254600354600454600554601054939492939192909190610fb0610457565b600f60005080549050985098509850985098509850985098509850909192939495969798565b600d805474ff0000000000000000000000000000000000000000191660a060020a179055565b600d805474ff000000000000000000000000000000000000000019169055565b5060015b600a54811161104e5760008181526009602052604090205461107e90600160a060020a0316610eb88161055a565b8115610d0057604051600d54600160a060020a03908116916000913016319082818181858883f150505050505050565b600101611020565b82156110bb57506000905060015b600a5481116110e55760008181526009602052604090206001015490910190600101611094565b601354604051600d54600160a060020a03169160009182818181858883f150505060135550505050565b816000148015611101575060135430600160a060020a03163114155b1561112f57604051600d54600160a060020a03908116916000913016319082818181858883f1505050601355505b610a13565b50600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519150505b60018054600160a060020a0319168217908190556040805160e260020a630bbceb330281526024810187905260048181019283528a5160448301528a51600160a060020a039490941693632ef3accc938c938a939192839260649290920191602087810192918291859183918691600091601f850104600f02600301f150905090810190601f1680156112335780820380516001836020036101000a031916815260200191505b5093505050506020604051808303816000876161da5a03f115610002575050604051519250503a8402670de0b6b3a76400000182111561127c5750600091505b50949350505050565b600160009054906101000a9004600160a060020a0316600160a060020a03166385dee34c8360008a8a8a8a6040518760e060020a028152600401808681526020018060200180602001806020018581526020018481038452888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156113275780820380516001836020036101000a031916815260200191505b508481038352878181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156113805780820380516001836020036101000a031916815260200191505b508481038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156113d95780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038185886185025a03f11561000257505060405151945061127392505050565b50600060009054906101000a9004600160a060020a0316600160a060020a03166338cc48316040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051519150505b60018054600160a060020a031916821790819055604080517fc281d19e0000000000000000000000000000000000000000000000000000000081529051600160a060020a03929092169163c281d19e9160048181019260209290919082900301816000876161da5a03f115610002575050604051519250610524915050565b9050610ec1565b9150600190505b600a54811161151a5760008181526009602052604090205461155990600160a060020a031661055a565b600c8390558282148015906115325750600a54600090115b1561154e5760138054848403908101909155600c805490910190555b601154601255505050565b60008281526009602052604090206001908101829055930192016114f0565b6115818361055a565b821115611594576115918361055a565b91505b50600160a060020a0382166000908152600b602090815260408083205483526009909152902060010180548290039055600c8054829003905560085460138054612710928402929092049182019055610a1383828403610b62565b1115611623575060008054600160a060020a031916731d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed1790556001610ec1565b6000611642739efbea6358bed926b293d2ce63a730d6d98d43dd610956565b1115611678575060008054739efbea6358bed926b293d2ce63a730d6d98d43dd600160a060020a03199091161790556001610ec1565b60006116977320e12a1f859b3feae5fb2a0a32c18f5a65555bbf610956565b1115610ebd575060008054600160a060020a0319167320e12a1f859b3feae5fb2a0a32c18f5a65555bbf1790556001610ec1565b8381815181101561000257016020015160f860020a90819004027f2e00000000000000000000000000000000000000000000000000000000000000141561171157600191505b600101610ac8565b60001995909501945b600a83029250825060308482815181101561000257016020015160f860020a90819004810204909301602f19019250611711564244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000001d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000000000000009c4", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000000000000000000000000000000000000000000000000000be", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000064", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000000002c68af0bb140000", - "0x000000000000000000000000000000000000000000000000000000000000000c": "0x000000000000000000000000000000000000000000000006ad2ff8ba84afdcdc", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x000000000000000000000000a1b5f95be71ffa2f86adefcaa0028c46fe825161", - "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000000000022", - "0x0000000000000000000000000000000000000000000000000000000000000011": "0xffffffffffffffffffffffffffffffffffffffffffffffffd14ae0a37b4cc1d4", - "0x0000000000000000000000000000000000000000000000000000000000000012": "0xffffffffffffffffffffffffffffffffffffffffffffffffd5ab72be30cb5f50", - "0x0000000000000000000000000000000000000000000000000000000000000013": "0xffffffffffffffffd5bbd8ce9d1eb44232ca20eb5b4319ac5e1982d2c94bc3cb", - "0x8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac824": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1eb9": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1eba": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1ebb": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xe950f1be9a49788ef79ea4e854ed56155a7f60661724f41e3af5f799203a1ebc": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x61c808d82a3ac53231750dadc13c777b59310bd9": { - "balance": "0x12f621ea72fef44f848", - "nonce": "51830" - }, - "0x6412becf35cc7e2a9e7e47966e443f295e1e4f4a": { - "balance": "0xfb5dbfc0d448e70", - "nonce": "6" - }, - "0x88e1315687aec48a72786c6b3b3f075208b62713": { - "balance": "0x24b9f2c5dc266dc6", - "code": "0x606060405236156101535760e060020a60003504630f825673811461018f57806323dc42e7146102135780632ef3accc146102ad578063453629781461033b578063480a434d146103d5578063524f3889146103de5780635c242c591461043f57806360f66701146104de57806362b3b8331461056757806368742da6146105eb578063688dcfd71461062b578063757004371461065857806377228659146106f25780637d242ae5146107cd5780637e1c42051461085357806381ade3071461033b57806385dee34c14610932578063a2ec191a14610a0c578063adf59f9914610213578063ae81584314610658578063b5bfdd7314610a64578063bf1fe42014610af2578063c281d19e14610b32578063c51be90f14610b44578063ca6ad1e414610bdd578063d959701614610bff578063db37e42f14610cb6578063de4b326214610d6d578063e839e65e14610daf575b61065660025433600160a060020a039081169116148015906101855750600154600160a060020a039081163390911614155b15610e8a57610002565b6106566004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650505050505050600254600160a060020a0390811633909116148015906102095750600154600160a060020a039081163390911614155b15610ebb57610002565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505050505050506000610f2084848462030d406104cb565b610e8c6004808035906020019082018035906020019191908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965050933593505050506000610f288383335b6000600062030d40841115801561032d5750600160a060020a03831681526020819052604081205481145b1561184e5760009150611846565b610e8c6004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750506040805160208835808b0135601f81018390048302840183019094528383529799986044989297509190910194509092508291508401838280828437509496505050505050506000610f286000848462030d406104cb565b610e8c60085481565b610e8c6004808035906020019082018035906020019191908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496505050505050506000610f2f82336000610f288362030d4084610302565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050505b600083826000600061113d848433610302565b6106566004808035906020019082018035906020019191908080601f0160208091040260200160405190810160405280939291908181526020018383808284375094965050505050505080604051808280519060200190808383829060006004602084601f0104600f02600301f150905001915050604051809103902060046000508190555050565b6106566004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650505050505050600254600160a060020a0390811633909116148015906105e15750600154600160a060020a039081163390911614155b1561119757610002565b610656600435600254600160a060020a0390811633909116148015906106215750600154600160a060020a039081163390911614155b156111f957610002565b600160a060020a0333166000908152600660205260409020805460ff191660f860020a600435041790555b005b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050505b6000610f1d858585856104cb565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760849791965060249190910194509092508291508401838280828437509496505050505050506000610f1d8585858562030d4061091f565b60408051602060248035600481810135601f81018590048502860185019096528585526106569581359591946044949293909201918190840183828082843750949650505050505050600254600090600160a060020a0390811633909116148015906108495750600154600160a060020a039081163390911614155b1561121f57610002565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505050505b6000848260006000611516848433610302565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a019093528282529698976064979196506024919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760849791965060249190910194509092508291508401838280828437509496505093359350505050600061156b868686868661091f565b6106566004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750949650509335935050505061157282600083610ab5565b6106566004808035906020019082018035906020019191908080601f016020809104026020016040519081016040528093929190818152602001838380828437509496505093359350506044359150505b600254600090600160a060020a039081163390911614801590610ae85750600154600160a060020a039081163390911614155b1561157657610002565b610656600435600254600160a060020a039081163390911614801590610b285750600154600160a060020a039081163390911614155b1561162f57610002565b610e9e600154600160a060020a031681565b60408051602060248035600481810135601f8101859004850286018501909652858552610e8c9581359591946044949293909201918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897606497919650602491909101945090925082915084018382808284375094965050933593505050506000610f1d858585856106e4565b600160a060020a03331660009081526007602052604090206004359055610656565b604080516004803580820135602081810285810182019096528185526106569593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a99604499939850919091019550935083925085019084908082843750949650505050505050600254600090600160a060020a039081163390911614801590610cac5750600154600160a060020a039081163390911614155b1561163457610002565b604080516004803580820135602081810285810182019096528185526106569593946024949093850192918291908501908490808284375050604080518735808a013560208181028085018201909552818452989a99604499939850919091019550935083925085019084908082843750949650505050505050600254600090600160a060020a039081163390911614801590610d635750600154600160a060020a039081163390911614155b1561168f57610002565b61065660043560025460009033600160a060020a03908116911614801590610da55750600154600160a060020a039081163390911614155b1561170557610002565b610e8c6004808035906020019082018035906020019191908080601f01602080910402602001604051908101604052809392919081815260200183838082843750506040805160208835808b0135601f8101839004830284018301909452838352979998604498929750919091019450909250829150840183828082843750506040805160209735808a0135601f81018a90048a0283018a0190935282825296989760649791965060249190910194509092508291508401838280828437509496505050505050506000610f20600085858562030d4061091f565b565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60006003600050600083604051808280519060200190808383829060006004602084601f0104600f02600301f1509050019150506040518091039020815260200190815260200160002060006101000a81548160ff0219169083021790555050565b90505b949350505050565b9392505050565b92915050565b6000600050600033600160a060020a031681526020019081526020016000206000505433600160a060020a031630600160a060020a03160101604051808281526020019150506040518091039020945084506000600050600033600160a060020a031681526020019081526020016000206000818150548092919060010191905055507fb76d0edd90c6a07aa3ff7a222d7f5933e29c6acc660c059c97837f05c4ca1a8433868b8b8b8b6006600050600033600160a060020a0316815260200190815260200160002060009054906101000a900460f860020a026007600050600033600160a060020a03168152602001908152602001600020600050546040518089600160a060020a0316815260200188815260200187815260200180602001806020018681526020018581526020018481526020018381038352888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156110c35780820380516001836020036101000a031916815260200191505b508381038252878181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561111c5780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390a150505050949350505050565b91503482901061119257813403905060008111156111765760405133600160a060020a031690600090839082818181858883f150505050505b42624f1a000189118061118857504586115b15610f3557610002565b610002565b60016003600050600083604051808280519060200190808383829060006004602084601f0104600f02600301f1509050019150506040518091039020815260200190815260200160002060006101000a81548160ff0219169083021790555050565b604051600160a060020a03828116916000913016319082818181858883f1505050505050565b50600882905560005b600b548110156112a757600b8054600a91600091849081101561000257508054600080516020611883833981519152850154835260209390935260408220548602926009929190859081101561000257908252600080516020611883833981519152018150548152602081019190915260400160002055600101611228565b505050565b6000600050600033600160a060020a031681526020019081526020016000206000505433600160a060020a031630600160a060020a03160101604051808281526020019150506040518091039020945084506000600050600033600160a060020a031681526020019081526020016000206000818150548092919060010191905055507faf30e4d66b2f1f23e63ef4591058a897f67e6867233e33ca3508b982dcc4129b33868c8c8c8c8c6006600050600033600160a060020a0316815260200190815260200160002060009054906101000a900460f860020a026007600050600033600160a060020a0316815260200190815260200160002060005054604051808a600160a060020a0316815260200189815260200188815260200180602001806020018060200187815260200186815260200185815260200184810384528a8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561143f5780820380516001836020036101000a031916815260200191505b508481038352898181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156114985780820380516001836020036101000a031916815260200191505b508481038252888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156114f15780820380516001836020036101000a031916815260200191505b509c5050505050505050505050505060405180910390a1505050505b95945050505050565b915034829010611192578134039050600081111561154f5760405133600160a060020a031690600090839082818181858883f150505050505b42624f1a00018a118061156157504586115b156112ac57610002565b905061150d565b5050565b8383604051808380519060200190808383829060006004602084601f0104600f02600301f150905001828152600101925050506040518091039020905080600b600050600b600050805480919060010190908154818355818115116115fe578183600052602060002091820191016115fe91905b8082111561162b57600081556001016115ea565b5050508154811015610002576000918252602080832090910192909255918252600a905260409020555050565b5090565b600555565b5060005b81518110156112a7578281815181101561000257906020019060200201516007600050600084848151811015610002576020908102909101810151600160a060020a03168252919091526040902055600101611638565b5060005b81518110156112a75782818151811015610002579060200190602002015160f860020a026006600050600084848151811015610002576020908102909101810151600160a060020a031682529190915260409020805460f860020a90920460ff19909216919091179055600101611693565b50600881905560005b600b5481101561157257600b8054600a91600091849081101561000257600080516020611883833981519152015482526020929092526040812054825490850292600992918590811015610002576000805160206118838339815191520154825250602091909152604090205560010161170e565b60096000506000866006600050600087600160a060020a0316815260200190815260200160002060009054906101000a900460f860020a02604051808380519060200190808383829060006004602084601f0104600f02600301f150905001828152600101925050506040518091039020815260200190815260200160002060005054915081506007600050600084600160a060020a03168152602001908152602001600020600050549050806000141561183d57506005545b83810291909101905b509392505050565b600454600014801590611875575060045460009081526003602052604090205460ff166001145b156117835760009150611846560175b7a638427703f0dbe7bb9bbf987a2551717b34e79f33b5b1008d1fa01db9", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000004": "0xbb130806898f085471286ecb4f3966fcbe090ba29e4f9d194ee9e9062f6b61ae", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x00000000000000000000000000000000000000000000000000000004a817c800", - "0x797fdd0f6c82412493cfa2aacdc9999c10e5d0c9aa3f05a8a289b1b3918c6db8": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8d90a37db271d62339ebfe84641d1ebdaf56fd5d50861d795eacb410dbb57630": "0x000000000000000000000000000000000000000000000000000cf4e712e8d654", - "0x9864048b6d6c99ecd7fcaecf663fbe1036a6e1fc00cec0a3eb25684dd08184c2": "0x0000000000000000000000000000000000000000000000000000000000000011", - "0xca9ea8077ddc97a21c029df4b19819e51903e11d4bfc7564a622a192cefd6356": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xf34e44a0672ef76b852374cc47d9772eb4e5e41fa79fba61dcfc9cf7d50418d5": "0x0000000000000000000000000000000000000000000000000000000000000022" - } - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "1725116", - "difficulty": "45966589844033", - "timestamp": "1466232988", - "gasLimit": "4716972", - "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9" - }, - "input": "0xf86d068504e3b2920083030d409450739060a2c32dc076e507ae1a893aab28ecfe68880429d069189e0000801ca04e403b46022c2098e41d3a0e561881ac368cd330637239da85759c1b4f44ab24a072a88235d98959283c00af411bd663b0da8703e05a94d3673aca37d0a39b7e07", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0x6412becf35cc7e2a9e7e47966e443f295e1e4f4a", - "gas": "0x30d40", - "gasUsed": "0x249eb", - "to": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "input": "0x", - "calls": [ - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x257af", - "gasUsed": "0xbc", - "to": "0x1d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed", - "input": "0x38cc4831", - "output": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x255a1", - "gasUsed": "0x73a", - "to": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "input": "0x2ef3accc000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000355524c0000000000000000000000000000000000000000000000000000000000", - "output": "0x00000000000000000000000000000000000000000000000000179d63013c5654", - "calls": [ - { - "from": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "gas": "0x12", - "gasUsed": "0x12", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x55524c", - "output": "0x55524c", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x24680", - "gasUsed": "0xbc", - "to": "0x1d3b2638a7cc9f2cb3d298a3da7a90b67e5506ed", - "input": "0x38cc4831", - "output": "0x00000000000000000000000088e1315687aec48a72786c6b3b3f075208b62713", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x12", - "gasUsed": "0x12", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x55524c", - "output": "0x55524c", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x22f3b", - "gasUsed": "0x73a", - "to": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "input": "0x2ef3accc000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000355524c0000000000000000000000000000000000000000000000000000000000", - "output": "0x00000000000000000000000000000000000000000000000000179d63013c5654", - "calls": [ - { - "from": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "gas": "0x12", - "gasUsed": "0x12", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x55524c", - "output": "0x55524c", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x12", - "gasUsed": "0x12", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x55524c", - "output": "0x55524c", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x30", - "gasUsed": "0x18", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30", - "output": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x99", - "gasUsed": "0x2d", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d", - "output": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "gas": "0x2083e", - "gasUsed": "0x4417", - "to": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "input": "0x85dee34c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000355524c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d0000000000000000000000000000000000000000", - "output": "0xd1b13c1538a940417bf0e73b2498634436753c854c7fb971224d971bd2ae3e88", - "calls": [ - { - "from": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "gas": "0x12", - "gasUsed": "0x12", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x55524c", - "output": "0x55524c", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "gas": "0x12", - "gasUsed": "0x12", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x55524c", - "output": "0x55524c", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "gas": "0x30", - "gasUsed": "0x18", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30", - "output": "0x6a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e30", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "gas": "0x99", - "gasUsed": "0x2d", - "to": "0x0000000000000000000000000000000000000004", - "input": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d", - "output": "0x4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x88e1315687aec48a72786c6b3b3f075208b62713", - "topics": [ - "0xaf30e4d66b2f1f23e63ef4591058a897f67e6867233e33ca3508b982dcc4129b" - ], - "data": "0x00000000000000000000000050739060a2c32dc076e507ae1a893aab28ecfe68d1b13c1538a940417bf0e73b2498634436753c854c7fb971224d971bd2ae3e8800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000249f011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000355524c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000436a736f6e2868747470733a2f2f6170692e72616e646f6d2e6f72672f6a736f6e2d7270632f312f696e766f6b65292e726573756c742e72616e646f6d2e646174612e300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c4244584a68725670424a35336f3243786c4a526c51745a4a4b5a714c5974354951652b37335944533448744e6a5335486f64624942337476666f773755717579416b303835566b4c6e4c3945704b67777157517a375a4c64477673516c526432734b78496f6c4e673944626e6650737047714c684c62625953566e4e38437776736a7041586353536f33632b34634e774339307946346f4e69626b764433797461706f5a37676f5453796f5559546677536a6e773374692b484a5648374e332b633069774f43715a6a4464734751556358336d33532f494857624f4f5151356f734f344c626a33476730783155644e7466557a5943465937396e7a596757495145464375524249306e364e42764251573732372b4f73445259304a2f392f676a74387563696248576963303d0000000000000000000000000000000000000000", - "position": "0x4" - } - ], - "value": "0x179d63013c5654", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0x50739060a2c32dc076e507ae1a893aab28ecfe68", - "topics": [], - "data": "0x62616e6b726f6c6c5f6d69736d61746368", - "position": "0x2" - } - ], - "value": "0x429d069189e0000", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json deleted file mode 100644 index 64941dd4db..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/simple.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "genesis": { - "difficulty": "8430028481555", - "extraData": "0xd783010302844765746887676f312e352e31856c696e7578", - "gasLimit": "3141592", - "hash": "0xde66937783697293f2e529d2034887c531535d78afa8c9051511ae12ba48fbea", - "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226", - "mixHash": "0xba28a43bfbca4a2effbb76bb70d03482a8a0c92e2883ff36cbac3d7c6dbb7df5", - "nonce": "0xa3827ec0a82fe823", - "number": "765824", - "stateRoot": "0x8d96cb027a29f8ca0ccd6d31f9ea0656136ec8030ecda70bb9231849ed6f41a2", - "timestamp": "1451389443", - "totalDifficulty": "4838314986494741271", - "alloc": { - "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb": { - "balance": "0x14203bee2ea6fbe8c", - "nonce": "34" - }, - "0xe2fe6b13287f28e193333fdfe7fedf2f6df6124a": { - "balance": "0x2717a9c870a286f4350" - }, - "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd": { - "balance": "0x0", - "code": "0x606060405260e060020a600035046306fdde038114610047578063313ce567146100a457806370a08231146100b057806395d89b41146100c8578063a9059cbb14610123575b005b61015260008054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156101f55780601f106101ca576101008083540402835291602001916101f5565b6101c060025460ff1681565b6101c060043560036020526000908152604090205481565b610152600180546020601f6002600019610100858716150201909316929092049182018190040260809081016040526060828152929190828280156101f55780601f106101ca576101008083540402835291602001916101f5565b610045600435602435600160a060020a033316600090815260036020526040902054819010156101fd57610002565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156101b25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116101d857829003601f168201915b505050505081565b600160a060020a03821660009081526040902054808201101561021f57610002565b806003600050600033600160a060020a03168152602001908152602001600020600082828250540392505081905550806003600050600084600160a060020a0316815260200190815260200160002060008282825054019250508190555081600160a060020a031633600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505056", - "storage": { - "0x1dae8253445d3a5edbe8200da9fc39bc4f11db9362181dc1b640d08c3c2fb4d6": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8ba52aac7f255d80a49abcf003d6af4752aba5a9531cae94fde7ac8d72191d67": "0x000000000000000000000000000000000000000000000000000000000178e460" - } - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "765825", - "difficulty": "8425912256743", - "timestamp": "1451389488", - "gasLimit": "3141592", - "miner": "0xe2fe6b13287f28e193333fdfe7fedf2f6df6124a" - }, - "input": "0xf8aa22850ba43b740083024d4594f4eced2f682ce333f96f2d8966c613ded8fc95dd80b844a9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb00000000000000000000000000000000000000000000000000000000009896801ca067da548a2e0f381a957b9b51f086073375d6bfc7312cbc9540b3647ccab7db11a042c6e5b34bc7ba821e9c25b166fa13d82ad4b0d044d16174d5587d4f04ecfcd1", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", - "gas": "0x24d45", - "gasUsed": "0xc6a5", - "to": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd", - "input": "0xa9059cbb000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb0000000000000000000000000000000000000000000000000000000000989680", - "logs": [ - { - "address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd", - "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", - "0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb" - ], - "data": "0x0000000000000000000000000000000000000000000000000000000000989680", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json deleted file mode 100644 index 30346d07f1..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_failed.json +++ /dev/null @@ -1,244 +0,0 @@ -{ - "genesis": { - "difficulty": "56311715121637", - "extraData": "0x7777772e62772e636f6d", - "gasLimit": "4712388", - "hash": "0x20d3b8daa046f2f10564d84ccbe6d0a8842d8d52bc6d623e23c38050a8f73776", - "miner": "0xbcdfc35b86bedf72f0cda046a3c16829a2ef41d1", - "mixHash": "0x75029f90d7de3f9e3d5eac4a25019f9ac5d0041641d1ef17e7759e45699d4224", - "nonce": "0x54ff3b34fa1d9c97", - "number": "1968179", - "stateRoot": "0x6420003b1779cca3bcdab698c239bbc63623c0a7e4deeedbdb8190b9e7fd7520", - "timestamp": "1469713675", - "totalDifficulty": "42284028928878034360", - "alloc": { - "0x10abb5efecdc09581f8b7cb95791fe2936790b4e": { - "balance": "0x81f158e2814b4ab624c", - "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", - "nonce": "3", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057bda071", - "0x0000000000000000000000000000000000000000000000000000000000000010": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000011": "0x0000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c18941301", - "0x0000000000000000000000000000000000000000000000000000000000000012": "0x000000000000000000000000fde8d5f77ef48bb7bf5766c7404691b9ee1dfca7", - "0x0000000000000000000000000000000000000000000000000000000000000016": "0x00000000000000000000000000000000000000000000081f158e2814b4ab624c", - "0x7ffc832d0c7f56b16d03bf3ff14bc4dd6a6cb1ec75841f7397362f4a9be4d392": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xaccfa2662c944e8eae80b7720d9d232eb6809c18f6c8da65189acbb38069d869": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x630a0cd35d5bd57e61410fda76fea850225cda18": { - "balance": "0x0", - "code": "0x6060604052361561006c5760e060020a60003504630121b93f81146100e15780636637b882146101615780636dbf2fa0146101935780638da5cb5b1461026a578063a6f9dae11461027c578063beabacc8146102ae578063d979f5aa14610322578063e1fa763814610354575b61050b600060006000600460005054111561051d576004805460001901905560015460035460055460e260020a6320998771026060908152606492909252600160a060020a03908116608452909116906382661dc49060a49060209060448187876161da5a03f11561000257506105c3915050565b6105cb60043560005433600160a060020a039081169116141561015e57600180547fc9d27afe0000000000000000000000000000000000000000000000000000000060609081526064849052608492909252600160a060020a03169063c9d27afe9060a4906020906044816000876161da5a03f115610002575050505b50565b6105cb60043560005433600160a060020a039081169116141561015e5760018054600160a060020a0319168217905550565b60806020604435600481810135601f8101849004909302840160405260608381526105cb9482359460248035956064949391019190819083828082843750949650505050505050600054600160a060020a039081163390911614156102655782600160a060020a03168282604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561024b5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f1505050505b505050565b6105cd600054600160a060020a031681565b6105cb60043560005433600160a060020a039081169116141561015e5760008054600160a060020a0319168217905550565b6105cb6004356024356044356000805433600160a060020a039081169116141561031c5760e060020a63a9059cbb026060908152600160a060020a03848116606452608484905285929083169163a9059cbb9160a4916020916044908290876161da5a03f115610002575050505b50505050565b6105cb60043560005433600160a060020a039081169116141561015e5760028054600160a060020a0319168217905550565b6105cb60043560243560005433600160a060020a03908116911614156105075760015460e060020a6370a0823102606090815230600160a060020a0390811660645291909116906370a08231906084906020906024816000876161da5a03f1156100025750506040805180516006556002546001547f1a695230000000000000000000000000000000000000000000000000000000008352600160a060020a039081166004840152925192169250631a695230916024828101926000929190829003018183876161da5a03f1156100025750505060048181556003839055600154604080517f013cf08b00000000000000000000000000000000000000000000000000000000815292830185905251600160a060020a03919091169163013cf08b91602482810192602092919082900301816000876161da5a03f11561000257505060408051805160058054600160a060020a0319169091179081905560015460035460e260020a63209987710284526004840152600160a060020a0391821660248401529251921692506382661dc491604482810192602092919082900301816000876161da5a03f115610002575050505b5050565b60408051918252519081900360200190f35b60015460e060020a6370a0823102606090815230600160a060020a0390811660645291909116906370a082319060849060209060248187876161da5a03f11561000257505060408051805160015460025460e060020a63a9059cbb028452600160a060020a039081166004850152602484018390529351919550909216925063a9059cbb916044828101926020929190829003018188876161da5a03f115610002575050505b600191505090565b005b6060908152602090f3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000e6002189a74b43e6868b20c1311bc108e38aac57", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c189413", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000006e073c0e1bd5af550239025dffcfb37175acedd3", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x6e073c0e1bd5af550239025dffcfb37175acedd3": { - "balance": "0x0", - "code": "0x606060405260e060020a60003504631a69523081146100475780636dbf2fa01461006d5780638da5cb5b14610144578063a6f9dae114610156578063beabacc814610196575b005b610045600435600080548190819032600160a060020a0390811691161461022957610002565b60806020604435600481810135601f8101849004909302840160405260608381526100459482359460248035956064949391019190819083828082843750949650505050505050600054600160a060020a0390811633909116141561013f5782600160a060020a03168282604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156101255780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f1505050505b505050565b61021f600054600160a060020a031681565b61004560043560005433600160a060020a0390811691161415610193576000805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b6100456004356024356044356000805433600160a060020a0390811691161415610343577fa9059cbb000000000000000000000000000000000000000000000000000000006060908152600160a060020a03808516606452608484905285929083169163a9059cbb9160a4916020916044908290876161da5a03f1156100025750505050505050565b6060908152602090f35b7f70a0823100000000000000000000000000000000000000000000000000000000606090815230600160a060020a039081166064528594508416906370a082319060849060209060248187876161da5a03f1156100025750506040805180517f18160ddd00000000000000000000000000000000000000000000000000000000825291519194506318160ddd916004828101926020929190829003018187876161da5a03f11561000257505050604051805190602001509050808211156102ee579050805b82600160a060020a031663a9059cbb33846040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050505b5050505056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000e6002189a74b43e6868b20c1311bc108e38aac57" - } - }, - "0xbb9bc244d798123fde783fcc1c72d3bb8c189413": { - "balance": "0x53d2c8df046dd3db5", - "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", - "nonce": "3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000120", - "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057495e10", - "0x0000000000000000000000000000000000000000000000000000000000000011": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000016": "0x000000000000000000000000000000000000000000098b4d3b425f8c368391b2", - "0x29066f14bd0b438bb3db8771a65febf0be7574be7528f87e7ae11aafc2b2c3ac": "0x000000000000000000000000000000000000000000000025d57ab057892050fc", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f443": "0x000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f444": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f445": "0x0000000000000000000000000000000000000000000000000000000000000093", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f446": "0x00000000000000000000000000000000000000000000000000000000579a07ea", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f447": "0x0000000000000000000000000000000000000000000000000000000000000101", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f448": "0x63c103e1feea47a9bf6c0dce1349da1a95b96532661d43063ab8e52b3e2a844b", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f449": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44a": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44b": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44c": "0x00000000000000000000000000000000000000000000000001620725a3de2009", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f44d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3f450": "0x000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650", - "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb060": "0x00000000000000000000000000000000000000000000081f2acc2a62590de041", - "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb061": "0x000000000000000000000000000000000000000000098b4d3b425f8c368391b2", - "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb062": "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", - "0x3987ba2457a57cc6778cce06d8c58970029977d834f0de345c7a495612cbb063": "0x00000000000000000000000010abb5efecdc09581f8b7cb95791fe2936790b4e", - "0x6f125332c6f598e8798f0c277f4b1052ac80cd02ff2eebe0c7f362d63b6959ef": "0x000000000000000000000000000000000000000000000000008dc9007b27b5a9", - "0x793bebaf0ea12c858c08547e9aa88b849bba94bb6933c7bdb0fecbb707ecf5c7": "0x00000000000000000000000000000000000000000000076d52eebfbfbfc172e5", - "0xaccfa2662c944e8eae80b7720d9d232eb6809c18f6c8da65189acbb38069d869": "0x000000000000000000000000000000000000000000000000000289739e60e3e2", - "0xb6e4d5c52e0c64fb49c5a97cacdbcf8bd94b5bd4d490590326a19d27eaf543ae": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xbe273e24e8bd646e29d1fb5a924a12a8585095b9f45a317fc708165a127fdd70": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xc34fc4bc1a730d3f836c9ac5124865056e88f3776b63662e34976bdb47549077": "0x000000000000000000000000000000000000000000000036353be4c563784a57", - "0xe2112d92b8a1d00a569b85fbe7a384a5c9f74f5ff8478647397cb58dde254ffa": "0x53706c697420666f722070656f706c652077686f2073656e74206d6f6e657920", - "0xe2112d92b8a1d00a569b85fbe7a384a5c9f74f5ff8478647397cb58dde254ffb": "0x746f207468652044414f20616674657220746865204861726420466f726b2062", - "0xe2112d92b8a1d00a569b85fbe7a384a5c9f74f5ff8478647397cb58dde254ffc": "0x79206d697374616b650000000000000000000000000000000000000000000000", - "0xf60322aa1a2e769d412b36e4a9def4300f7540bf1bc9e0f4691786a9100145fa": "0x0000000000000000000000000000000000000000000000000000000062188dd2", - "0xf735edeea40e4ec771f49da7f7b854b398a1ad43f8a9617d43e53d3093e9fdc0": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xf7905fa5d54027d5d59f4678dda481331babad2d3d0fdefd552afbce2e74c07e": "0x0000000000000000000000000000000000000000000000000000000000000110" - } - }, - "0xe6002189a74b43e6868b20c1311bc108e38aac57": { - "balance": "0x29129264d1ae4848b", - "nonce": "45" - }, - "0xea674fdde714fd979de3edf0f56aa9716b898ec8": { - "balance": "0x1601bbe4c58ec73210", - "nonce": "337736" - }, - "0xfde8d5f77ef48bb7bf5766c7404691b9ee1dfca7": { - "balance": "0x0", - "code": "0x606060405236156100405760e060020a60003504630221038a811461004d57806318bdc79a146100aa5780638da5cb5b146100be578063d2cc718f146100d0575b6100d96001805434019055565b6100db6004356024356000805433600160a060020a0390811691161415806100755750600034115b806100a05750805460a060020a900460ff1680156100a057508054600160a060020a03848116911614155b156100f757610002565b6100db60005460ff60a060020a9091041681565b6100ed600054600160a060020a031681565b6100db60015481565b005b60408051918252519081900360200190f35b6060908152602090f35b600160a060020a0383168260608381818185876185025a03f1925050501561015c57604080518381529051600160a060020a038516917f9735b0cb909f3d21d5c16bbcccd272d85fa11446f6d679f6ecb170d2dabfecfc919081900360200190a25060015b9291505056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "1968180", - "difficulty": "56311715252709", - "timestamp": "1469713694", - "gasLimit": "4712388", - "miner": "0xea674fdde714fd979de3edf0f56aa9716b898ec8" - }, - "input": "0xf8aa2d850c2b6f9f7e830aae6094630a0cd35d5bd57e61410fda76fea850225cda1880b844e1fa7638000000000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000000000000001ba0563f81ca66b2c618bf4be9470fab88fff1b44eb5c33a9c73a68e8b26fbaa7c8da041464789c49fee77d2e053ff0705bc845fe2a78a35e478132371f294bb594021", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0xe6002189a74b43e6868b20c1311bc108e38aac57", - "gas": "0xaae60", - "gasUsed": "0xaae60", - "to": "0x630a0cd35d5bd57e61410fda76fea850225cda18", - "input": "0xe1fa763800000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000000", - "error": "invalid jump destination", - "calls": [ - { - "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18", - "gas": "0x9f5a0", - "gasUsed": "0x314", - "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "input": "0x70a08231000000000000000000000000630a0cd35d5bd57e61410fda76fea850225cda18", - "output": "0x000000000000000000000000000000000000000000000000000289739e60e3e2", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18", - "gas": "0x9a327", - "gasUsed": "0x67b0", - "to": "0x6e073c0e1bd5af550239025dffcfb37175acedd3", - "input": "0x1a695230000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c189413", - "calls": [ - { - "from": "0x6e073c0e1bd5af550239025dffcfb37175acedd3", - "gas": "0x93ff6", - "gasUsed": "0x314", - "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "input": "0x70a082310000000000000000000000006e073c0e1bd5af550239025dffcfb37175acedd3", - "output": "0x000000000000000000000000000000000000000000000025d57ab057892050fc", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e073c0e1bd5af550239025dffcfb37175acedd3", - "gas": "0x93c42", - "gasUsed": "0x13f", - "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "input": "0x18160ddd", - "output": "0x000000000000000000000000000000000000000000098b4d3b425f8c368391b2", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x6e073c0e1bd5af550239025dffcfb37175acedd3", - "gas": "0x939ba", - "gasUsed": "0x5fca", - "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "input": "0xa9059cbb000000000000000000000000630a0cd35d5bd57e61410fda76fea850225cda18000000000000000000000000000000000000000000000025d57ab057892050fc", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18", - "gas": "0x8d8b6", - "gasUsed": "0x7be", - "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "input": "0x013cf08b0000000000000000000000000000000000000000000000000000000000000110", - "output": "0x000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000579a07ea0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000163c103e1feea47a9bf6c0dce1349da1a95b96532661d43063ab8e52b3e2a844b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000001620725a3de20090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650000000000000000000000000000000000000000000000000000000000000004953706c697420666f722070656f706c652077686f2073656e74206d6f6e657920746f207468652044414f20616674657220746865204861726420466f726b206279206d697374616b650000000000000000000000000000000000000000000000", - "value": "0x0", - "type": "CALL" - }, - { - "from": "0x630a0cd35d5bd57e61410fda76fea850225cda18", - "gas": "0x880f8", - "gasUsed": "0x880f8", - "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "input": "0x82661dc40000000000000000000000000000000000000000000000000000000000000110000000000000000000000000b3b10eff47b9c0b3e5579bf1c25872111667e650", - "error": "invalid jump destination", - "calls": [ - { - "from": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "gas": "0x7f910", - "gasUsed": "0xd20f", - "to": "0x10abb5efecdc09581f8b7cb95791fe2936790b4e", - "input": "0xbaac5300000000000000000000000000630a0cd35d5bd57e61410fda76fea850225cda18", - "output": "0x0000000000000000000000000000000000000000000000000000000000000001", - "calls": [ - { - "from": "0x10abb5efecdc09581f8b7cb95791fe2936790b4e", - "gas": "0x76e12", - "gasUsed": "0x13f9", - "to": "0xfde8d5f77ef48bb7bf5766c7404691b9ee1dfca7", - "input": "0x", - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x20320625e3126cb0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - } - ], - "value": "0x0", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json deleted file mode 100644 index 6faf898a0f..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/tx_partial_failed.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "genesis": { - "difficulty": "45372803248884", - "extraData": "0x65746865726d696e652e6f7267202855533129", - "gasLimit": "4712388", - "hash": "0xa2b18cc64ec062676680f2bb2d880205dcd372f4396722f2294d3fceece96193", - "miner": "0xea674fdde714fd979de3edf0f56aa9716b898ec8", - "mixHash": "0xce7c26a9238b249edcdcd51f0ea1ad0e632e872daf9a09f039d918bcaeb7194f", - "nonce": "0x849d49e634e93bb5", - "number": "1646451", - "stateRoot": "0x2bd193b9911caf43204960cc7661ce864bf0bac7f9b60191aa02bbff24f061fb", - "timestamp": "1465103859", - "totalDifficulty": "24813742796574158431", - "alloc": { - "0x01115b41bd2731353dd3e6abf44818fdc035aaf1": { - "balance": "0x16d99e16e809000", - "nonce": "23" - }, - "0x61c808d82a3ac53231750dadc13c777b59310bd9": { - "balance": "0x6a636960e34bd696f4", - "nonce": "36888" - }, - "0xbb9bc244d798123fde783fcc1c72d3bb8c189413": { - "balance": "0x9b37460cdbcba74181f81", - "code": "0x6060604052361561020e5760e060020a6000350463013cf08b8114610247578063095ea7b3146102d05780630c3b7b96146103455780630e7082031461034e578063149acf9a1461036057806318160ddd146103725780631f2dc5ef1461037b57806321b5b8dd1461039b578063237e9492146103ad57806323b872dd1461040e5780632632bf2014610441578063341458081461047257806339d1f9081461047b5780634b6753bc146104935780634df6d6cc1461049c5780634e10c3ee146104b7578063590e1ae3146104ca578063612e45a3146104db578063643f7cdd1461057a578063674ed066146105925780636837ff1e1461059b57806370a08231146105e5578063749f98891461060b57806378524b2e1461062457806381f03fcb1461067e57806382661dc41461069657806382bf6464146106b75780638b15a605146106c95780638d7af473146106d257806396d7f3f5146106e1578063a1da2fb9146106ea578063a3912ec814610704578063a9059cbb1461070f578063b7bc2c841461073f578063baac53001461074b578063be7c29c1146107b1578063c9d27afe14610817578063cc9ae3f61461082d578063cdef91d014610841578063dbde198814610859578063dd62ed3e1461087e578063e33734fd146108b2578063e5962195146108c6578063e66f53b7146108de578063eceb2945146108f0578063f8c80d261461094f575b610966600f546000906234bc000142108015610239575060125433600160a060020a03908116911614155b156109785761098033610752565b6109866004356000805482908110156100025750808052600e8202600080516020612a3683398151915201905060038101546004820154600683015460018401548454600786015460058701546009880154600a890154600d8a0154600160a060020a039586169b509599600201989760ff81811698610100909204811697949691951693168c565b61096660043560243533600160a060020a03908116600081815260156020908152604080832094871680845294825280832086905580518681529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060015b92915050565b61096660105481565b610a7d600754600160a060020a031681565b610a7d600e54600160a060020a031681565b61096660165481565b6109665b60004262127500600f60005054031115610de557506014610983565b610a7d601254600160a060020a031681565b60408051602060248035600481810135601f810185900485028601850190965285855261096695813595919460449492939092019181908401838280828437509496505050505050506000600060006000600060003411156116a857610002565b6109666004356024356044355b60115460009060ff1680156104315750600f5442115b80156124e957506124e78461044b565b6109666000610980335b600160a060020a0381166000908152600b602052604081205481908114156129cb57610b99565b61096660065481565b6109665b600d5430600160a060020a03163103610983565b610966600f5481565b61096660043560046020526000908152604090205460ff1681565b61096660043560243560006124cb610831565b610a9a6000341115610ba457610002565b604080516020604435600481810135601f8101849004840285018401909552848452610966948135946024803595939460649492939101918190840183828082843750506040805160209735808a0135601f81018a90048a0283018a01909352828252969897608497919650602491909101945090925082915084018382808284375094965050933593505060a435915050600060006110c1336105ec565b61096660043560096020526000908152604090205481565b61096660015481565b610a9a60043530600160a060020a031633600160a060020a03161415806105db5750600160a060020a03811660009081526004602052604090205460ff16155b156121cb576121c8565b6109666004355b600160a060020a0381166000908152601460205260409020545b919050565b6109666004356024356000600034111561259957610002565b610966600062e6b680420360026000505410806106505750600354600160a060020a0390811633909116145b80156106645750600254621274ff19420190105b156126145750426002908155600180549091028155610983565b610966600435600a6020526000908152604090205481565b610966600435602435600060006000600060006000341115611ba157610002565b610a7d600854600160a060020a031681565b610966600c5481565b61096660005460001901610983565b61096660025481565b61096660043560006000600060003411156121fc57610002565b6109665b6001610983565b6109666004356024355b60115460009060ff16801561072f5750600f5442115b801561248757506124853361044b565b61096660115460ff1681565b6109666004355b60006000600f600050544210801561076a5750600034115b80156107a457506011546101009004600160a060020a0316600014806107a457506011546101009004600160a060020a0390811633909116145b15610b9f57610a9c61037f565b610a7d600435600060006000508281548110156100025750508080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56b600e83020180548290811015610002575081526020902060030154600160a060020a0316610606565b61096660043560243560006000610e1b336105ec565b6109665b6000600034111561247c57610002565b61096660043560056020526000908152604090205481565b610966600435602435604435600061252f845b6000600060003411156127ac57610002565b610966600435602435600160a060020a0382811660009081526015602090815260408083209385168352929052205461033f565b610a9a600435600034111561254557610002565b610966600435600b6020526000908152604090205481565b610a7d600354600160a060020a031681565b604080516020606435600481810135601f81018490048402850184019095528484526109669481359460248035956044359560849492019190819084018382808284375094965050505050505060006000600034111561103257610002565b610a7d6011546101009004600160a060020a031681565b60408051918252519081900360200190f35b610980610708565b90505b90565b604051808d600160a060020a031681526020018c8152602001806020018b81526020018a815260200189815260200188815260200187815260200186815260200185815260200184815260200183600160a060020a0316815260200182810382528c818154600181600116156101000203166002900481526020019150805460018160011615610100020316600290048015610a635780601f10610a3857610100808354040283529160200191610a63565b820191906000526020600020905b815481529060010190602001808311610a4657829003601f168201915b50509d505050505050505050505050505060405180910390f35b60408051600160a060020a03929092168252519081900360200190f35b005b604051601254601434908102939093049350600160a060020a03169183900390600081818185876185025a03f150505050600160a060020a038316600081815260146020908152604080832080548601905560168054860190556013825291829020805434019055815184815291517fdbccb92686efceafb9bb7e0394df7f58f71b954061b81afb57109bf247d3d75a9281900390910190a260105460165410801590610b4c575060115460ff16155b15610b94576011805460ff1916600117905560165460408051918252517ff381a3e2428fdda36615919e8d9c35878d9eb0cf85ac6edf575088e80e4c147e9181900360200190a15b600191505b50919050565b610002565b600f5442118015610bb8575060115460ff16155b15610de357601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040516012549051600160a060020a039190911631109050610cc9576040805160125460e060020a63d2cc718f0282529151600160a060020a039290921691630221038a913091849163d2cc718f91600482810192602092919082900301816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a039490941660048201526024810193909352516044838101936020935082900301816000876161da5a03f115610002575050505b33600160a060020a0316600081815260136020526040808220549051909181818185876185025a03f19250505015610de35733600160a060020a03167fbb28353e4598c3b9199101a66e0989549b659a59a54d2c27fbb183f1932c8e6d6013600050600033600160a060020a03168152602001908152602001600020600050546040518082815260200191505060405180910390a26014600050600033600160a060020a0316815260200190815260200160002060005054601660008282825054039250508190555060006014600050600033600160a060020a031681526020019081526020016000206000508190555060006013600050600033600160a060020a03168152602001908152602001600020600050819055505b565b4262054600600f60005054031115610e13576201518062127500600f60005054034203046014019050610983565b50601e610983565b60001415610e2857610002565b6000341115610e3657610002565b6000805485908110156100025750600160a060020a03331681527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56e600e8602908101602052604090912054600080516020612a3683398151915291909101915060ff1680610eb05750600c810160205260406000205460ff165b80610ebf575060038101544210155b15610ec957610002565b8215610f0f5733600160a060020a03166000908152601460209081526040808320546009850180549091019055600b84019091529020805460ff19166001179055610f4b565b33600160a060020a0316600090815260146020908152604080832054600a850180549091019055600c84019091529020805460ff191660011790555b33600160a060020a03166000908152600b60205260408120541415610f77576040600020849055610feb565b33600160a060020a03166000908152600b60205260408120548154811015610002579080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566600e909102015460038201541115610feb5733600160a060020a03166000908152600b602052604090208490555b60408051848152905133600160a060020a03169186917f86abfce99b7dd908bec0169288797f85049ec73cbe046ed9de818fab3a497ae09181900360200190a35092915050565b6000805487908110156100025750808052600e8702600080516020612a3683398151915201905090508484846040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020816005016000505414915050949350505050565b600014156110ce57610002565b82801561111857508660001415806110e857508451600014155b806111005750600354600160a060020a038981169116145b8061110b5750600034115b80611118575062093a8084105b1561112257610002565b8215801561114257506111348861115c565b158061114257506212750084105b156111fe57610002565b83546118e590600160a060020a03165b600160a060020a03811660009081526004602052604081205460ff16806111f15750601254600160a060020a039081169083161480156111f15750601260009054906101000a9004600160a060020a0316600160a060020a031663d2cc718f6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610002575050604051516006541190505b156129a157506001610606565b6249d40084111561120e57610002565b60115460ff1615806112215750600f5442105b806112365750600c5434108015611236575082155b1561124057610002565b42844201101561124f57610002565b30600160a060020a031633600160a060020a0316141561126e57610002565b60008054600181018083559091908280158290116112a557600e0281600e0283600052602060002091820191016112a5919061136a565b505060008054929450918491508110156100025750808052600e8302600080516020612a368339815191520190508054600160a060020a031916891781556001818101899055875160028084018054600082815260209081902096975091959481161561010002600019011691909104601f908101829004840193918b019083901061146257805160ff19168380011785555b5061149292915061144a565b5050600060098201819055600a820155600d81018054600160a060020a03191690556001015b8082111561145e578054600160a060020a03191681556000600182810182905560028084018054848255909281161561010002600019011604601f81901061143057505b506000600383018190556004808401805461ffff19169055600584018290556006840182905560078401805460ff191690556008840180548382559083526020909220611344929091028101905b8082111561145e57600080825560018201818155600283019190915560039091018054600160a060020a03191690556113fc565b601f0160209004906000526020600020908101906113ae91905b8082111561145e576000815560010161144a565b5090565b82800160010185558215611338579182015b82811115611338578251826000505591602001919060010190611474565b50508787866040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f150905001935050505060405180910390208160050160005081905550834201816003016000508190555060018160040160006101000a81548160ff02191690830217905550828160070160006101000a81548160ff02191690830217905550821561157857600881018054600181018083559091908280158290116115735760040281600402836000526020600020918201910161157391906113fc565b505050505b600d8082018054600160a060020a031916331790553460068301819055815401905560408051600160a060020a038a16815260208181018a9052918101859052608060608201818152895191830191909152885185937f5790de2c279e58269b93b12828f56fd5f2bc8ad15e61ce08572585c81a38756f938d938d938a938e93929160a084019185810191908190849082908590600090600490601f850104600f02600301f150905090810190601f1680156116485780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a2509695505050505050565b6040805186815260208101839052815189927fdfc78bdca8e3e0b18c16c5c99323c6cb9eb5e00afde190b4e7273f5158702b07928290030190a25b5050505092915050565b6000805488908110156100025750808052600e8802600080516020612a36833981519152019050600781015490945060ff166116e757620d2f006116ec565b622398805b600485015490935060ff16801561170857506003840154830142115b15611716576117b887611890565b600384015442108061172d5750600484015460ff16155b806117ae57508360000160009054906101000a9004600160a060020a03168460010160005054876040518084600160a060020a0316606060020a0281526014018381526020018280519060200190808383829060006004602084601f0104600f02600301f15090500193505050506040518091039020846005016000505414155b1561114c57610002565b61169e565b60048401805461ff001916610100179055835460019550600160a060020a03908116309091161480159061180157508354600754600160a060020a03908116911614155b801561181d57506008548454600160a060020a03908116911614155b801561183957508354601254600160a060020a03908116911614155b801561185557506003548454600160a060020a03908116911614155b1561188b5760018401805430600160a060020a031660009081526005602052604090208054919091019055546006805490910190555b611663875b6000600060005082815481101561000257908052600e02600080516020612a36833981519152018150600481015490915060ff16156118d757600d80546006830154900390555b600401805460ff1916905550565b15156118f45761190087611890565b6001915061193161047f565b604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050505061169e565b6001850154111561194157600091505b50600a8301546009840154865191019060049010801590611986575085600081518110156100025790602001015160f860020a900460f860020a02606860f860020a02145b80156119b6575085600181518110156100025790602001015160f860020a900460f860020a02603760f860020a02145b80156119e6575085600281518110156100025790602001015160f860020a900460f860020a0260ff60f860020a02145b8015611a16575085600381518110156100025790602001015160f860020a900460f860020a02601e60f860020a02145b8015611a45575030600160a060020a0316600090815260056020526040902054611a4290611a5d61047f565b81105b15611a4f57600091505b6001840154611a8090611a5f565b015b30600160a060020a03166000908152600560205260408120546129a961047f565b8110611ad457604051600d8501546006860154600160a060020a0391909116916000919082818181858883f193505050501515611abc57610002565b4260025560165460059004811115611ad45760056001555b6001840154611ae290611a5f565b8110158015611af85750600a8401546009850154115b8015611b015750815b1561188b578360000160009054906101000a9004600160a060020a0316600160a060020a0316846001016000505487604051808280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611b7d5780820380516001836020036101000a031916815260200191505b5091505060006040518083038185876185025a03f19250505015156117bd57610002565b611baa336105ec565b60001415611bb757610002565b60008054889081101561000257508052600e87027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e566810154600080516020612a36833981519152919091019450421080611c1957506003840154622398800142115b80611c3257508354600160a060020a0390811690871614155b80611c425750600784015460ff16155b80611c68575033600160a060020a03166000908152600b8501602052604090205460ff16155b80611c9c575033600160a060020a03166000908152600b60205260409020548714801590611c9c5750604060009081205414155b15611ca657610002565b600884018054600090811015610002579081526020812060030154600160a060020a03161415611e1257611efc86604051600090600160a060020a038316907f9046fefd66f538ab35263248a44217dcb70e2eb2cd136629e141b8b8f9f03b60908390a260408051600e547fe2faf044000000000000000000000000000000000000000000000000000000008252600160a060020a03858116600484015260248301859052604483018590526223988042016064840152925192169163e2faf04491608480820192602092909190829003018187876161da5a03f1156100025750506040515191506106069050565b6008850180546000908110156100025781815260208082209390935530600160a060020a031681526005909252604082205481549092908110156100025790815260208120905060020155601654600885018054600090811015610002579081526020812090506001015560048401805461ff0019166101001790555b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090505433600160a060020a031660009081526014602052604081205460088801805493909102939093049550908110156100025790815260208120905060030154604080517fbaac530000000000000000000000000000000000000000000000000000000000815233600160a060020a0390811660048301529151929091169163baac53009186916024808301926020929190829003018185886185025a03f11561000257505060405151600014159150611f78905057610002565b60088501805460009081101561000257818152602081206003018054600160a060020a03191690931790925580549091908110156100025790815260208120905060030154600160a060020a031660001415611f5757610002565b600d5430600160a060020a0316311015611f7057610002565b611d9561047f565b6008840180546000908110156100025781548282526020822060010154929190811015610002579081526020812090506002015433600160a060020a0390811660009081526014602090815260408083205430909416835260058083528184205460099093529083205460088b018054969095029690960497509487020494508593929091908290811015610002575260208120815060030154600160a060020a0390811682526020828101939093526040918201600090812080549095019094553016835260059091529020548290101561205357610002565b30600160a060020a031660009081526005602052604081208054849003905560088501805483926009929091829081101561000257508152602080822060030154600160a060020a039081168352929052604080822080549094019093553090911681522054819010156120c657610002565b30600160a060020a0390811660009081526009602090815260408083208054869003905533909316808352601482528383205484519081529351929390927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929181900390910190a36121383361086c565b5033600160a060020a03166000908152601460209081526040808320805460168054919091039055839055600a9091528120556001945061169e565b30600160a060020a0390811660008181526005602090815260408083208054958716808552828520805490970190965584845283905560099091528082208054948352908220805490940190935590815290555b50565b604051600160a060020a0382811691309091163190600081818185876185025a03f192505050151561217457610002565b33600160a060020a03818116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f028352935197995091969195929092169363d2cc718f936004848101949193929183900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a03168152602001908152602001600020600050540204101561229d57610002565b600160a060020a03338116600090815260096020908152604080832054815160065460085460e060020a63d2cc718f02835293519296909593169363d2cc718f93600483810194929383900301908290876161da5a03f11561000257505050604051805190602001506005600050600033600160a060020a0316815260200190815260200160002060005054020403905083156123ec57600860009054906101000a9004600160a060020a0316600160a060020a0316630221038a83600160a060020a0316630e7082036040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060408051805160e160020a63011081c5028252600160a060020a031660048201526024810186905290516044808301935060209282900301816000876161da5a03f115610002575050604051511515905061245457610002565b6040805160085460e160020a63011081c5028252600160a060020a038581166004840152602483018590529251921691630221038a9160448082019260209290919082900301816000876161da5a03f115610002575050604051511515905061245457610002565b600160a060020a03331660009081526009602052604090208054909101905550600192915050565b6109803361086c565b155b80156124a257506124a23384845b6000600061293a856105ec565b80156124be57506124be83836000600034111561261c57610002565b15610b9f5750600161033f565b15156124d657610002565b6124e08383610719565b905061033f565b155b80156124fb57506124fb848484612495565b80156125185750612518848484600060003411156126c157610002565b15610b9f57506001612528565b90505b9392505050565b151561253a57610002565b61252584848461041b565b30600160a060020a031633600160a060020a031614158061258a575030600160a060020a031660009081526005602052604090205460649061258561047f565b010481115b1561259457610002565b600c55565b600354600160a060020a0390811633909116146125b557610002565b600160a060020a038316600081815260046020908152604091829020805460ff191686179055815185815291517f73ad2a153c8b67991df9459024950b318a609782cee8c7eeda47b905f9baa91f9281900390910190a250600161033f565b506000610983565b33600160a060020a03166000908152601460205260409020548290108015906126455750600082115b156126b957600160a060020a03338116600081815260146020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a350600161033f565b50600061033f565b600160a060020a03841660009081526014602052604090205482901080159061270a5750601560209081526040600081812033600160a060020a03168252909252902054829010155b80156127165750600082115b156127a457600160a060020a03838116600081815260146020908152604080832080548801905588851680845281842080548990039055601583528184203390961684529482529182902080548790039055815186815291519293927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3506001612528565b506000612528565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f11561000257505060405151905061281a866105ec565b0204101561282757610002565b600160a060020a038381166000908152600a6020908152604080832054601654600754835160e060020a63d2cc718f02815293519296919591169363d2cc718f9360048181019492939183900301908290876161da5a03f115610002575050604051519050612895866105ec565b0204039050600760009054906101000a9004600160a060020a0316600160a060020a0316630221038a84836040518360e060020a0281526004018083600160a060020a03168152602001828152602001925050506020604051808303816000876161da5a03f115610002575050604051511515905061291357610002565b600160a060020a0383166000908152600a6020526040902080548201905560019150610b99565b600160a060020a0386166000908152600a602052604090205480850291909104915081111561296857610002565b600160a060020a038581166000908152600a60205260408082208054859003905591861681522080548201905560019150509392505050565b506000610606565b0160030260166000505483020460016000505460166000505404019050610606565b600160a060020a0383166000908152600b6020526040812054815481101561000257818052600e02600080516020612a368339815191520190506003810154909150421115610b9457600160a060020a0383166000908152600b602052604081208190559150610b9956290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", - "nonce": "3", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000000f": "0x0000000000000000000000000000000000000000000000000000000057495e10", - "0x0000000000000000000000000000000000000000000000000000000000000012": "0x000000000000000000000000807640a13483f8ac783c557fcdf27be11ea4ac7a" - } - }, - "0xcf1476387d780169410d4e936d75a206fda2a68c": { - "balance": "0x15fd0ad66ea7000", - "code": "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e1461015f5780634123cb6b146101875780635c52c2f5146101905780637065cb48146101ba578063746c9171146101e7578063797af627146101f0578063b20d30a914610203578063b61d27f614610230578063b75c7dc614610251578063ba51a6df14610280578063c2cf7326146102ad578063cbf0b0c0146102eb578063f00d4b5d14610318578063f1736d861461034a575b61035460003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610354600435600060003660405180838380828437820191505092505050604051809103902061064a815b600160a060020a03331660009081526101026020526040812054818082811415610c6657610dbf565b6103566004355b600160a060020a03811660009081526101026020526040812054115b919050565b61035660015481565b61035460003660405180838380828437820191505092505050604051809103902061078b81610136565b6103546004356000366040518083838082843782019150509250505060405180910390206105c681610136565b61035660005481565b6103566004355b600081610a2781610136565b61035460043560003660405180838380828437820191505092505050604051809103902061077f81610136565b6103566004803590602480359160443591820191013560006107aa33610166565b610354600435600160a060020a03331660009081526101026020526040812054908082811415610368576103e7565b61035460043560003660405180838380828437820191505092505050604051809103902061070881610136565b610356600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054828181141561076157610776565b61035460043560003660405180838380828437820191505092505050604051809103902061079981610136565b610354600435602435600060003660405180838380828437820191505092505050604051809103902061047281610136565b6103566101055481565b005b60408051918252519081900360200190f35b50506000828152610103602052604081206001810154600284900a9290831611156103e75780546001828101805492909101835590839003905560408051600160a060020a03331681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b50505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a1505b505050565b156103e75761048083610166565b1561048b575061046d565b600160a060020a0384166000908152610102602052604081205492508214156104b4575061046d565b6103ed5b6101045460005b81811015610f0b57610104805461010891600091849081101561000257600080516020610fd88339815191520154825250602091909152604081208054600160a060020a0319168155600181810183905560028281018054858255939493909281161561010002600019011604601f819010610f9057505b5050506001016104bf565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005055600154600160a060020a03831660008181526101026020908152604091829020939093558051918252517f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3929181900390910190a15b505b50565b156105c1576105d482610166565b156105df57506105c3565b6105e76104b8565b60015460fa90106105fa576105fa61060f565b60015460fa901061054257506105c3565b6106c75b60015b6001548110156105c3575b6001548110801561063d5750600281610100811015610002570154600014155b15610dc75760010161061d565b1561046d57600160a060020a03831660009081526101026020526040812054925082141561067857506105c1565b600160016000505403600060005054111561069357506105c1565b600060028361010081101561000257508301819055600160a060020a0384168152610102602052604081205561060b6104b8565b60408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b156105c15760015482111561071d57506105c3565b600082905561072a6104b8565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001820154600282900a9081166000141593505b50505092915050565b156105c1575061010555565b156105c35760006101065550565b156105c15781600160a060020a0316ff5b156109eb576107be846000610ea133610166565b1561087d577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843782019150509250505060006040518083038185876185025a03f150600093506109eb92505050565b6000364360405180848480828437820191505082815260200193505050506040518091039020905080506108b0816101f7565b1580156108d3575060008181526101086020526040812054600160a060020a0316145b156109eb5760008181526101086020908152604082208054600160a060020a0319168817815560018181018890556002918201805481865294849020909491821615610100026000190190911691909104601f9081019290920481019185919087908390106109f35760ff198135168380011785555b506109659291505b80821115610a235760008155600101610951565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b82800160010185558215610949579182015b82811115610949578235826000505591602001919060010190610a05565b5090565b15610aaa5760008381526101086020526040812054600160a060020a031614610aaa5760408051600091909120805460018281015460029384018054600160a060020a0394909416959194909391928392859291811615610100026000190116048015610adb5780601f10610ab057610100808354040283529160200191610adb565b50919050565b820191906000526020600020905b815481529060010190602001808311610abe57829003601f168201915b505091505060006040518083038185876185025a03f1505050600084815261010860209081526040918290208054600180830154855133600160a060020a0381811683529682018c9052968101829052929094166060830181905260a06080840181815260029586018054948516156101000260001901909416959095049084018190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a97508a95949193919060c083019084908015610bdd5780601f10610bb257610100808354040283529160200191610bdd565b820191906000526020600020905b815481529060010190602001808311610bc057829003601f168201915b5050965050505050505060405180910390a16000838152610108602052604081208054600160a060020a0319168155600181810183905560028281018054858255939493909281161561010002600019011604601f819010610c4857505b5050506001915050610182565b601f016020900490600052602060002090810190610c3b9190610951565b60008581526101036020526040812080549093501415610cee576000805483556001838101919091556101048054918201808255828015829011610cbd57818360005260206000209182019101610cbd9190610951565b50505060028301819055610104805487929081101561000257600091909152600080516020610fd883398151915201555b506001810154600283900a90811660001415610dbf5760408051600160a060020a03331681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1815460019011610dac576000858152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610fd8833981519152929092018190558082556001828101829055600292909201559450610dbf9050565b8154600019018255600182018054821790555b505050919050565b5b60018054118015610dea57506001546002906101008110156100025701546000145b15610dfe5760018054600019019055610dc8565b60015481108015610e215750600154600290610100811015610002570154600014155b8015610e3b57506002816101008110156100025701546000145b15610e9c57600154600290610100811015610002578101549082610100811015610002579090016000505580610102600060028361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b610612565b156101825761010754610eb75b62015180420490565b1115610ed057600061010655610ecb610eae565b610107555b6101065480830110801590610eed57506101055461010654830111155b15610f0357506101068054820190556001610182565b506000610182565b6105c16101045460005b81811015610fae5761010480548290811015610002576000918252600080516020610fd8833981519152015414610f8857610104805461010391600091849081101561000257600080516020610fd883398151915201548252506020919091526040812081815560018101829055600201555b600101610f15565b601f0160209004906000526020600020908101906105379190610951565b610104805460008083559190915261046d90600080516020610fd883398151915290810190610951564c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000105": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000106": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000107": "0x000000000000000000000000000000000000000000000000000000000000423d", - "0xcabd288dcb1ace4f49c34e8ac2d843772952b4226b3c832bdb4ac1ddca0f7c05": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "1646452", - "difficulty": "45328493887096", - "timestamp": "1465103894", - "gasLimit": "4712388", - "miner": "0x61c808d82a3ac53231750dadc13c777b59310bd9" - }, - "input": "0xf9018b178504a817c80083030d4094cf1476387d780169410d4e936d75a206fda2a68c80b90124b61d27f6000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c189413000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000088613930353963626230303030303030303030303030303030303030303030303039306433633138313264653236363962663830376264373735386365623165333439376163376534303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030316336626635323633343030300000000000000000000000000000000000000000000000001ca0f1ae5ea07b1d00eb5e06fc854124ee0234ec61c8b393147f9d030804a75c98daa01d045d7633012cca74e30e975c3d00d11b4243dd8648f2e78d652f3a8aaafceb", - "tracerConfig": { - "withLog": true - }, - "result": { - "from": "0x01115b41bd2731353dd3e6abf44818fdc035aaf1", - "gas": "0x30d40", - "gasUsed": "0x288c9", - "to": "0xcf1476387d780169410d4e936d75a206fda2a68c", - "input": "0xb61d27f6000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c18941300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030000000000000000000000000000000000000000000000000", - "output": "0x0000000000000000000000000000000000000000000000000000000000000000", - "calls": [ - { - "from": "0xcf1476387d780169410d4e936d75a206fda2a68c", - "gas": "0x1e30b", - "gasUsed": "0x1e30b", - "to": "0xbb9bc244d798123fde783fcc1c72d3bb8c189413", - "input": "0x61393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030", - "error": "invalid jump destination", - "value": "0x0", - "type": "CALL" - } - ], - "logs": [ - { - "address": "0xcf1476387d780169410d4e936d75a206fda2a68c", - "topics": [ - "0x92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004" - ], - "data": "0x00000000000000000000000001115b41bd2731353dd3e6abf44818fdc035aaf10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb9bc244d798123fde783fcc1c72d3bb8c1894130000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008861393035396362623030303030303030303030303030303030303030303030303930643363313831326465323636396266383037626437373538636562316533343937616337653430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303031633662663532363334303030", - "position": "0x0" - } - ], - "value": "0x0", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json b/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json deleted file mode 100644 index e73081107f..0000000000 --- a/eth/tracers/internal/tracetest/testdata/call_tracer_withLog/with_onlyTopCall.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "genesis": { - "difficulty": "11934798510088", - "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773", - "gasLimit": "3141592", - "hash": "0xfc543a4a551afbd4a6c5d6d49041371e6bb58b1108c12aaec7f487ce656bb97f", - "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069", - "mixHash": "0xa6a1e67fc68da76b8d9cc3ce1c45d5e1f4bbd96b5dcfddbe0017d7fa99903ead", - "nonce": "0x5f00c600268b4659", - "number": "995200", - "stateRoot": "0x3579328470dd2aef5b9da69f5480cbe0d375e653b530ab3c1aee0da5e1ff4c94", - "timestamp": "1455322761", - "totalDifficulty": "7077231809278509672", - "alloc": { - "0x200edd17f30485a8735878661960cd7a9a95733f": { - "balance": "0x0", - "code": "0x3660008037602060003660003473273930d21e01ee25e4c219b63259d214872220a261235a5a03f21560015760206000f3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000104": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf04": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf05": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x8ba1097eb3abe3dc1b51faa48445d593bf968f722e20b67bb62a87495836bf06": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xa611e7c895a426c0477bc9e280db9c3b1e456dc6310ffcf23926ef5186c1facc": "0x0000000000000000000000000000000000000000000000000000000000000002", - "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410e": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c410f": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xac682d343707aadf06c2c4c3692831d9e7ba711099ef36f9efb8bb29be8c4110": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x273930d21e01ee25e4c219b63259d214872220a2": { - "balance": "0x0", - "code": "0x606060405236156100da5760e060020a6000350463173825d9811461012c5780632f54bf6e146101875780634123cb6b146101af57806352375093146101b857806354fd4d50146101c25780635c52c2f5146101cc578063659010e7146101fd5780637065cb4814610207578063746c91711461023b578063797af62714610244578063b20d30a914610257578063b61d27f61461028b578063b75c7dc6146102ac578063ba51a6df146102db578063c2cf73261461030f578063cbf0b0c01461034d578063f00d4b5d14610381578063f1736d86146103ba575b6103c4600034111561012a5760408051600160a060020a033216815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b6103c46004356000600036436040518084848082843750505090910190815260405190819003602001902090506106c9815b600160a060020a03321660009081526101026020526040812054818082811415610c3f57610d97565b6103c66004355b600160a060020a03811660009081526101026020526040812054115b919050565b6103c660015481565b6103c66101075481565b6103c66101085481565b6103c46000364360405180848480828437505050909101908152604051908190036020019020905061081a8161015e565b6103c66101065481565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506106418161015e565b6103c660005481565b6103c66004355b600081610a7d8161015e565b6103c46004356000364360405180848480828437505050909101908152604051908190036020019020905061080e8161015e565b6103c66004803590602480359160443591820191013560006108393261018e565b6103c4600435600160a060020a033216600090815261010260205260408120549080828114156103d857610457565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506107888161015e565b6103c6600435602435600082815261010360209081526040808320600160a060020a038516845261010290925282205482818114156107e157610805565b6103c4600435600036436040518084848082843750505090910190815260405190819003602001902090506108288161015e565b6103c46004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104e28161015e565b6103c66101055481565b005b60408051918252519081900360200190f35b50506000828152610103602052604081206001810154600284900a9290831611156104575780546001828101805492909101835590839003905560408051600160a060020a03321681526020810186905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b50505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a1505b505050565b15610457576104f08361018e565b156104fb57506104dd565b600160a060020a03841660009081526101026020526040812054925082141561052457506104dd565b61045d5b6101045460005b81811015610ee457610104805461010991600091849081101561000257600080516020610f9f83398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f6992601f9290920104810190610a65565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561063c5761064f8261018e565b1561065a575061063e565b610662610528565b60015460fa90106106775761067561068c565b505b60015460fa90106105a2575061063e565b6107465b600060015b600154811015610a79575b600154811080156106bc5750600281610100811015610002570154600014155b15610d9f5760010161069c565b156104dd57600160a060020a0383166000908152610102602052604081205492508214156106f7575061063c565b6001600160005054036000600050541115610712575061063c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610688610528565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561063c5760015482111561079d575061063e565b60008290556107aa610528565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001820154600282900a908116600014156108005760009350610805565b600193505b50505092915050565b1561063c575061010555565b1561063e5760006101065550565b1561063c5781600160a060020a0316ff5b15610a555761084d846000610e793261018e565b15610909577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00432858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a5592505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061093990508161024b565b15801561095c575060008181526101096020526040812054600160a060020a0316145b15610a555760008181526101096020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a5d579182015b82811115610a5d5782358260005055916020019190600101906109b1565b50507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328132868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b506109cf9291505b80821115610a795760008155600101610a65565b5090565b15610c2c5760008381526101096020526040812054600160a060020a031614610c2c5760408051600091909120805460018201546002929092018054600160a060020a0392909216939091819083908015610afd57820191906000526020600020905b815481529060010190602001808311610ae057829003601f168201915b505091505060006040518083038185876185025a03f150505060008481526101096020908152604080519281902080546001820154600160a060020a033281811688529587018b905293860181905292166060850181905260a06080860181815260029390930180549187018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a975094958a959293909160c083019084908015610bcf57820191906000526020600020905b815481529060010190602001808311610bb257829003601f168201915b5050965050505050505060405180910390a160008381526101096020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c3292601f9290920104810190610a65565b50919050565b50505060019150506101aa565b60008581526101036020526040812080549093501415610cc7576000805483556001838101919091556101048054918201808255828015829011610c9657818360005260206000209182019101610c969190610a65565b50505060028301819055610104805487929081101561000257600091909152600080516020610f9f83398151915201555b506001810154600283900a90811660001415610d975760408051600160a060020a03321681526020810187905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1815460019011610d84576000858152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f9f8339815191529290920181905580825560018083018290556002909201559450610d979050565b8154600019018255600182018054821790555b505050919050565b5b60018054118015610dc257506001546002906101008110156100025701546000145b15610dd65760018054600019019055610da0565b60015481108015610df95750600154600290610100811015610002570154600014155b8015610e1357506002816101008110156100025701546000145b15610e7457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b610691565b156101aa5761010754610e8f5b62015180420490565b1115610ea857600061010655610ea3610e86565b610107555b6101065480830110801590610ec65750610106546101055490830111155b15610edc575061010680548201905560016101aa565b5060006101aa565b61063c6101045460005b81811015610f745761010480548290811015610002576000918252600080516020610f9f833981519152015414610f6157610104805461010391600091849081101561000257600080516020610f9f83398151915201548252506020919091526040812081815560018101829055600201555b600101610eee565b50505060010161052f565b61010480546000808355919091526104dd90600080516020610f9f83398151915290810190610a6556004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe" - }, - "0x4f5777744b500616697cb655dcb02ee6cd51deb5": { - "balance": "0xb0983f1b83eec290", - "nonce": "2" - }, - "0xf8b483dba2c3b7176a3da549ad41a48bb3121069": { - "balance": "0x16969a0ba2c2d384d07", - "nonce": "67521" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "995201", - "difficulty": "11940626048551", - "timestamp": "1455322773", - "gasLimit": "3141592", - "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069" - }, - "input": "0xf89102850a954d522e8303308594200edd17f30485a8735878661960cd7a9a95733f888ac7230489e80000a4ba51a6df00000000000000000000000000000000000000000000000000000000000000001ca04f2cc45b96f965296382b2e9b657e90808301d5179035a5d91a2de7b912def20a056e19271ea4e19e4e034f38e925e312beed4d300c267160eeb2f565c42deb578", - "tracerConfig": { - "withLog": true, - "onlyTopCall": true - }, - "result": { - "from": "0x4f5777744b500616697cb655dcb02ee6cd51deb5", - "gas": "0x33085", - "gasUsed": "0x1a9e5", - "to": "0x200edd17f30485a8735878661960cd7a9a95733f", - "input": "0xba51a6df0000000000000000000000000000000000000000000000000000000000000000", - "output": "0xba51a6df00000000000000000000000000000000000000000000000000000000", - "value": "0x8ac7230489e80000", - "type": "CALL" - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json deleted file mode 100644 index a34d3b759e..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/create_existing_contract.json +++ /dev/null @@ -1,85 +0,0 @@ -{ - "genesis": { - "difficulty": "6217248151198", - "extraData": "0xd783010103844765746887676f312e342e32856c696e7578", - "gasLimit": "3141592", - "hash": "0xe8bff55fe3e61936ef321cf3afaeb1ba2f7234e1e89535fa8ae39963caebe9c3", - "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", - "mixHash": "0x03da00d5a15a064e5ebddf53cd0aaeb9a8aff0f40c0fb031a74f463d11ec83b8", - "nonce": "0x6575fe08c4167044", - "number": "243825", - "stateRoot": "0x47182fe2e6e740b8a76f82fe5c527d6ad548f805274f21792cf4047235b24fbf", - "timestamp": "1442424328", - "totalDifficulty": "1035061827427752845", - "alloc": { - "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { - "balance": "0xc820f93200f4000", - "nonce": "0x5E", - "code": "0x" - }, - "0x332b656504f4eabb44c8617a42af37461a34e9dc": { - "balance": "0x11faea4f35e5af80000", - "code": "0x" - }, - "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { - "balance": "0xbf681825be002ac452", - "nonce": "0x70FA", - "code": "0x" - }, - "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": { - "balance": "0xb3d0ac5cb94df6f6b0", - "nonce": "0x1", - "code": "0x" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "ethash": {} - } - }, - "context": { - "number": "243826", - "difficulty": "6214212385501", - "timestamp": "1442424353", - "gasLimit": "3141592", - "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" - }, - "input": "0xf8e85e850ba43b7400830f42408080b89660606040527382effbaaaf28614e55b2ba440fb198e0e5789b0f600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600a80608c6000396000f30060606040526008565b001ca0340b21661e5bb85a46319a15f33a362e5c0f02faa7cdbf9c5808b2134da968eaa0226e6788f8c20e211d436ab7f6298ef32fa4c23a509eeeaac0880d115c17bc3f", - "result": { - "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { - "balance": "0xc820f93200f4000", - "nonce": 94 - }, - "0x332b656504f4eabb44c8617a42af37461a34e9dc": { - "balance": "0x11faea4f35e5af80000", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { - "balance": "0xbf681825be002ac452", - "nonce": 28922 - }, - "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": { - "balance": "0xb3d0ac5cb94df6f6b0", - "nonce": 1 - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json deleted file mode 100644 index 7204bfcbfe..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "result": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "nonce": 22 - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "nonce": 1, - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "nonce": 29072 - }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json deleted file mode 100644 index 44b1f08dd3..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_legacy/simple.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "result": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": 22, - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": 1, - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": 29072, - "storage": {} - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json deleted file mode 100644 index 1b09622474..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "genesis": { - "difficulty": "13756228101629", - "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773", - "gasLimit": "3141592", - "hash": "0x58b7a87b6ba10b46b4e251d64ebc3d9822dd82218eaf24dff6796f6f1f687251", - "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069", - "mixHash": "0x5984b9a316116bd890e6e5f4c52d655184b0d7aa74821e1382d7760f9803c1dd", - "nonce": "0xea4bb4997242c681", - "number": "1061221", - "stateRoot": "0x5402c04d481414248d824c3b61e924e0c9307adbc9fbaae774a74cce30a4163d", - "timestamp": "1456458069", - "totalDifficulty": "7930751135586064334", - "alloc": { - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x9fb6b81e112638b886", - "nonce": "217865", - "code": "0x" - }, - "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": { - "balance": "0x15b6828e22bb12188", - "nonce": "747", - "code": "0x" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "ethash": {} - } - }, - "context": { - "number": "1061222", - "difficulty": "13749511193633", - "timestamp": "1456458097", - "gasLimit": "3141592", - "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226" - }, - "input": "0xf905498202eb850ba43b7400830f42408080b904f460606040526040516102b43803806102b48339016040526060805160600190602001505b5b33600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b806001600050908051906020019082805482825590600052602060002090601f01602090048101928215609e579182015b82811115609d5782518260005055916020019190600101906081565b5b50905060c5919060a9565b8082111560c1576000818150600090555060010160a9565b5090565b50505b506101dc806100d86000396000f30060606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001ee7b225f6964223a225a473466784a7245323639384866623839222c22666f726d5f736f75726365223a22434c54523031222c22636f6d6d69746d656e745f64617465223a22222c22626f72726f7765725f6e616d65223a22222c22626f72726f7765725f616464726573735f6c696e6531223a22222c22626f72726f7765725f616464726573735f6c696e6532223a22222c22626f72726f7765725f636f6e74616374223a22222c22626f72726f7765725f7374617465223a22222c22626f72726f7765725f74797065223a22222c2270726f70657274795f61646472657373223a22222c226c6f616e5f616d6f756e745f7772697474656e223a22222c226c6f616e5f616d6f756e74223a22222c224c54565f7772697474656e223a22222c224c5456223a22222c2244534352223a22222c2270726f70657274795f74797065223a22222c2270726f70657274795f6465736372697074696f6e223a22222c226c656e646572223a22222c2267756172616e746f7273223a22222c226c696d69746564223a22222c226361705f616d6f756e74223a22222c226361705f70657263656e745f7772697474656e223a22222c226361705f70657263656e74616765223a22222c227465726d5f7772697474656e223a22222c227465726d223a22222c22657874656e64223a22227d0000000000000000000000000000000000001ba027d54712289af34f0ec0f06092745104d68e5801cd17097bc1104111f855258da070ec9f1c942d9bedf89f9660a684d3bb8cd9c2ac7f6dd883cb3e26a193180244", - "tracerConfig": { - "diffMode": true - }, - "result": { - "pre": { - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x9fb6b81e112638b886", - "nonce": 217865 - }, - "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": { - "balance": "0x15b6828e22bb12188", - "nonce": 747 - } - }, - "post": { - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x9fb71abdd2621d8886" - }, - "0x40f2f445da6c9047554683fb382fba6769717116": { - "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f0c5cef39b17c213cfe090a46b8c7760ffb7928a", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000000000000000001ee", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": "0x7b225f6964223a225a473466784a7245323639384866623839222c22666f726d", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7": "0x5f736f75726365223a22434c54523031222c22636f6d6d69746d656e745f6461", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8": "0x7465223a22222c22626f72726f7765725f6e616d65223a22222c22626f72726f", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9": "0x7765725f616464726573735f6c696e6531223a22222c22626f72726f7765725f", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfa": "0x616464726573735f6c696e6532223a22222c22626f72726f7765725f636f6e74", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfb": "0x616374223a22222c22626f72726f7765725f7374617465223a22222c22626f72", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfc": "0x726f7765725f74797065223a22222c2270726f70657274795f61646472657373", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfd": "0x223a22222c226c6f616e5f616d6f756e745f7772697474656e223a22222c226c", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cfe": "0x6f616e5f616d6f756e74223a22222c224c54565f7772697474656e223a22222c", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cff": "0x224c5456223a22222c2244534352223a22222c2270726f70657274795f747970", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d00": "0x65223a22222c2270726f70657274795f6465736372697074696f6e223a22222c", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d01": "0x226c656e646572223a22222c2267756172616e746f7273223a22222c226c696d", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d02": "0x69746564223a22222c226361705f616d6f756e74223a22222c226361705f7065", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d03": "0x7263656e745f7772697474656e223a22222c226361705f70657263656e746167", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d04": "0x65223a22222c227465726d5f7772697474656e223a22222c227465726d223a22", - "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0d05": "0x222c22657874656e64223a22227d000000000000000000000000000000000000" - } - }, - "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": { - "balance": "0x15b058920efcc5188", - "nonce": 748 - } - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json deleted file mode 100644 index d19d3c52e2..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_failed.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "genesis": { - "baseFeePerGas": "51088069741", - "difficulty": "14315558652874667", - "extraData": "0xd883010a10846765746888676f312e31362e35856c696e7578", - "gasLimit": "30058590", - "hash": "0xdf6b95183f99054fb6541e3b482c0109c9f6be40553cff24efa3ac76736adbf5", - "miner": "0xb7e390864a90b7b923c9f9310c6f98aafe43f707", - "mixHash": "0x8d76b0d32e42ab277dbf00836eabef76674cd70ae2bb53718175069ad6b6147e", - "nonce": "0x8d3a1c010ad2c687", - "number": "14707767", - "stateRoot": "0x8a50c896a6f7eb1f3479337db981fa10ce316281cb4dd2f07487be9ca27dae6b", - "timestamp": "1651623275", - "alloc": { - "0x0000000000000000000000000000000000000000": { - "balance": "0x268fd0b894b8c4f6d1f" - }, - "0x13b152c9f50878ffaf3de41e192653bda545d889": { - "balance": "0x0", - "nonce": "1", - "code": "0x363d3d373d3d3d363d73059ffafdc6ef594230de44f824e2bd0a51ca5ded5af43d82803e903d91602b57fd5bf3" - }, - "0x808b4da0be6c9512e948521452227efc619bea52": { - "balance": "0x2cdb96c56db040b43", - "nonce": "1223932" - }, - "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7": { - "balance": "0x38079b28689d40240e", - "nonce": "44" - }, - "0xffa397285ce46fb78c588a9e993286aac68c37cd": { - "balance": "0x0", - "nonce": "747319", - "code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063b97a23191461003b578063fb90b3201461006f575b600080fd5b6100436100bd565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100bb6004803603604081101561008557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506100e1565b005b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008282604051602001808373ffffffffffffffffffffffffffffffffffffffff1660601b815260140182815260200192505050604051602081830303815290604052805190602001209050600061015960008054906101000a900473ffffffffffffffffffffffffffffffffffffffff168361024d565b90508073ffffffffffffffffffffffffffffffffffffffff166319ab453c856040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b1580156101c457600080fd5b505af11580156101d8573d6000803e3d6000fd5b505050507fa35ea2cc726861482a50a162c72aad60965cc64641d419cd4d675036238b52048185604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150505050565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152836037826000f5925050509291505056fea2646970667358221220c87b2492828fdd7dad3175a32a98ff07fc0eedf106536f2eddd9a016971c56a764736f6c63430007050033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000059ffafdc6ef594230de44f824e2bd0a51ca5ded" - } - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "terminalTotalDifficultyPassed": true, - "apricotPhase1BlockTimestamp": 0, - "apricotPhase2BlockTimestamp": 0, - "apricotPhase3BlockTimestamp": 0 - } - }, - "context": { - "number": "14707768", - "difficulty": "14322823549655084", - "timestamp": "1651623279", - "gasLimit": "30029237", - "miner": "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7" - }, - "input": "0x02f8b4018312acfc8459682f00851a46bcf47a8302b1a194ffa397285ce46fb78c588a9e993286aac68c37cd80b844fb90b3200000000000000000000000002a549b4af9ec39b03142da6dc32221fc390b553300000000000000000000000000000000000000000000000000000000000cb3d5c001a03002079d2873f7963c4278200c43aa71efad262b2150bc8524480acfc38b5faaa077d44aa09d56b9cf99443c7f55aaad1bbae9cfb5bbb9de31eaf7a8f9e623e980", - "tracerConfig": { - "diffMode": true - }, - "result": { - "pre": { - "0x808b4da0be6c9512e948521452227efc619bea52": { - "balance": "0x2cdb96c56db040b43", - "nonce": 1223932 - }, - "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7": { - "balance": "0x38079b28689d40240e", - "nonce": 44 - } - }, - "post": { - "0x808b4da0be6c9512e948521452227efc619bea52": { - "balance": "0x2cd987071ba2346b6", - "nonce": 1223933 - }, - "0x8f03f1a3f10c05e7cccf75c1fd10168e06659be7": { - "balance": "0x3807bc244dbe20e89b" - } - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json deleted file mode 100644 index fdeb0e5067..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_suicide.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "genesis": { - "difficulty": "6217248151198", - "extraData": "0xd783010103844765746887676f312e342e32856c696e7578", - "gasLimit": "3141592", - "hash": "0xe8bff55fe3e61936ef321cf3afaeb1ba2f7234e1e89535fa8ae39963caebe9c3", - "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", - "mixHash": "0x03da00d5a15a064e5ebddf53cd0aaeb9a8aff0f40c0fb031a74f463d11ec83b8", - "nonce": "0x6575fe08c4167044", - "number": "243825", - "stateRoot": "0x47182fe2e6e740b8a76f82fe5c527d6ad548f805274f21792cf4047235b24fbf", - "timestamp": "1442424328", - "totalDifficulty": "1035061827427752845", - "alloc": { - "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { - "balance": "0xc820f93200f4000", - "nonce": "0x5E", - "code": "0x" - }, - "0x332b656504f4eabb44c8617a42af37461a34e9dc": { - "balance": "0x11faea4f35e5af80000", - "code": "0x", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { - "balance": "0xbf681825be002ac452", - "nonce": "0x70FA", - "code": "0x" - }, - "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": { - "balance": "0xb3d0ac5cb94df6f6b0", - "nonce": "0x1", - "code": "0x" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "ethash": {} - } - }, - "context": { - "number": "243826", - "difficulty": "6214212385501", - "timestamp": "1442424353", - "gasLimit": "3141592", - "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" - }, - "input": "0xf8e85e850ba43b7400830f42408080b89660606040527382effbaaaf28614e55b2ba440fb198e0e5789b0f600060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b600a80608c6000396000f30060606040526008565b001ca0340b21661e5bb85a46319a15f33a362e5c0f02faa7cdbf9c5808b2134da968eaa0226e6788f8c20e211d436ab7f6298ef32fa4c23a509eeeaac0880d115c17bc3f", - "tracerConfig": { - "diffMode": true - }, - "result": { - "pre": { - "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { - "balance": "0xc820f93200f4000", - "nonce": 94 - }, - "0x332b656504f4eabb44c8617a42af37461a34e9dc": { - "balance": "0x11faea4f35e5af80000", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { - "balance": "0xbf681825be002ac452", - "nonce": 28922 - }, - "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": { - "balance": "0xb3d0ac5cb94df6f6b0", - "nonce": 1 - } - }, - "post": { - "0x082d4cdf07f386ffa9258f52a5c49db4ac321ec6": { - "balance": "0xc7d4d88af8b4c00", - "nonce": 95 - }, - "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5": { - "balance": "0xbf681ce7c870aeb852" - }, - "0x82effbaaaf28614e55b2ba440fb198e0e5789b0f": { - "balance": "0x1d37f515017a8eef6b0" - } - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json deleted file mode 100644 index 9c0030a0a8..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json +++ /dev/null @@ -1,312 +0,0 @@ -{ - "genesis": { - "difficulty": "13707196986889", - "extraData": "0xd983010302844765746887676f312e342e328777696e646f7773", - "gasLimit": "3141592", - "hash": "0x607b38fe7e94427ee8f3b9a62375c67f953f8d49e05dbfd0145f9d3bac142193", - "miner": "0xf8b483dba2c3b7176a3da549ad41a48bb3121069", - "mixHash": "0x98c74c9e76fd0078157e1696e4334a7e787396459693a84536d8b96414dafd5d", - "nonce": "0x77a5a0a73ad8745e", - "number": "1062502", - "stateRoot": "0x1df615df5fdbc8d5397bf3574f462f6d9696428eb8796d8e9252bccc8e3a8996", - "timestamp": "1456480432", - "totalDifficulty": "7948153536501153741", - "alloc": { - "0x0000000000000000000000000000000000000004": { - "balance": "0x0", - "code": "0x" - }, - "0x1deeda36e15ec9e80f3d7414d67a4803ae45fc80": { - "balance": "0x0", - "code": "0x650200d2f18c7350606060405236156100c15760e060020a60003504630bd295e681146100c65780630fd1f94e1461017d5780630fee183d1461018c578063349501b7146101ad5780635054d98a146101c75780637c0278fc146101ef5780637e92656214610287578063a0943154146102f6578063a1873db61461030e578063a9d2293d14610355578063b5d0f16e146103ad578063c17e6817146103ce578063cc3471af1461046a578063da46be0a1461047a578063f55627531461052a575b610007565b6105d36004356024356044355b60006000600030915081600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515191505080841080610173575081600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015060ff16810184115b1561100d57610007565b6105d3600060f0610f6d61046e565b6105d3600435602435604435606435600081600202831015610ff657610fee565b6105d36004355b600081600014156109115750600161098f565b6105d36004355b6008810154600090819062010000900460ff16156105f257600691506105ec565b60408051602060248035600481810135601f81018590048502860185019096528585526105e5958135959194604494929390920191819084018382808284375094965050505050505060006004825103836001016000508181546001816001161561010002031660029004825481601f106108005782601f1061083a575b826008026101000360020a80910402828001178355610851565b6105e5600435602435604051600090600160a060020a038316907f398bd6b21ae4164ec322fb0eb8c2eb6277f36fd41903fbbed594dfe125591281908390a26007830154819010610e415760078301546005840154610e3f9162010000909104600160a060020a0316906103d8565b6105d3600435602435600060006000611064856101ce565b6105d36004356024356044356004830154600090819030908410156110e4577f4e4f545f454e4f5547485f47415300000000000000000000000000000000000091506112dd565b6105d35b60006000309050600a81600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515160091901935050505b5090565b6105d36004356024355b60008282111561099e578183606402049050610998565b6105d36004356024355b600030600160a060020a0316318211156103fa57600160a060020a0330163191505b6000821115610994577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc84846040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100075750839250610998915050565b6105d35b6000600f610f6d610359565b6105e560043560243560443560643560843560088501805461ff00191661010017905584543090600090819081908190819060a060020a900460e060020a02811480156104db575060018b8101546002918116156101000260001901160481145b156109b3578a5460028c0154600160a060020a039190911690895a60405191900391906000818181858888f193505050508b60080160006101000a81548160ff02191690830217905550610bfa565b6105d36004355b6000600060006000309250600a83600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151600919019350505081851115610eb05782600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450610ea89050565b60408051918252519081900360200190f35b005b600291505b50919050565b6008830154610100900460ff161561060d57600591506105ec565b30905080600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515143610109011015905061066457600091506105ec565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515143600a01101590506106d3576005830154620100009004600160a060020a0316600014156105e757600191506105ec565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151431015905061072357600391506105ec565b80600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015060ff1681600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519190910143101590506107bf57600491506105ec565b600791506105ec565b5081800160010183558181151161085157601f016020900481601f016020900483600052602060002091820191016108519190610826565b82601f106107c8575082600052602060002080549082601f016020900481019061090691905b808211156103a95760008155600101610826565b60ff19168360005260206000205581800160010183555b5050505060048251111561090c575060005b6001838101546002918116156101000260001901160481101561090c57818160040181518110156100075790602001015160f860020a900460f860020a02836001016000508281546001816001161561010002031660029004811015610007578154600116156108e25790600052602060002090602091828204019190065b601f036101000a81548160ff0219169060f860020a84040217905550600101610863565b5061026d565b505050565b604080517f5f5f6469672875696e74323536290000000000000000000000000000000000008152815190819003600e01812060e060020a9081900481028190049081028252600019850160048301529151600160a060020a03301692916102bc86029160248281019260009291908290030181838887f19450505050505b919050565b5060005b92915050565b818360020203836064020460c8039050610998565b8a5460a060020a900460e060020a0260001415610a23578a5460028c0154600160a060020a039190911690895a03908d6001016000506040518082805460018160011615610100020316600290048015610ae55780601f10610aba57610100808354040283529160200191610ae5565b60018b8101546002918116156101000260001901160460001415610b1a578a5460028c0154600160a060020a039190911690895a03908d60000160149054906101000a900460e060020a0260e060020a900491906040518360e060020a028152600401809050600060405180830381858988f19450505050508b60080160006101000a81548160ff02191690830217905550610bfa565b820191906000526020600020905b815481529060010190602001808311610ac857829003601f168201915b5050915050600060405180830381858888f193505050508b60080160006101000a81548160ff02191690830217905550610bfa565b8a5460028c0154600160a060020a039190911690895a03908d60000160149054906101000a900460e060020a0260e060020a900491908e6001016000506040518460e060020a0281526004018082805460018160011615610100020316600290048015610bc85780601f10610b9d57610100808354040283529160200191610bc8565b820191906000526020600020905b815481529060010190602001808311610bab57829003601f168201915b5050915050600060405180830381858988f19450505050508b60080160006101000a81548160ff021916908302179055505b85600160a060020a031663938b5f326040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750505060405180519060200150600160a060020a031660405180807f75706461746544656661756c745061796d656e742829000000000000000000008152602001506016019050604051809103902060e060020a8091040260e060020a90046040518160e060020a0281526004018090506000604051808303816000876161da5a03f15050505060038b0154610cc8903a6103b7565b60058c0154909550620100009004600160a060020a03908116908a161415610cf65760068b01549350610d38565b85600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450505b6064858502048b6007016000505401925060648587600160a060020a031663625cc4656040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505050604051805190602001500204915060008b60070160005081905550865a8b03013a029050610db7898285016103d8565b9250610dd773d3cda913deb6f67967b99d67acdfa1712c293601836103d8565b6040805160088e01548482526020820187905281830184905260ff1660608201529051919350600160a060020a038b16917f4538b7ec91dae8fada01e66a052482086d3e690c3db5a80457fbcd55457b4ae19181900360800190a25050505050505050505050565b505b309050610e8c81600160a060020a031663ae45850b6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040515190316103d8565b505050600801805462ff0000191662010000179055565b600093505b505050919050565b600e19919091019081851115610f075782600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051519450610ea89050565b60ef19919091019081851115610ea357818503905060f08184600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050506040518051906020015002049350610ea8565b03905090565b6006860181905560058601805475ffffffffffffffffffffffffffffffffffffffff000019166201000087021790556007860184905560408051600160a060020a0387168152602081019290925280517fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a9281900390910190a15b949350505050565b610f7343610531565b600192505b50509392505050565b60108185031015610fff576005860154620100009004600160a060020a03166000148061105057506005860154620100009004600160a060020a03908116908616145b9250611004565b600092505b505092915050565b91503090506000821480156110c4575080600160a060020a031663ae45850b6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505060405151600160a060020a039081169086161490505b156110d2576001925061105c565b6007821415611057576001925061105c565b6008860154610100900460ff161561111e577f414c52454144595f43414c4c454400000000000000000000000000000000000091506112dd565b80600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f115610007575050604051514310905080611206575080600160a060020a031663a06db7dc6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100075750506040805180517f0a16697a000000000000000000000000000000000000000000000000000000008252915160ff9092169291630a16697a9160048181019260209290919082900301816000876161da5a03f1156100075750506040515191909101431190505b15611233577f4e4f545f494e5f43414c4c5f57494e444f57000000000000000000000000000091506112dd565b61123e8686436100d3565b151561126c577f4e4f545f415554484f52495a454400000000000000000000000000000000000091506112dd565b6005860154600061ffff91909116118015611299575032600160a060020a031685600160a060020a031614155b80156112b4575060058601546112b29061ffff166101b4565b155b156112dd577f535441434b5f544f4f5f4445455000000000000000000000000000000000000091505b60008214610fff5760408051600160a060020a03871681526020810184905281517fdcb278834ca505ad219cf8e4b5d11f026080abef6ec68e249ea5e4d9bb3dc7b2929181900390910190a16000925061100456" - }, - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x98e1c608601c2496b2", - "nonce": "218916", - "code": "0x" - }, - "0x651913977e8140c323997fce5e03c19e0015eebf": { - "balance": "0x0", - "code": "0x", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000e": "0x0000000000000000000000000000000000000000000000000000000000000000" - } - }, - "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": { - "balance": "0x0", - "nonce": "237", - "code": "0x6060604052361561027c5760e060020a600035046301991313811461027e57806303d22885146102ca5780630450991814610323578063049ae734146103705780630ce46c43146103c35780630e85023914610602578063112e39a8146106755780631b4fa6ab146106c25780631e74a2d3146106d057806326a7985a146106fd5780633017fe2414610753578063346cabbc1461075c578063373a1bc3146107d55780633a9e74331461081e5780633c2c21a01461086e5780633d9ce89b146108ba578063480b70bd1461092f578063481078431461097e57806348f0518714610a0e5780634c471cde14610a865780634db3da8314610b09578063523ccfa814610b4f578063586a69fa14610be05780635a9f2def14610c3657806364ee49fe14610caf57806367beaccb14610d055780636840246014610d74578063795b9a6f14610dca5780637b55c8b514610e415780637c73f84614610ee15780638c0e156d14610f145780638c1d01c814610f605780638e46afa914610f69578063938c430714610fc0578063971c803f146111555780639772c982146111ac57806398c9cdf41461122857806398e00e541461127f5780639f927be7146112d5578063a00aede914611383578063a1c0539d146113d3578063aff21c6514611449578063b152f19e14611474578063b549793d146114cb578063b5b33eda1461154b578063bbc6eb1f1461159b578063c0f68859146115ab578063c3a2c0c314611601578063c43d05751461164b578063d8e5c04814611694578063dbfef71014611228578063e29fb547146116e7578063e6470fbe1461173a578063ea27a8811461174c578063ee77fe86146117d1578063f158458c14611851575b005b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387876020604051908101604052806000815260200150612225610f6d565b61188260043560243560443560643560843560a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338b8a6020604051908101604052806000815260200150896125196106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a026020604051908101604052806000815260200150611e4a610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503389896020604051908101604052806000815260200150886124e86106c6565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750506040805160a08082019092529597963596608435969095506101449450925060a491506005908390839080828437509095505050505050604080518082018252600160a060020a03338116825288166020820152815160c0810190925260009173e54d323f9ef17c1f0dede47ecc86a9718fe5ea349163e3042c0f91600191908a908a9089908b90808b8b9090602002015181526020018b60016005811015610002579090602002015181526020018b60026005811015610002579090602002015181526020018b60036005811015610002579090602002015181526020018b6004600581101561000257909060200201518152602001348152602001506040518860e060020a02815260040180888152602001876002602002808383829060006004602084601f0104600f02600301f150905001868152602001806020018560ff1681526020018461ffff168152602001836006602002808383829060006004602084601f0104600f02600301f1509050018281038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038160008760325a03f2156100025750506040515191506124cd9050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808787611e64610f6d565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611d28610f6d565b61189f5b6000611bf8611159565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881600060005054611a9561159f565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346326a7985a6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b760075b90565b604080516020606435600481810135601f8101849004840285018401909552848452611882948135946024803595604435956084949201919081908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160013389898861224b610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386866020604051908101604052806000815260200150611e64610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333896020604051908101604052806000815260200150886123bc6106c6565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387866020604051908101604052806000815260200150611f8d610f6d565b60408051602060248035600481810135601f810185900485028601850190965285855261188295813595919460449492939092019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808888612225610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503388886020604051908101604052806000815260200150612388610f6d565b611882600435604080517fc4144b2600000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163c4144b26916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133888888612238610f6d565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338b8b8b896126536106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333866020604051908101604052806000815260200150611e4a610f6d565b6118b76004355b604080517fed5bd7ea00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163ed5bd7ea916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b61189f600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463586a69fa6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650509335935050606435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808989612388610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a896020604051908101604052806000815260200150886124d76106c6565b6040805160206004803580820135601f8101849004840285018401909552848452611882949193602493909291840191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808587611e4a610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a8a60206040519081016040528060008152602001508961262d6106c6565b604080516020606435600481810135601f810184900484028501840190955284845261188294813594602480359560443595608494920191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338888876120c7610f6d565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437505060408051608080820190925295979635969561010495509350608492508591508390839080828437509095505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989898961263a6106c6565b6118b7600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881858585611ba361122c565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050333388602060405190810160405280600081526020015061236e610f6d565b6118b760005481565b6118c95b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea34638e46afa96040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a43560c43560e43561010435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338e8e8d8f8e8e8e8e8e346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111195780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519b9a5050505050505050505050565b61189f5b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463971c803f6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650509335935050608435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989896123a2610f6d565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398c9cdf46040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152600160048201527f3e3d0000000000000000000000000000000000000000000000000000000000006024820152604481018390529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163e6ce3a6a916064818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a0260206040519081016040528060008152602001506121ef610f6d565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338787876120b5610f6d565b6118b7600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88183611b4561159f565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463b152f19e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808b8b8961262d6106c6565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386600060e060020a026020604051908101604052806000815260200150612200610f6d565b6118b75b60005460649004610759565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611bff610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333876020604051908101604052806000815260200150612200610f6d565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387600060e060020a026020604051908101604052806000815260200150612213610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338a60206040519081016040528060008152602001508961250c6106c6565b61027c6000600060006118e033610b56565b6118b7600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881868686866040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b949350505050565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338a8a8a886124fa6106c6565b6118b7600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88184846000611b4f61122c565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b60408051918252519081900360200190f35b6040805160ff929092168252519081900360200190f35b15611a905733925082600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fc6803622000000000000000000000000000000000000000000000000000000008252915191945063c680362291600482810192602092919082900301816000876161da5a03f11561000257505060405151905080156119d1575082600160a060020a031663d379be236040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a03166000141590505b80156119dd5750600082115b80156119ec5750600054600190115b15611a90578183600160a060020a031663830953ab6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040515160640291909104915050604281118015611a4d5750600054829011155b15611a675760008054612710612711909102049055611a90565b602181108015611a7a5750600054829010155b15611a90576000805461271061270f9091020490555b505050565b6000611a9f61122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b919050565b6000611af261122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b9392505050565b9050610759565b611c076106c6565b6000611c11611478565b611c1961122c565b600054611c2461159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611cf25780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b611d306106c6565b60008b611d3b61122c565b600054611d4661159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611e145780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b409050565b611e526106c6565b6000611e5c611478565b611d3b61122c565b611e6c6106c6565b6000611e76611478565b611e7e61122c565b600054611e8961159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611f575780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b9d9050565b611f956106c6565b8b611f9e611478565b611fa661122c565b600054611fb161159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561207f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611bf19050565b6120bd6106c6565b6000611f9e611478565b6120cf6106c6565b8b6120d8611478565b6120e061122c565b6000546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506117c99050565b6121f76106c6565b8b611e76611478565b6122086106c6565b60008b611e7e61122c565b61221b6106c6565b8a8c611fa661122c565b61222d6106c6565b60008b611fa661122c565b6122406106c6565b60008b6120e061122c565b6122536106c6565b8c8b61225d61122c565b60005461226861159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156123365780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f21561000257505060405151979650505050505050565b6123766106c6565b60008c8c600060005054611fb161159f565b6123906106c6565b60008c8c6000600050546120eb61159f565b6123aa6106c6565b60008c8c60006000505461226861159f565b60008d8d6000600050546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561249c5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150505b9695505050505050565b8e8d8d6000600050546123ce61159f565b60008d8d60006000505461226861159f565b60008d8d6000600050546123ce61159f565b60008e8e8d61226861159f565b8f8e8e8d61252561159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156125f35780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519998505050505050505050565b60008e8e8d6123ce61159f565b8a5160208c015160408d015160608e015161226861159f565b60008e8e8d61252561159f56", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000011f8119429ed3a", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe", - "0x031b9ec274101cc3ccff4d6d98ef4513742dadbaadba538bff48b88403253234": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x20ef51bb8ea9e8e8d5e2c17d28e47285698893c1017db4b4e40b792358a3dbc7": "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01", - "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8ac2": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfb": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe", - "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfc": "0x00000000000000000000000000000000000000000000000000000000000f6897", - "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfd": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dfe": "0x0000000000000000000000002859ddf2877c46d54e67b6becdb1cafb8ef4a458", - "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794dff": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9", - "0x37a551428681c06e6f97b79bb6c8c325935dc1a51b31a982594f40f2dd794e00": "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x3b20a4b931bc4ae9450774ee52b8f5da1b248d23e61cd20c09b25662f73894fd": "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x3b99aee1e3090227401ac2055c861246ca6ec62f426b4b4d74df88510f841b89": "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef711": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef712": "0x0000000000000000000000000000000000000000000000000000000000102ce9", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef713": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef714": "0x00000000000000000000000016917c151bb1399852a0741eb7b317b443e2cfa3", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef716": "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a3fe": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1", - "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a3ff": "0x00000000000000000000000000000000000000000000000000000000000fff67", - "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a400": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9", - "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a401": "0x00000000000000000000000010fc2e8ba5f40336c3576ffaa25177f1cdedf836", - "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a402": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0", - "0x5d866e5ddc53cb4c50f232302c51f03204d70c867baf663c9211cc229676a403": "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5ba": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bb": "0x000000000000000000000000000000000000000000000000000000000010347b", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bc": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5be": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bf": "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2751": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2752": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2753": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2754": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2755": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2756": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a7": "0x000000000000000000000000b7df3c43a8b13ecf45777c267404e15c7cdb04c9", - "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a8": "0x00000000000000000000000000000000000000000000000000000000000fe13d", - "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826a9": "0x000000000000000000000000f5d861791e76fa01433e0d7421aee565290e4afe", - "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826aa": "0x00000000000000000000000063110531142fb314118164ff579ba52746504408", - "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826ab": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1", - "0xa9e249fecbfa0518be95c32972ad551c71206081844335006bb2a349490826ac": "0x0000000000000000000000000000000000000000000000000000000000000007", - "0xac33ff75c19e70fe83507db0d683fd3465c996598dc972688b7ace676c890780": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xccd2cbc946692be8ade97db99353304e3af0fa6202f93649d4e185ad8b1f385c": "0x0000000000000000000000000000000000000000000000000000000000000004", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4ef": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f0": "0x00000000000000000000000000000000000000000000000000000000001030b3", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f1": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f2": "0x000000000000000000000000dd87a67740c2acf48a31829783a095a81c3628d9", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f3": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f4": "0x0000000000000000000000000000000000000000000000000000000000000003", - "0xdabde47554d6a6cfcff3c968abb145f298585fafa9e24c10fc526269794bd626": "0x0000000000000000000000000000000000000000000000000000000000000003", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db7": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db8": "0x000000000000000000000000000000000000000000000000000000000010365c", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64db9": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dba": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbb": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbc": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdec": "0x000000000000000000000000fd97a0d81cc92eecd52452831930b27889925ef0", - "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bded": "0x0000000000000000000000000000000000000000000000000000000000101dc2", - "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdee": "0x000000000000000000000000c5ef24ec3bf0e3522cfc8e53f3e076b043547ce1", - "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdef": "0x000000000000000000000000173243e117a6382211b1ac91eeb262f4a7021c16", - "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdf0": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c", - "0xfbba286dd5525a6ed3322411df4f261c98e43b123fef71777adc2b44d705bdf1": "0x0000000000000000000000000000000000000000000000000000000000000005" - } - }, - "0x741467b251fca923d6229c4b439078b55dca233b": { - "balance": "0x29c613529e8218f8", - "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000011f79bd42b0c7c", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000002dfeff8fca5d", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000003defb9627dd677b54fc954824a7bc49bd26cbdfa12c75adf", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000ba43b7400", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x00000000000000000000000000000000000000000000000000000000001e8480", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x000000000000000000000000000000000000000000000000000000000000000a": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x000000000000000000000000000000000000000000000000000000000010365c", - "0x000000000000000000000000000000000000000000000000000000000000000e": "0x00000000000000000000000000000000000000000000000000000000000000ff" - } - }, - "0x7c1eb207c07e7ab13cf245585bd03d0fa478d034": { - "balance": "0x0", - "code": "0x650200d2f18c7350606060405236156100a05760e060020a60003504630e9f1a3c81146100a55780632b4096b4146100c95780636ec13982146100eb578063a3119e571461010d578063a749f19b1461012f578063ab7366f714610151578063bacd69581461017f578063bfdf87c0146101c2578063c4144b26146101e1578063caa46c9c1461023c578063e6ce3a6a14610297578063ed5bd7ea146102b6575b610007565b6102d960043560243560008181526001830160205260409020600401545b92915050565b6102d960043560243560008181526001830160205260409020600301546100c3565b6102d960043560243560008181526001830160205260409020600201546100c3565b6102d960043560243560008181526001838101602052604090912001546100c3565b6102d960043560243560008181526001830160205260409020600501546100c3565b6102eb6004356024355b600081815260018301602052604081208054829182918291908614610790576101b9565b6102eb600435602435604435600082815260018401602052604081205481908190819086141561068a576040812060010154851415610680575b50505050505050565b6102d960043560243560008181526001830160205260409020546100c3565b6102d96004356024355b6040805160c08101825260008082526020828101829052828401829052606083018290526080830182905260a08301829052848252600186019052918220805490919083908114156102fb576102f2565b6102d96004356024355b6040805160c08101825260008082526020828101829052828401829052606083018290526080830182905260a08301829052848252600186019052918220805490919083908114156104c0576102f2565b6102d960043560243560443582546000908181811415610a6557610a8c565b6102d96004356024356000818152600183016020526040812060050154116100c3565b60408051918252519081900360200190f35b005b815193505b50505092915050565b60048301546000146103d257600483810154600090815260018881016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015460608201529181015460808301526005015460a082015291505b60608201516000146102ed57606091820151600090815260018781016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015493810193909352600481015460808401526005015460a0830152610364565b600283015460001461045b5750506002810154600081815260018681016020908152604092839020835160c081018552865481529286015491830191909152918101929092526003830154606083015260048301546080830152600583015460a08301525b81516003820154141561044d57805493506102f2565b600281015460001415610464575b600093506102f2565b6040805160c08101825282548152600183810154602083810191909152600285015483850181905260038601546060850152600486015460808501526005959095015460a0840152600094855290890190529120909150610437565b600383015460001461059757600383810154600090815260018881016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252918101546060830152600481015460808301526005015460a082015291505b60808201516000146102ed57608091820151600090815260018781016020908152604092839020835160c081018552815481529281015491830191909152600281015492820192909252600382015460608201526004820154938101939093526005015460a0830152610529565b600283015460001461045b5750506002810154600081815260018681016020908152604092839020835160c081018552865481529286015491830191909152918101929092526003830154606083015260048301546080830152600583015460a08301525b81516004820154141561061257805493506102f2565b6002810154600014156106245761045b565b6040805160c08101825282548152600183810154602083810191909152600285015483850181905260038601546060850152600486015460808501526005959095015460a08401526000948552908901905291209091506105fc565b61068a878761015b565b86546000925082141561069b578587555b508554600090815260018701602052604090205b8054600014156107255785815560028101829055600181018590556101b987875b60008181526001830160205260408120905b8154610d8e9085905b60008181526001830160205260408082206004810154835281832060059081015460038301548552929093209092015403905b5092915050565b60018101548154925085126107625760048101546000141561074957600481018690555b60040154600090815260018701602052604090206106af565b60038101546000141561077757600381018690555b60030154600090815260018701602052604090206106af565b600381015460001415806107a957506004810154600014155b156107cf576003810154600014610826578054600188019060009061083b908a90610246565b6002810154600014610a285760028101546000908152600188016020526040902060038101548254919550141561080857600060038501555b60048401548154141561081d57600060048501555b83549150610a2d565b80546001880190600090610852908a906101eb565b815260208101919091526040016000209450610865565b8152602081019190915260400160002094505b600285015460009081526001880160205260409020600381015486549195509092508214156108b9576004850154600385018190556000146108b95760048501546000908152604090208454600282015592505b60048401548554141561091357600385015460048501819055600014610913578660010160005060008660030160005054815260200190815260200160002060005092508250836000016000505483600201600050819055505b60028082015490860181905560001461098457866001016000506000826002016000505481526020019081526020016000206000509350835080600001600050548460030160005054141561096a57845460038501555b60048401548154141561097f57845460048501555b610989565b845487555b6003818101549086018190556000146109d6578660010160005060008260030160005054815260200190815260200160002060005092508250846000016000505483600201600050819055505b600481810154908601819055600014610a23578660010160005060008260040160005054815260200190815260200160002060005092508250846000016000505483600201600050819055505b610a2d565b600087555b6000808255600182018190556002820181905560038201819055600482018190556005820181905582146101b9576101b987836106d0565b50600081815260018601602052604090205b6001810154610a95908686610ad4565b805492505b50509392505050565b15610b915760fa60020a600f02851480610ab6575060f060020a613c3d0285145b15610af157600481015460001415610b3a5780549250610a8c565b86865b600060f960020a601f02831415610ce357508083135b9392505050565b60f960020a601f02851480610b0d575060f060020a613e3d0285145b80610b1f575060f060020a613d3d0285145b15610b9157600381015460001415610bc85780549250610a8c565b610b73610ad1878360040160005054600081815260018301602052604081205b600381015460001415610d61576001810154915061071e565b15610a87576004015460009081526001860160205260409020610a77565b60fa60020a600f02851480610bad575060f060020a613c3d0285145b15610c1f57600381015460001415610c565760009250610a8c565b610c01610ad1878360030160005054600081815260018301602052604081205b600481015460001415610d48576001810154915061071e565b15610a87576003015460009081526001860160205260409020610a77565b60f960020a601f02851480610c3b575060f060020a613e3d0285145b15610c6f57600481015460001415610ca25760009250610a8c565b6003015460009081526001860160205260409020610a77565b60f060020a613d3d02851415610cde57600181015484901215610cbb57600481015460001415610ca25760009250610a8c565b6004015460009081526001860160205260409020610a77565b600181015484901315610cde57600381015460001415610c565760009250610a8c565b610a77565b60fa60020a600f02831415610cfb5750808312610aea565b60f060020a613e3d02831415610d15575080831215610aea565b60f060020a613c3d02831415610d2f575080831315610aea565b60f060020a613d3d028314156100a05750828114610aea565b6004015460009081526001840160205260409020610be8565b6003015460009081526001840160205260409020610b5a565b600282015460001415610fbd575b50505050565b90508060021415610e2657610daa8483600301600050546106eb565b6000191415610dc457610dc4848360030160005054610dfe565b8154610e269085905b60008181526001830160205260408120600381015490919081908190811415610ffb57610007565b8154610e5a9085905b60008181526001830160205260408120600481015490919081908190811415610e7f57610007565b806001191415610e5a57610e418483600401600050546106eb565b60011415610df557610df5848360040160005054610dcd565b8060001913158015610e6d575060018113155b15610d7a578154610d7a908590610f7a565b6004840180546000908152600188016020526040812060028088015490820181905592829055945014610f0f57856001016000506000856002016000505481526020019081526020016000206000509150836000016000505482600301600050541415610efa57826000016000505482600301600050819055505b835460048301541415610f0f57825460048301555b6003830154600014610f40575060038201546000908152600186016020526040902080546004850155835460028201555b82546002808601919091558454600385015583015460001415610f7157826000016000505486600001600050819055505b8354610fe69087905b6000818152600183016020526040808220600381015483528183206005908101546004830154855292842001549092610fd99291908183106110fa5750816100c3565b60029091015460009081526001840160205260409020906106e2565b6001016005820155505050565b8254610ff3908790610f7a565b505050505050565b600384018054600090815260018801602052604081206002808801549082018190559282905594501461108b5785600101600050600085600201600050548152602001908152602001600020600050915083600001600050548260030160005054141561107657826000016000505482600301600050819055505b83546004830154141561108b57825460048301555b60048301546000146110bd57506004820154600081815260018701602052604090206003850191909155835460028201555b82546002808601919091558454600485015583015460001415610f7157826000016000505486600001600050819055508354610fe6908790610f7a565b50806100c356" - }, - "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": { - "balance": "0xd7a58f5b73b4b6c4", - "code": "0x606060405236156100985760e060020a60003504633896002781146100e15780633defb962146100ea5780633f4be8891461010c5780634136aa351461011f5780634a420138146101a057806369c1a7121461028c5780638129fc1c146102955780638da5cb5b146102a6578063ae45850b146102b8578063af3309d8146102cc578063ea8a1af0146102d5578063ead50da3146102f4575b610308671bc16d674ec8000030600160a060020a03163110156100df57600554604051600160a060020a03918216916000913091909116319082818181858883f150505050505b565b61030a60005481565b610308671bc16d674ec8000030600160a060020a031631101561040f576100df565b61031c600454600160a060020a03165b90565b61030a5b600080548190118015610199575060408051600480547f0a16697a0000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692630a16697a928083019260209291829003018187876161da5a03f1156100025750506040515160ff01431090505b905061011c565b6103085b600354600554604080517f8c0e156d0000000000000000000000000000000000000000000000000000000081527f3defb96200000000000000000000000000000000000000000000000000000000600482015260a060020a90920461ffff1643016024830152621e8480604483015251600092600160a060020a031691638c0e156d916729a2241af62c000091606481810192602092909190829003018185886185025a03f1156100025750506040515192600160a060020a0384161491506102899050576004805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b61030a60015481565b61030860008054146103f2576100df565b61031c600554600160a060020a031681565b61031c600354600160a060020a031661011c565b61030a60025481565b610308600554600160a060020a03908116339091161461035157610002565b61033960055460a060020a900461ffff1681565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6004546000600160a060020a03919091163111156103c75760408051600480547fea8a1af00000000000000000000000000000000000000000000000000000000083529251600160a060020a03939093169263ea8a1af0928083019260009291829003018183876161da5a03f115610002575050505b600554604051600160a060020a03918216916000913091909116319082818181858883f15050505050565b426000556100df6101a4565b600280546001908101909155429055565b600454600160a060020a03908116339091161461042b576100df565b610433610123565b151561043e576100df565b6103fe6101a456", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000056be5b99", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d0009b", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008b", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000001e0d3cda913deb6f67967b99d67acdfa1712c293601" - } - }, - "0x89efe605e9ecbe22849cd85d5449cc946c26f8f3": { - "balance": "0x0", - "code": "0x650200d2f18c73506060604052361561007f5760e060020a600035046312c82bcc81146100845780635548c837146100a55780635c54305e146101015780636b103966146101555780637fcf532c14610189578063b1df3d80146101d5578063b5bc6dbb146101ee578063c6ab451414610225578063e62af6c114610293575b610007565b6102c56004356024356000620186a05a10156103855761030083835a610232565b6102d760043560243560443581600160a060020a031683600160a060020a03167f47a08955ce2b7f21ea62ff0024e1ea0ad87430953554a87e6bc65d777f18e639836040518082815260200191505060405180910390a3505050565b6102d760043560243560443560408051838152602081018390528151600160a060020a038616927f9b24879829bed3003de08d5c5d7e18dcbb8dc76faebd95cafc5d4dec8c61a3a5928290030190a2505050565b6102d76004356024356044355b600160a060020a03821660009081526020849052604090205480820110156102d957610007565b6102d7600435602435604080518281529051600160a060020a038416917fd0c5cf41ee8ebf084ad0bce53de7cbc6e4693d9b53a4019ca36a2f91cdc20b3a919081900360200190a25050565b6102c560043560243560443560006102fc848484610162565b6102c5600435602435604435600160a060020a03821660009081526020849052604081205482901061032b576103338484846102a0565b6102c56004356024356044355b60006000831180156102605750604051600160a060020a038516908290859082818181858883f19350505050155b156102fc57604051600160a060020a03851690839085906000818181858888f1935050505015156102fc57506000610300565b6102d76004356024356044355b600160a060020a03821660009081526020849052604090205481111561030757610007565b60408051918252519081900360200190f35b005b600160a060020a0382166000908152602084905260409020805482019055505050565b5060015b9392505050565b600160a060020a038216600090815260208490526040902080548290039055505050565b506000610300565b604051600160a060020a03841690600090849082818181858883f1935050505015156102fc57604051600160a060020a038416908390600081818185876185025a03f19250505015156102fc57610007565b6103008383620186a061023256" - }, - "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": { - "balance": "0xffe9b09a5c474dca", - "nonce": "975", - "code": "0x" - }, - "0xd3cda913deb6f67967b99d67acdfa1712c293601": { - "balance": "0x4f5807198e238f13e", - "nonce": "283", - "code": "0x" - }, - "0xe54d323f9ef17c1f0dede47ecc86a9718fe5ea34": { - "balance": "0x0", - "code": "0x650200d2f18c7350606060405236156100ab5760e060020a600035046326a7985a81146100b057806350d4e411146100be57806354fd4d501461023d578063586a69fa1461025d5780638e46afa91461026857806396cff3df14610272578063971c803f1461029657806398c9cdf4146102a157806398e00e54146102ae578063b152f19e146102b8578063c0f68859146102c4578063e3042c0f146102cf578063ea27a88114610461575b610007565b6102845b60006104cb6102a5565b604080516020601f60843560048181013592830184900484028501840190955281845261047f948035946024803595604435956064359560a494930191819084018382808284375094965050933593505060c43591505060e435610104356101243561014435610164356101843560006101806040519081016040528060008152602001600081526020016000815260200160206040519081016040528060008152602001508152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200150610180604051908101604052808f81526020018e81526020018d81526020018c81526020018981526020018b81526020018a81526020018881526020018781526020018681526020018581526020018481526020015090506104d48f825b600060006000600a43018460e0015110156105de577f544f4f5f534f4f4e0000000000000000000000000000000000000000000000009150610524565b604080516000808252600760208301528183015290519081900360600190f35b61049c5b6103e85b90565b6104b460ff610265565b62030d403a0260026024356004350102015b60408051918252519081900360200190f35b61049c5b600a610265565b6102845b62030d40610265565b6102846010610265565b61028443600a01610265565b6102845b6020610265565b60408051808201825261047f916004803592909160649190602490600290839083908082843780516020601f608435808c01359182018390048302840183019094528083529499983598975060a49650909450910191908190840183828082843750506040805160c0818101909252959796359660c435969095506101a49450925060e491506006908390839080828437509095505050505050604080516101808181018352600080835260208381018290528385018290528451908101855281815260608401526080830181905260a0830181905260c0830181905260e0830181905261010083018190526101208301819052610140830181905261016083018190528351918201909352808984505181526020018960015060209081015182528101899052604081018890526060018484505181526020810187905260408101869052606001846001506020908101518252018460025060400151815260200184600350606001518152602001846004506080015181526020018460055060a00151905290506104e78982610200565b6102846004356024356044356064355b3a0291909201600202010190565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6040805160ff929092168252519081900360200190f35b45039050610265565b9f9e505050505050505050505050505050565b9998505050505050505050565b8461016001511015610524577f494e53554646494349454e545f46554e4453000000000000000000000000000091505b600082146106ed576040805185518482529151600160a060020a0392909216917f513485fc54ef019ef1bc1ea683ef7d5d522f2865224ae10871ff992749c0ba4f9181900360200190a27389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc85600001518661016001516040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f215610007575050505b505092915050565b8360c0015161ffff166105ef61029a565b61ffff1611806106115750610602610261565b61ffff168460c0015161ffff16115b1561063e577f535441434b5f434845434b5f4f55545f4f465f52414e474500000000000000009150610524565b6106466102c8565b8460a0015160ff16101561067c577f47524143455f544f4f5f53484f525400000000000000000000000000000000009150610524565b6106846102a5565b84610100015110806106a157506106996100b4565b846101000151115b156106ce577f52455155495245445f4741535f4f55545f4f465f52414e4745000000000000009150610524565b6104f48461012001518561014001518660800151876101000151610471565b83610160015184600001518560e001518660a001518760200151886040015189606001518a608001518b61010001518c60c001518d61012001518e6101400151604051611078806108fa833901808c600160a060020a031681526020018b81526020018a60ff16815260200189600160a060020a03168152602001888152602001806020018781526020018681526020018561ffff1681526020018481526020018381526020018281038252888181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156107ec5780820380516001836020036101000a031916815260200191505b509c505050505050505050505050506040518091039082f090509050737c1eb207c07e7ab13cf245585bd03d0fa478d03463bacd69588683600160a060020a031660010284600160a060020a0316630a16697a6040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000757505050604051805190602001506040518460e060020a02815260040180848152602001838152602001828152602001935050505060006040518083038160008760325a03f21561000757505060408051600160a060020a038416815290517f2b05d346f0b0b9fd470024751c52d3b5dac5c37796f077c1a66241f2eada44b792509081900360200190a18092506105d656606060405260405161107838038061107883398101604052805160805160a05160c05160e05161010051610120516101405161016051610180516101a051999a98999798969795969490940194929391929091908a84848a8a8a8a88886101008051600c8054600160a060020a031990811633179091556000805482168d1781556001868155600286815560078e90556008805461ffff19168e1790553a600655600380547c01000000000000000000000000000000000000000000000000000000008d04740100000000000000000000000000000000000000000260a060020a63ffffffff0219919096168e17169490941790935588516004805493819052956020601f9385161590910260001901909316939093048101919091047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b908101939091608091909101908390106101ee57805160ff19168380011785555b5061017a9291505b8082111561021e5760008155600101610166565b5050826003600050600201600050819055505050505050505050508a600060006101000a815481600160a060020a030219169083021790555089600d6000508190555088600e60006101000a81548160ff021916908302179055505050505050505050505050610e56806102226000396000f35b8280016001018555821561015e579182015b8281111561015e578251826000505591602001919060010190610200565b509056606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "ethash": {} - } - }, - "context": { - "number": "1062503", - "difficulty": "13700504019867", - "timestamp": "1456480446", - "gasLimit": "3141592", - "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226" - }, - "input": "0xf86b8203cf850ba43b740083200b2094741467b251fca923d6229c4b439078b55dca233b8084614619541ca078293714f69a810356f1ee29dc686ec2ca3a0e5448e1ef6322c77369ebdd26c2a01c3836fa363548959554ee5360361be9db4aea9eb7c31f61550f0e9a10138adf", - "tracerConfig": { - "diffMode": true - }, - "result": { - "pre": { - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x98e1c608601c2496b2", - "nonce": 218916 - }, - "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": { - "balance": "0x0", - "nonce": 237, - "code": "0x6060604052361561027c5760e060020a600035046301991313811461027e57806303d22885146102ca5780630450991814610323578063049ae734146103705780630ce46c43146103c35780630e85023914610602578063112e39a8146106755780631b4fa6ab146106c25780631e74a2d3146106d057806326a7985a146106fd5780633017fe2414610753578063346cabbc1461075c578063373a1bc3146107d55780633a9e74331461081e5780633c2c21a01461086e5780633d9ce89b146108ba578063480b70bd1461092f578063481078431461097e57806348f0518714610a0e5780634c471cde14610a865780634db3da8314610b09578063523ccfa814610b4f578063586a69fa14610be05780635a9f2def14610c3657806364ee49fe14610caf57806367beaccb14610d055780636840246014610d74578063795b9a6f14610dca5780637b55c8b514610e415780637c73f84614610ee15780638c0e156d14610f145780638c1d01c814610f605780638e46afa914610f69578063938c430714610fc0578063971c803f146111555780639772c982146111ac57806398c9cdf41461122857806398e00e541461127f5780639f927be7146112d5578063a00aede914611383578063a1c0539d146113d3578063aff21c6514611449578063b152f19e14611474578063b549793d146114cb578063b5b33eda1461154b578063bbc6eb1f1461159b578063c0f68859146115ab578063c3a2c0c314611601578063c43d05751461164b578063d8e5c04814611694578063dbfef71014611228578063e29fb547146116e7578063e6470fbe1461173a578063ea27a8811461174c578063ee77fe86146117d1578063f158458c14611851575b005b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387876020604051908101604052806000815260200150612225610f6d565b61188260043560243560443560643560843560a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338b8a6020604051908101604052806000815260200150896125196106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a026020604051908101604052806000815260200150611e4a610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503389896020604051908101604052806000815260200150886124e86106c6565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750506040805160a08082019092529597963596608435969095506101449450925060a491506005908390839080828437509095505050505050604080518082018252600160a060020a03338116825288166020820152815160c0810190925260009173e54d323f9ef17c1f0dede47ecc86a9718fe5ea349163e3042c0f91600191908a908a9089908b90808b8b9090602002015181526020018b60016005811015610002579090602002015181526020018b60026005811015610002579090602002015181526020018b60036005811015610002579090602002015181526020018b6004600581101561000257909060200201518152602001348152602001506040518860e060020a02815260040180888152602001876002602002808383829060006004602084601f0104600f02600301f150905001868152602001806020018560ff1681526020018461ffff168152602001836006602002808383829060006004602084601f0104600f02600301f1509050018281038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038160008760325a03f2156100025750506040515191506124cd9050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808787611e64610f6d565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611d28610f6d565b61189f5b6000611bf8611159565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881600060005054611a9561159f565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346326a7985a6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b760075b90565b604080516020606435600481810135601f8101849004840285018401909552848452611882948135946024803595604435956084949201919081908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160013389898861224b610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386866020604051908101604052806000815260200150611e64610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333896020604051908101604052806000815260200150886123bc6106c6565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387866020604051908101604052806000815260200150611f8d610f6d565b60408051602060248035600481810135601f810185900485028601850190965285855261188295813595919460449492939092019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808888612225610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503388886020604051908101604052806000815260200150612388610f6d565b611882600435604080517fc4144b2600000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163c4144b26916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133888888612238610f6d565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338b8b8b896126536106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333866020604051908101604052806000815260200150611e4a610f6d565b6118b76004355b604080517fed5bd7ea00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163ed5bd7ea916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b61189f600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463586a69fa6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650509335935050606435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808989612388610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a896020604051908101604052806000815260200150886124d76106c6565b6040805160206004803580820135601f8101849004840285018401909552848452611882949193602493909291840191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808587611e4a610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a8a60206040519081016040528060008152602001508961262d6106c6565b604080516020606435600481810135601f810184900484028501840190955284845261188294813594602480359560443595608494920191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338888876120c7610f6d565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437505060408051608080820190925295979635969561010495509350608492508591508390839080828437509095505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989898961263a6106c6565b6118b7600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881858585611ba361122c565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050333388602060405190810160405280600081526020015061236e610f6d565b6118b760005481565b6118c95b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea34638e46afa96040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a43560c43560e43561010435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338e8e8d8f8e8e8e8e8e346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111195780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519b9a5050505050505050505050565b61189f5b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463971c803f6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650509335935050608435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989896123a2610f6d565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398c9cdf46040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152600160048201527f3e3d0000000000000000000000000000000000000000000000000000000000006024820152604481018390529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163e6ce3a6a916064818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a0260206040519081016040528060008152602001506121ef610f6d565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338787876120b5610f6d565b6118b7600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88183611b4561159f565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463b152f19e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808b8b8961262d6106c6565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386600060e060020a026020604051908101604052806000815260200150612200610f6d565b6118b75b60005460649004610759565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611bff610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333876020604051908101604052806000815260200150612200610f6d565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387600060e060020a026020604051908101604052806000815260200150612213610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338a60206040519081016040528060008152602001508961250c6106c6565b61027c6000600060006118e033610b56565b6118b7600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881868686866040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b949350505050565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338a8a8a886124fa6106c6565b6118b7600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88184846000611b4f61122c565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b60408051918252519081900360200190f35b6040805160ff929092168252519081900360200190f35b15611a905733925082600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fc6803622000000000000000000000000000000000000000000000000000000008252915191945063c680362291600482810192602092919082900301816000876161da5a03f11561000257505060405151905080156119d1575082600160a060020a031663d379be236040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a03166000141590505b80156119dd5750600082115b80156119ec5750600054600190115b15611a90578183600160a060020a031663830953ab6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040515160640291909104915050604281118015611a4d5750600054829011155b15611a675760008054612710612711909102049055611a90565b602181108015611a7a5750600054829010155b15611a90576000805461271061270f9091020490555b505050565b6000611a9f61122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b919050565b6000611af261122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b9392505050565b9050610759565b611c076106c6565b6000611c11611478565b611c1961122c565b600054611c2461159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611cf25780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b611d306106c6565b60008b611d3b61122c565b600054611d4661159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611e145780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b409050565b611e526106c6565b6000611e5c611478565b611d3b61122c565b611e6c6106c6565b6000611e76611478565b611e7e61122c565b600054611e8961159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611f575780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b9d9050565b611f956106c6565b8b611f9e611478565b611fa661122c565b600054611fb161159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561207f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611bf19050565b6120bd6106c6565b6000611f9e611478565b6120cf6106c6565b8b6120d8611478565b6120e061122c565b6000546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506117c99050565b6121f76106c6565b8b611e76611478565b6122086106c6565b60008b611e7e61122c565b61221b6106c6565b8a8c611fa661122c565b61222d6106c6565b60008b611fa661122c565b6122406106c6565b60008b6120e061122c565b6122536106c6565b8c8b61225d61122c565b60005461226861159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156123365780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f21561000257505060405151979650505050505050565b6123766106c6565b60008c8c600060005054611fb161159f565b6123906106c6565b60008c8c6000600050546120eb61159f565b6123aa6106c6565b60008c8c60006000505461226861159f565b60008d8d6000600050546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561249c5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150505b9695505050505050565b8e8d8d6000600050546123ce61159f565b60008d8d60006000505461226861159f565b60008d8d6000600050546123ce61159f565b60008e8e8d61226861159f565b8f8e8e8d61252561159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156125f35780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519998505050505050505050565b60008e8e8d6123ce61159f565b8a5160208c015160408d015160608e015161226861159f565b60008e8e8d61252561159f56", - "storage": { - "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bc": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bd": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bf": "0x0000000000000000000000000000000000000000000000000000000000000002", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f1": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f3": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f4": "0x0000000000000000000000000000000000000000000000000000000000000003", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbc": "0x0000000000000000000000000000000000000000000000000000000000000001" - } - }, - "0x741467b251fca923d6229c4b439078b55dca233b": { - "balance": "0x29c613529e8218f8", - "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256" - }, - "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": { - "balance": "0xd7a58f5b73b4b6c4", - "code": "0x606060405236156100985760e060020a60003504633896002781146100e15780633defb962146100ea5780633f4be8891461010c5780634136aa351461011f5780634a420138146101a057806369c1a7121461028c5780638129fc1c146102955780638da5cb5b146102a6578063ae45850b146102b8578063af3309d8146102cc578063ea8a1af0146102d5578063ead50da3146102f4575b610308671bc16d674ec8000030600160a060020a03163110156100df57600554604051600160a060020a03918216916000913091909116319082818181858883f150505050505b565b61030a60005481565b610308671bc16d674ec8000030600160a060020a031631101561040f576100df565b61031c600454600160a060020a03165b90565b61030a5b600080548190118015610199575060408051600480547f0a16697a0000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692630a16697a928083019260209291829003018187876161da5a03f1156100025750506040515160ff01431090505b905061011c565b6103085b600354600554604080517f8c0e156d0000000000000000000000000000000000000000000000000000000081527f3defb96200000000000000000000000000000000000000000000000000000000600482015260a060020a90920461ffff1643016024830152621e8480604483015251600092600160a060020a031691638c0e156d916729a2241af62c000091606481810192602092909190829003018185886185025a03f1156100025750506040515192600160a060020a0384161491506102899050576004805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b61030a60015481565b61030860008054146103f2576100df565b61031c600554600160a060020a031681565b61031c600354600160a060020a031661011c565b61030a60025481565b610308600554600160a060020a03908116339091161461035157610002565b61033960055460a060020a900461ffff1681565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6004546000600160a060020a03919091163111156103c75760408051600480547fea8a1af00000000000000000000000000000000000000000000000000000000083529251600160a060020a03939093169263ea8a1af0928083019260009291829003018183876161da5a03f115610002575050505b600554604051600160a060020a03918216916000913091909116319082818181858883f15050505050565b426000556100df6101a4565b600280546001908101909155429055565b600454600160a060020a03908116339091161461042b576100df565b610433610123565b151561043e576100df565b6103fe6101a456", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d0009b", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008b", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b" - } - }, - "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": { - "balance": "0xffe9b09a5c474dca", - "nonce": 975 - }, - "0xd3cda913deb6f67967b99d67acdfa1712c293601": { - "balance": "0x4f5807198e238f13e", - "nonce": 283 - } - }, - "post": { - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x98e2b02f14529b1eb2" - }, - "0x651913977e8140c323997fce5e03c19e0015eebf": { - "balance": "0x29a2241af62c0000", - "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000011f8119429ed3a", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x00000000000000000000000000000000000000000000000000002e002d006b55", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000003defb9627dd677b54fc954824a7bc49bd26cbdfa12c75adf", - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000ba43b7400", - "0x0000000000000000000000000000000000000000000000000000000000000007": "0x00000000000000000000000000000000000000000000000000000000001e8480", - "0x0000000000000000000000000000000000000000000000000000000000000008": "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x000000000000000000000000000000000000000000000000000000000000000c": "0x0000000000000000000000006c8f2a135f6ed072de4503bd7c4999a1a17f824b", - "0x000000000000000000000000000000000000000000000000000000000000000d": "0x0000000000000000000000000000000000000000000000000000000000103847", - "0x000000000000000000000000000000000000000000000000000000000000000e": "0x00000000000000000000000000000000000000000000000000000000000000ff" - } - }, - "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": { - "nonce": 238, - "storage": { - "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", - "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bc": "0x000000000000000000000000a4d91b341f0e9a7000be916a668408b463f4c38c", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bd": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", - "0x95e05d02b91af970cb4998107e8613455258880676e00b819c12d675e60de5bf": "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2751": "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2752": "0x0000000000000000000000000000000000000000000000000000000000103847", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2753": "0x000000000000000000000000741467b251fca923d6229c4b439078b55dca233b", - "0x99d5294a34e2d6d560a223237786adc8b5651c09094b9ecd56e6ae7abc2a2756": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f1": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f3": "0x000000000000000000000000c9a2bfd279fe57e7651e5d9f29bb1793c9a1cf01", - "0xd3a5582b3eff6ef8ee90f3962e9d598a3f4b7d07840356c9b8fd7b494879b4f4": "0x0000000000000000000000000000000000000000000000000000000000000002", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbb": "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf", - "0xf7518490c515b9fc8e7fe713b647fe88eacefc92d616fa9454e61fe9aab64dbc": "0x0000000000000000000000000000000000000000000000000000000000000002" - } - }, - "0x741467b251fca923d6229c4b439078b55dca233b": { - "balance": "0x0", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000000b": "0x0000000000000000000000000000000000000000000000000000000000000101" - } - }, - "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": { - "balance": "0xd6c5f42b8502a0e3", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d020be", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008c", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000651913977e8140c323997fce5e03c19e0015eebf" - } - }, - "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": { - "balance": "0x10002e64ebd492a46", - "nonce": 976 - }, - "0xd3cda913deb6f67967b99d67acdfa1712c293601": { - "balance": "0x4f5809f97e1c8bb9b" - } - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json deleted file mode 100644 index 01cc3c5058..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "context": { - "difficulty": "3502894804", - "gasLimit": "4722976", - "miner": "0x1585936b53834b021f68cc13eeefdec2efc8e724", - "number": "2289806", - "timestamp": "1513601314" - }, - "genesis": { - "alloc": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "code": "0x", - "nonce": "22", - "storage": {} - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "nonce": "1", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000003c", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "code": "0x", - "nonce": "29072", - "storage": {} - } - }, - "config": { - "byzantiumBlock": 1700000, - "chainId": 3, - "daoForkSupport": true, - "eip150Block": 0, - "eip150Hash": "0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d", - "eip155Block": 10, - "eip158Block": 10, - "ethash": {}, - "homesteadBlock": 0 - }, - "difficulty": "3509749784", - "extraData": "0x4554482e45544846414e532e4f52472d4641313738394444", - "gasLimit": "4727564", - "hash": "0x609948ac3bd3c00b7736b933248891d6c901ee28f066241bddb28f4e00a9f440", - "miner": "0xbbf5029fd710d227630c8b7d338051b8e76d50b3", - "mixHash": "0xb131e4507c93c7377de00e7c271bf409ec7492767142ff0f45c882f8068c2ada", - "nonce": "0x4eb12e19c16d43da", - "number": "2289805", - "stateRoot": "0xc7f10f352bff82fac3c2999d3085093d12652e19c7fd32591de49dc5d91b4f1f", - "timestamp": "1513601261", - "totalDifficulty": "7143276353481064" - }, - "input": "0xf88b8271908506fc23ac0083015f90943b873a919aa0512d5a0f09e6dcceaa4a6727fafe80a463e4bff40000000000000000000000000024f658a46fbb89d8ac105e98d7ac7cbbaf27c52aa0bdce0b59e8761854e857fe64015f06dd08a4fbb7624f6094893a79a72e6ad6bea01d9dde033cff7bb235a3163f348a6d7ab8d6b52bc0963a95b91612e40ca766a4", - "tracerConfig": { - "diffMode": true - }, - "result": { - "pre": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x0", - "nonce": 22 - }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x0" - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d87094125a369d9bd5", - "nonce": 1, - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d77678137ac1b775", - "nonce": 29072 - } - }, - "post": { - "0x0024f658a46fbb89d8ac105e98d7ac7cbbaf27c5": { - "balance": "0x6f05b59d3b20000" - }, - "0x1585936b53834b021f68cc13eeefdec2efc8e724": { - "balance": "0x420eed1bd6c00" - }, - "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { - "balance": "0x4d869a3b70062eb9bd5", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b95e" - } - }, - "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { - "balance": "0x1780d7725724a9044b75", - "nonce": 29073 - } - } - } -} diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json deleted file mode 100644 index 5021bda192..0000000000 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "genesis": { - "difficulty": "5697691613344", - "extraData": "0xd783010202844765746887676f312e342e32856c696e7578", - "gasLimit": "3141592", - "hash": "0x2004021ae3545cf8abba1ec97a7e401157cee9e847131e2f4c75ce38610040cc", - "miner": "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", - "mixHash": "0x651f01d13fb801c602e1544ab80b3bc32888ea40ef298efa52ec3df983b558ee", - "nonce": "0xdf23f0da925518a6", - "number": "422908", - "stateRoot": "0xd914c6440edf9f4a6f997a9b3ecb6e1a9ca2310f74b0b6890c0d0d4a3c28e4d3", - "timestamp": "1445530335", - "totalDifficulty": "2148894717741690476", - "alloc": { - "0x2861bf89b6c640c79040d357c1e9513693ef5d3f": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a600035046312055e8f8114610084578063185061da146100b157806322beb9b9146100d5578063245a03ec146101865780633fa4f245146102a657806341c0e1b5146102af578063890eba68146102cb578063b29f0835146102de578063d6b4485914610308578063dd012a15146103b9575b005b6001805474ff0000000000000000000000000000000000000000191660a060020a60043502179055610082565b6100826001805475ff00000000000000000000000000000000000000000019169055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527fb29f0835000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b6100826004356024356001547fb0f07e440000000000000000000000000000000000000000000000000000000060609081526064839052600160a060020a039091169063b0f07e449060849060009060248183876161da5a03f150604080516001547f73657449742875696e74323536290000000000000000000000000000000000008252825191829003600e018220878352835192839003602001832060e060020a6352afbc33028452600160a060020a03308116600486015260e060020a9283900490920260248501526044840152438901606484015260a060020a820460ff1694830194909452600060a483018190529251931694506352afbc33935060c48181019391829003018183876161da5a03f115610002575050505050565b6103c460025481565b61008260005433600160a060020a039081169116146103ce575b565b6103c460015460a860020a900460ff1681565b6100826001805475ff000000000000000000000000000000000000000000191660a860020a179055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527f185061da000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b600435600255610082565b6060908152602090f35b6001547f6ff96d17000000000000000000000000000000000000000000000000000000006060908152600160a060020a0330811660645290911690632e1a7d4d908290636ff96d17906084906020906024816000876161da5a03f1156100025750506040805180517f2e1a7d4d0000000000000000000000000000000000000000000000000000000082526004820152905160248281019350600092829003018183876161da5a03f115610002575050600054600160a060020a03169050ff", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000ff30c9e568f133adce1f1ea91e189613223fc461b9" - } - }, - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x326601cc6cf364f6b9", - "nonce": "12122", - "code": "0x" - }, - "0x30c9e568f133adce1f1ea91e189613223fc461b9": { - "balance": "0x8b83c417dd78000", - "nonce": "2", - "code": "0x606060405236156102ea5760e060020a6000350463022bc71f81146102f757806303d6d7b61461037f578063086ae9e4146103ec57806309c975df146104595780631145a20f146104c657806312d67c5f146104e75780631302188c146104f15780631ae460e5146104fc57806323306ed614610573578063234917d4146105ca57806329917954146106375780632a472ae81461071d5780632e1a7d4d1461078a578063306b031d1461087f57806333613cbe1461089d57806334c19b93146108c257806335b281531461092f5780633664a0ea146109b85780633c941423146109c35780633cbfed7414610a3b57806350a3bd3914610a4957806352afbc3314610a735780635539d40014610c2a5780635a5383ac14610c3e57806360b831e514610cb55780636164947214610d7f578063685c234a14610d8a5780636ffc089614610de0578063741b3c3914610e4d5780637542861514610ed25780637772a38014610f5557806377b19cd514610ff057806378bc64601461105d5780638b37e656146110ca5780638baced64146111375780638dd5e298146111b157806393423e9c146111de57806394d2b21b1461120257806394f3f81d1461121657806398e00e54146112665780639f927be7146112bc578063a502aae81461136a578063a6c01cfd146113e8578063a9743c68146113fa578063aa4cc01f14611467578063b010d94a146114d4578063b0171fa41461154e578063b0ac4c8c146115cc578063b0f07e4414611635578063b35594601461171c578063c0f6885914611739578063c3daab961461178f578063c630f92b146117bb578063c831391d146117e5578063cd062734146117f0578063d0e30db01461185d578063db681e5414611865578063e40986551461190c578063e850f3ae14611979578063ed2b8e0b146119e6578063f340fa01146119f1578063f828c3fa14611ae8578063f8b1185314611b07578063f9f447eb14611b24578063fc30052214611b91578063fcf3691814611bfe575b6112645b611c86336119f8565b611c88600435604080517fc4144b260000000000000000000000000000000000000000000000000000000081526010600482015260248101839052905160009173ce642b6a82e72147ceade0e72c786ba8eaeb31d79163c4144b26916044818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b637d613b346000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63da40fd616000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c9a60043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63c68efc486000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b61126460043560243560443560643560843561200185858585856000610a89565b611c886004545b90565b611c886005546104ee565b611c886040805160e160020a6333f8a36702815260066004820152600160a060020a0333166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f916367f146ce916044818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b611c885b60007327b1b436e4699a012cc8698e33c8f3e1c035c28b6323306ed66040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63e99a66856000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264604080517f317c152d00000000000000000000000000000000000000000000000000000000815260066004820152600160a060020a0333166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163317c152d916044818101926020929091908290030181878760325a03f2156100025750506040805180517ff1173928000000000000000000000000000000000000000000000000000000008252600160a060020a0333166004830152602482018190529151919363f1173928926044838101938290030181838760325a03f2156100025750505050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63707378396000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264600435604080517fb5bc6dbb00000000000000000000000000000000000000000000000000000000815260126004820152600160a060020a033316602482015260448101839052905173d3cb18959b0435864ff33010fa83be60afc04b229163b5bc6dbb916064828101926020929190829003018160008760325a03f21561000257505060405151159050611d255773d3cb18959b0435864ff33010fa83be60afc04b22637fcf532c33836040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060006040518083038160008760325a03f21561000257505050611ae5565b611c886004356000818152600e60205260409020600201545b919050565b611c886004355b600160a060020a0381166000908152600f6020526040902054610898565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63fc4730126000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264600435604080517fa95d3e76000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a0384811660248401523316604483015291517327b1b436e4699a012cc8698e33c8f3e1c035c28b9263a95d3e7692606481810193918290030181838760325a03f2156100025750505050565b611c886002546104ee565b611c9a60043560243560007327b1b436e4699a012cc8698e33c8f3e1c035c28b6398213db6600060005085856040518460e060020a02815260040180848152602001838152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150610dda9050565b611c886000611e0a336108a4565b611264600073c895c144d0b0f88417cf9e14e03e6abc82c0af3f635748147e600633611ec2610577565b61126460043560243560443560643560843560a4355b604080517ff1924efb000000000000000000000000000000000000000000000000000000008152600060048201819052600160a060020a03338116602484015289166044830152606482018890526084820187905260a4820186905260ff851660c483015260e48201849052915182917327b1b436e4699a012cc8698e33c8f3e1c035c28b9163f1924efb91610104818101926020929091908290030181878760325a03f2156100025750506040805180517f5a1230bf000000000000000000000000000000000000000000000000000000008252600160a060020a0333811660048401528c166024830152604482018b9052606482018a90526084820189905260ff881660a483015260c482018790529151919450635a1230bf9160e48083019260209291908290030181878760325a03f215610002575050604051519183149050612008577327b1b436e4699a012cc8698e33c8f3e1c035c28b6318b753ab82846040518360e060020a028152600401808381526020018281526020019250505060006040518083038160008760325a03f21561000257505050612056565b611c9a600154600160a060020a03166104ee565b611c886040805160e560020a6304b47bb902815260066004820152600160a060020a0333166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163968f7720916044818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b6112646004357327b1b436e4699a012cc8698e33c8f3e1c035c28b637e853f3d600060005083336040518460e060020a0281526004018084815260200183815260200182600160a060020a03168152602001935050505060206040518083038160008760325a03f21561000257505060405151159050611ae5577327b1b436e4699a012cc8698e33c8f3e1c035c28b63ab2af349826040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f2156100025750505050565b611c886008546104ee565b611c88600435602435604080516c01000000000000000000000000600160a060020a03858116820283528416026014820152815160289181900391909101902060009081526015602052205460ff165b92915050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63b506054f6000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264604080517f068e3ef100000000000000000000000000000000000000000000000000000000815260066004820152600160a060020a0333166024820152346044820152905173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163068e3ef19160648281019260009291908290030181838760325a03f21561000257505050565b611cb76004356040805160208181018352600080835284815260138252838120600d0154815260148252835190849020805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015611fb85780601f10611f8d57610100808354040283529160200191611fb8565b611c886004356024355b604080517fa163a32500000000000000000000000000000000000000000000000000000000815260066004820152600160a060020a038416602482015260448101839052905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163a163a325916064818101926020929091908290030181878760325a03f215610002575050604051519150610dda9050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63775f20f96000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b637517a7c96000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c9a60043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63250687836000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c886004356040805160e160020a6333f8a36702815260066004820152600160a060020a0383166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f916367f146ce916044818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c88600435600073c895c144d0b0f88417cf9e14e03e6abc82c0af3f6354e37911600684611e6d610577565b611c88600435600160a060020a038116600090815260126020526040902054610898565b611c9a600054600160a060020a03166104ee565b604080516c01000000000000000000000000600435600160a060020a0390811682028352331602601482015281516028918190039190910190206000908152601560205220805460ff191690555b005b611c8860007327b1b436e4699a012cc8698e33c8f3e1c035c28b6398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b611c88600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152601060048201527f3e3d000000000000000000000000000000000000000000000000000000000000602482015260448101839052905160009173ce642b6a82e72147ceade0e72c786ba8eaeb31d79163e6ce3a6a916064818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c88604080517f8f00e61a00000000000000000000000000000000000000000000000000000000815260066004820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f91638f00e61a916024818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b611c886004356000611e113383610f5f565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63dd382dd36000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63aebd65476000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c886004356040805160e560020a6304b47bb902815260066004820152600160a060020a0383166024820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163968f7720916044818101926020929091908290030181878760325a03f2156100025750506040515191506108989050565b611c88604080517fc75e8f8800000000000000000000000000000000000000000000000000000000815260066004820152905160009173c895c144d0b0f88417cf9e14e03e6abc82c0af3f9163c75e8f88916024818101926020929091908290030181878760325a03f2156100025750506040515191506104ee9050565b611cb760408051602081810183526000825282516003805460026000196001831615610100020190911604601f81018490048402830184019095528482529293909291830182828015611fef5780601f10611fc457610100808354040283529160200191611fef565b611264604080517fa89713750000000000000000000000000000000000000000000000000000000081526000600482018181526024830193845236604484018190527327b1b436e4699a012cc8698e33c8f3e1c035c28b9463a89713759484939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050604080516005547f321f45840000000000000000000000000000000000000000000000000000000082526004820152905163321f4584916024818101926000929091908290030181838760325a03f21561000257505050565b611c886004356000818152600e6020526040902060030154610898565b611c8860007327b1b436e4699a012cc8698e33c8f3e1c035c28b63c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b61126460043573c895c144d0b0f88417cf9e14e03e6abc82c0af3f63dd8abb6c60063384611db7610577565b611c88600073c895c144d0b0f88417cf9e14e03e6abc82c0af3f6354e37911600633611e18610577565b611c886007546104ee565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63125935846000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b6112646102ee565b611c886004356000818152601360209081526040805181842060038101546004828101547f38f4c9eb0000000000000000000000000000000000000000000000000000000085526006918501919091526024840182905260ff160160448301529151919273c895c144d0b0f88417cf9e14e03e6abc82c0af3f926338f4c9eb9260648181019392918290030181888760325a03f21561000257505060405151949350505050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63fae644646000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63b3a5e2556000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c886006546104ee565b6112646004355b604080517fb1df3d8000000000000000000000000000000000000000000000000000000000815260126004820152600160a060020a0383166024820152346044820152905173d3cb18959b0435864ff33010fa83be60afc04b229163b1df3d80916064828101926020929190829003018160008760325a03f215610002575050604080517f5548c837000000000000000000000000000000000000000000000000000000008152600160a060020a033381166004830152841660248201523460448201529051635548c837916064818101926000929091908290030181838760325a03f215610002575050505b50565b611264600435602435604435606435611ffb8484848460ff6000610a89565b611c886004356000818152600e6020526040902060010154610898565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b63c9abdb7c6000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611c8860043560007327b1b436e4699a012cc8698e33c8f3e1c035c28b6386b0aac96000600050846040518360e060020a028152600401808381526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515191506108989050565b611264600435604080517f25fea09900000000000000000000000000000000000000000000000000000000815260006004820181905260248201849052600160a060020a033316604483015291517327b1b436e4699a012cc8698e33c8f3e1c035c28b926325fea09992606481810193918290030181838760325a03f2156100025750505050565b565b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f168015611d175780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600160a060020a0333166000818152601260205260408051818320547f5c54305e00000000000000000000000000000000000000000000000000000000825260048201949094526024810185905260448101939093525173d3cb18959b0435864ff33010fa83be60afc04b2292635c54305e9260648281019391928290030181838760325a03f2156100025750505050565b6040518560e060020a0281526004018085815260200184600160a060020a0316815260200183815260200182815260200194505050505060006040518083038160008760325a03f2156100025750505050565b90506104ee565b9050610898565b6040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506104ee9050565b6040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506108989050565b6040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040805180517f6a704d7b000000000000000000000000000000000000000000000000000000008252600160a060020a033316600483015260248201819052915191935073c895c144d0b0f88417cf9e14e03e6abc82c0af3f9250636a704d7b9160448281019260009291908290030181838760325a03f2156100025750505050565b820191906000526020600020905b815481529060010190602001808311611f9b57829003601f168201915b50505050509050610898565b820191906000526020600020905b815481529060010190602001808311611fd257829003601f168201915b505050505090506104ee565b50505050565b5050505050565b7327b1b436e4699a012cc8698e33c8f3e1c035c28b635ca1bad5826040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f215610002575050505b505050505050505056", - "storage": { - "0x18b039f13c5f33908f0960616cb3e44029c716366508c54d555096d6e1fa5145": "0x00000000000000000000000000000000000000000000000008b83c417dd78000" - } - }, - "0xd3cb18959b0435864ff33010fa83be60afc04b22": { - "balance": "0x0", - "code": "0x650105e11e10f850606060405236156100695760e060020a60003504635548c837811461006e5780635c54305e146100ca5780636b1039661461011e5780637fcf532c14610152578063b1df3d801461019e578063b5bc6dbb146101b7578063e62af6c1146101ee575b610007565b61022060043560243560443581600160a060020a031683600160a060020a03167f47a08955ce2b7f21ea62ff0024e1ea0ad87430953554a87e6bc65d777f18e639836040518082815260200191505060405180910390a3505050565b61022060043560243560443560408051838152602081018390528151600160a060020a038616927f9b24879829bed3003de08d5c5d7e18dcbb8dc76faebd95cafc5d4dec8c61a3a5928290030190a2505050565b6102206004356024356044355b600160a060020a038216600090815260208490526040902054808201101561023457610007565b610220600435602435604080518281529051600160a060020a038416917fd0c5cf41ee8ebf084ad0bce53de7cbc6e4693d9b53a4019ca36a2f91cdc20b3a919081900360200190a25050565b610222600435602435604435600061025784848461012b565b610222600435602435604435600160a060020a0382166000908152602084905260408120548290106102865761028e8484846101fb565b6102206004356024356044355b600160a060020a03821660009081526020849052604090205481111561026257610007565b005b60408051918252519081900360200190f35b600160a060020a0382166000908152602084905260409020805482019055505050565b5060015b9392505050565b600160a060020a038216600090815260208490526040902080548290039055505050565b50600061025b565b604051600160a060020a03841690600090849082818181858883f19350505050151561025757604051600160a060020a038416908390600081818185876185025a03f19250505015156102575761000756" - }, - "0xd3cda913deb6f67967b99d67acdfa1712c293601": { - "balance": "0x1ff0509d9d6821e26", - "nonce": "138", - "code": "0x" - } - }, - "config": { - "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip150Hash": "0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0", - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "ethash": {} - } - }, - "context": { - "number": "422909", - "difficulty": "5694909537365", - "timestamp": "1445530357", - "gasLimit": "3141592", - "miner": "0x2a65aca4d5fc5b5c859090a6c34d164135398226" - }, - "input": "0xf86a818a850ba43b7400832d8a40942861bf89b6c640c79040d357c1e9513693ef5d3f808441c0e1b51ca0b8de64a9a04d699f5938efa5431ca7c80500f6accb329da43aadabd4eab84f17a035b969c198f694be991a2a5b287250e19e852efd0ccba30bd50707277bfbc9aa", - "tracerConfig": { - "diffMode": true - }, - "result": { - "pre": { - "0x2861bf89b6c640c79040d357c1e9513693ef5d3f": { - "balance": "0x0", - "code": "0x606060405236156100825760e060020a600035046312055e8f8114610084578063185061da146100b157806322beb9b9146100d5578063245a03ec146101865780633fa4f245146102a657806341c0e1b5146102af578063890eba68146102cb578063b29f0835146102de578063d6b4485914610308578063dd012a15146103b9575b005b6001805474ff0000000000000000000000000000000000000000191660a060020a60043502179055610082565b6100826001805475ff00000000000000000000000000000000000000000019169055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527fb29f0835000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b6100826004356024356001547fb0f07e440000000000000000000000000000000000000000000000000000000060609081526064839052600160a060020a039091169063b0f07e449060849060009060248183876161da5a03f150604080516001547f73657449742875696e74323536290000000000000000000000000000000000008252825191829003600e018220878352835192839003602001832060e060020a6352afbc33028452600160a060020a03308116600486015260e060020a9283900490920260248501526044840152438901606484015260a060020a820460ff1694830194909452600060a483018190529251931694506352afbc33935060c48181019391829003018183876161da5a03f115610002575050505050565b6103c460025481565b61008260005433600160a060020a039081169116146103ce575b565b6103c460015460a860020a900460ff1681565b6100826001805475ff000000000000000000000000000000000000000000191660a860020a179055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527f185061da000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b600435600255610082565b6060908152602090f35b6001547f6ff96d17000000000000000000000000000000000000000000000000000000006060908152600160a060020a0330811660645290911690632e1a7d4d908290636ff96d17906084906020906024816000876161da5a03f1156100025750506040805180517f2e1a7d4d0000000000000000000000000000000000000000000000000000000082526004820152905160248281019350600092829003018183876161da5a03f115610002575050600054600160a060020a03169050ff", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000ff30c9e568f133adce1f1ea91e189613223fc461b9" - } - }, - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x326601cc6cf364f6b9", - "nonce": 12122 - }, - "0xd3cda913deb6f67967b99d67acdfa1712c293601": { - "balance": "0x1ff0509d9d6821e26", - "nonce": 138 - } - }, - "post": { - "0x2a65aca4d5fc5b5c859090a6c34d164135398226": { - "balance": "0x326604ee5f5eecd2b9" - }, - "0xd3cda913deb6f67967b99d67acdfa1712c293601": { - "balance": "0x1ff01e7e76afa4226", - "nonce": 139 - } - } - } -} diff --git a/eth/tracers/internal/tracetest/util.go b/eth/tracers/internal/tracetest/util.go deleted file mode 100644 index 3cecbf84ab..0000000000 --- a/eth/tracers/internal/tracetest/util.go +++ /dev/null @@ -1,81 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -package tracetest - -import ( - "strings" - "unicode" - - // Force-load native and js packages, to trigger registration - _ "github.com/ava-labs/coreth/eth/tracers/js" - _ "github.com/ava-labs/coreth/eth/tracers/native" -) - -// To generate a new callTracer test, copy paste the makeTest method below into -// a Geth console and call it with a transaction hash you which to export. - -/* -// makeTest generates a callTracer test by running a prestate reassembled and a -// call trace run, assembling all the gathered information into a test case. -var makeTest = function(tx, rewind) { - // Generate the genesis block from the block, transaction and prestate data - var block = eth.getBlock(eth.getTransaction(tx).blockHash); - var genesis = eth.getBlock(block.parentHash); - - delete genesis.gasUsed; - delete genesis.logsBloom; - delete genesis.parentHash; - delete genesis.receiptsRoot; - delete genesis.sha3Uncles; - delete genesis.size; - delete genesis.transactions; - delete genesis.transactionsRoot; - delete genesis.uncles; - - genesis.gasLimit = genesis.gasLimit.toString(); - genesis.number = genesis.number.toString(); - genesis.timestamp = genesis.timestamp.toString(); - - genesis.alloc = debug.traceTransaction(tx, {tracer: "prestateTracer", rewind: rewind}); - for (var key in genesis.alloc) { - var nonce = genesis.alloc[key].nonce; - if (nonce) { - genesis.alloc[key].nonce = nonce.toString(); - } - } - genesis.config = admin.nodeInfo.protocols.eth.config; - - // Generate the call trace and produce the test input - var result = debug.traceTransaction(tx, {tracer: "callTracer", rewind: rewind}); - delete result.time; - - console.log(JSON.stringify({ - genesis: genesis, - context: { - number: block.number.toString(), - difficulty: block.difficulty, - timestamp: block.timestamp.toString(), - gasLimit: block.gasLimit.toString(), - miner: block.miner, - }, - input: eth.getRawTransaction(tx), - result: result, - }, null, 2)); -} -*/ - -// camel converts a snake cased input string into a camel cased output. -func camel(str string) string { - pieces := strings.Split(str, "_") - for i := 1; i < len(pieces); i++ { - pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:] - } - return strings.Join(pieces, "") -} diff --git a/eth/tracers/js/bigint.go b/eth/tracers/js/bigint.go deleted file mode 100644 index aa3f44e255..0000000000 --- a/eth/tracers/js/bigint.go +++ /dev/null @@ -1,30 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package js - -// bigIntegerJS is the minified version of https://github.com/peterolson/BigInteger.js. -const bigIntegerJS = `var bigInt=function(undefined){"use strict";var BASE=1e7,LOG_BASE=7,MAX_INT=9007199254740992,MAX_INT_ARR=smallToArray(MAX_INT),LOG_MAX_INT=Math.log(MAX_INT);function Integer(v,radix){if(typeof v==="undefined")return Integer[0];if(typeof radix!=="undefined")return+radix===10?parseValue(v):parseBase(v,radix);return parseValue(v)}function BigInteger(value,sign){this.value=value;this.sign=sign;this.isSmall=false}BigInteger.prototype=Object.create(Integer.prototype);function SmallInteger(value){this.value=value;this.sign=value<0;this.isSmall=true}SmallInteger.prototype=Object.create(Integer.prototype);function isPrecise(n){return-MAX_INT0)return Math.floor(n);return Math.ceil(n)}function add(a,b){var l_a=a.length,l_b=b.length,r=new Array(l_a),carry=0,base=BASE,sum,i;for(i=0;i=base?1:0;r[i]=sum-carry*base}while(i0)r.push(carry);return r}function addAny(a,b){if(a.length>=b.length)return add(a,b);return add(b,a)}function addSmall(a,carry){var l=a.length,r=new Array(l),base=BASE,sum,i;for(i=0;i0){r[i++]=carry%base;carry=Math.floor(carry/base)}return r}BigInteger.prototype.add=function(v){var n=parseValue(v);if(this.sign!==n.sign){return this.subtract(n.negate())}var a=this.value,b=n.value;if(n.isSmall){return new BigInteger(addSmall(a,Math.abs(b)),this.sign)}return new BigInteger(addAny(a,b),this.sign)};BigInteger.prototype.plus=BigInteger.prototype.add;SmallInteger.prototype.add=function(v){var n=parseValue(v);var a=this.value;if(a<0!==n.sign){return this.subtract(n.negate())}var b=n.value;if(n.isSmall){if(isPrecise(a+b))return new SmallInteger(a+b);b=smallToArray(Math.abs(b))}return new BigInteger(addSmall(b,Math.abs(a)),a<0)};SmallInteger.prototype.plus=SmallInteger.prototype.add;function subtract(a,b){var a_l=a.length,b_l=b.length,r=new Array(a_l),borrow=0,base=BASE,i,difference;for(i=0;i=0){value=subtract(a,b)}else{value=subtract(b,a);sign=!sign}value=arrayToSmall(value);if(typeof value==="number"){if(sign)value=-value;return new SmallInteger(value)}return new BigInteger(value,sign)}function subtractSmall(a,b,sign){var l=a.length,r=new Array(l),carry=-b,base=BASE,i,difference;for(i=0;i=0)};SmallInteger.prototype.minus=SmallInteger.prototype.subtract;BigInteger.prototype.negate=function(){return new BigInteger(this.value,!this.sign)};SmallInteger.prototype.negate=function(){var sign=this.sign;var small=new SmallInteger(-this.value);small.sign=!sign;return small};BigInteger.prototype.abs=function(){return new BigInteger(this.value,false)};SmallInteger.prototype.abs=function(){return new SmallInteger(Math.abs(this.value))};function multiplyLong(a,b){var a_l=a.length,b_l=b.length,l=a_l+b_l,r=createArray(l),base=BASE,product,carry,i,a_i,b_j;for(i=0;i0){r[i++]=carry%base;carry=Math.floor(carry/base)}return r}function shiftLeft(x,n){var r=[];while(n-- >0)r.push(0);return r.concat(x)}function multiplyKaratsuba(x,y){var n=Math.max(x.length,y.length);if(n<=30)return multiplyLong(x,y);n=Math.ceil(n/2);var b=x.slice(n),a=x.slice(0,n),d=y.slice(n),c=y.slice(0,n);var ac=multiplyKaratsuba(a,c),bd=multiplyKaratsuba(b,d),abcd=multiplyKaratsuba(addAny(a,b),addAny(c,d));var product=addAny(addAny(ac,shiftLeft(subtract(subtract(abcd,ac),bd),n)),shiftLeft(bd,2*n));trim(product);return product}function useKaratsuba(l1,l2){return-.012*l1-.012*l2+15e-6*l1*l2>0}BigInteger.prototype.multiply=function(v){var n=parseValue(v),a=this.value,b=n.value,sign=this.sign!==n.sign,abs;if(n.isSmall){if(b===0)return Integer[0];if(b===1)return this;if(b===-1)return this.negate();abs=Math.abs(b);if(abs=0;shift--){quotientDigit=base-1;if(remainder[shift+b_l]!==divisorMostSignificantDigit){quotientDigit=Math.floor((remainder[shift+b_l]*base+remainder[shift+b_l-1])/divisorMostSignificantDigit)}carry=0;borrow=0;l=divisor.length;for(i=0;ib_l){highx=(highx+1)*base}guess=Math.ceil(highx/highy);do{check=multiplySmall(b,guess);if(compareAbs(check,part)<=0)break;guess--}while(guess);result.push(guess);part=subtract(part,check)}result.reverse();return[arrayToSmall(result),arrayToSmall(part)]}function divModSmall(value,lambda){var length=value.length,quotient=createArray(length),base=BASE,i,q,remainder,divisor;remainder=0;for(i=length-1;i>=0;--i){divisor=remainder*base+value[i];q=truncate(divisor/lambda);remainder=divisor-q*lambda;quotient[i]=q|0}return[quotient,remainder|0]}function divModAny(self,v){var value,n=parseValue(v);var a=self.value,b=n.value;var quotient;if(b===0)throw new Error("Cannot divide by zero");if(self.isSmall){if(n.isSmall){return[new SmallInteger(truncate(a/b)),new SmallInteger(a%b)]}return[Integer[0],self]}if(n.isSmall){if(b===1)return[self,Integer[0]];if(b==-1)return[self.negate(),Integer[0]];var abs=Math.abs(b);if(absb.length?1:-1}for(var i=a.length-1;i>=0;i--){if(a[i]!==b[i])return a[i]>b[i]?1:-1}return 0}BigInteger.prototype.compareAbs=function(v){var n=parseValue(v),a=this.value,b=n.value;if(n.isSmall)return 1;return compareAbs(a,b)};SmallInteger.prototype.compareAbs=function(v){var n=parseValue(v),a=Math.abs(this.value),b=n.value;if(n.isSmall){b=Math.abs(b);return a===b?0:a>b?1:-1}return-1};BigInteger.prototype.compare=function(v){if(v===Infinity){return-1}if(v===-Infinity){return 1}var n=parseValue(v),a=this.value,b=n.value;if(this.sign!==n.sign){return n.sign?1:-1}if(n.isSmall){return this.sign?-1:1}return compareAbs(a,b)*(this.sign?-1:1)};BigInteger.prototype.compareTo=BigInteger.prototype.compare;SmallInteger.prototype.compare=function(v){if(v===Infinity){return-1}if(v===-Infinity){return 1}var n=parseValue(v),a=this.value,b=n.value;if(n.isSmall){return a==b?0:a>b?1:-1}if(a<0!==n.sign){return a<0?-1:1}return a<0?1:-1};SmallInteger.prototype.compareTo=SmallInteger.prototype.compare;BigInteger.prototype.equals=function(v){return this.compare(v)===0};SmallInteger.prototype.eq=SmallInteger.prototype.equals=BigInteger.prototype.eq=BigInteger.prototype.equals;BigInteger.prototype.notEquals=function(v){return this.compare(v)!==0};SmallInteger.prototype.neq=SmallInteger.prototype.notEquals=BigInteger.prototype.neq=BigInteger.prototype.notEquals;BigInteger.prototype.greater=function(v){return this.compare(v)>0};SmallInteger.prototype.gt=SmallInteger.prototype.greater=BigInteger.prototype.gt=BigInteger.prototype.greater;BigInteger.prototype.lesser=function(v){return this.compare(v)<0};SmallInteger.prototype.lt=SmallInteger.prototype.lesser=BigInteger.prototype.lt=BigInteger.prototype.lesser;BigInteger.prototype.greaterOrEquals=function(v){return this.compare(v)>=0};SmallInteger.prototype.geq=SmallInteger.prototype.greaterOrEquals=BigInteger.prototype.geq=BigInteger.prototype.greaterOrEquals;BigInteger.prototype.lesserOrEquals=function(v){return this.compare(v)<=0};SmallInteger.prototype.leq=SmallInteger.prototype.lesserOrEquals=BigInteger.prototype.leq=BigInteger.prototype.lesserOrEquals;BigInteger.prototype.isEven=function(){return(this.value[0]&1)===0};SmallInteger.prototype.isEven=function(){return(this.value&1)===0};BigInteger.prototype.isOdd=function(){return(this.value[0]&1)===1};SmallInteger.prototype.isOdd=function(){return(this.value&1)===1};BigInteger.prototype.isPositive=function(){return!this.sign};SmallInteger.prototype.isPositive=function(){return this.value>0};BigInteger.prototype.isNegative=function(){return this.sign};SmallInteger.prototype.isNegative=function(){return this.value<0};BigInteger.prototype.isUnit=function(){return false};SmallInteger.prototype.isUnit=function(){return Math.abs(this.value)===1};BigInteger.prototype.isZero=function(){return false};SmallInteger.prototype.isZero=function(){return this.value===0};BigInteger.prototype.isDivisibleBy=function(v){var n=parseValue(v);var value=n.value;if(value===0)return false;if(value===1)return true;if(value===2)return this.isEven();return this.mod(n).equals(Integer[0])};SmallInteger.prototype.isDivisibleBy=BigInteger.prototype.isDivisibleBy;function isBasicPrime(v){var n=v.abs();if(n.isUnit())return false;if(n.equals(2)||n.equals(3)||n.equals(5))return true;if(n.isEven()||n.isDivisibleBy(3)||n.isDivisibleBy(5))return false;if(n.lesser(25))return true}BigInteger.prototype.isPrime=function(){var isPrime=isBasicPrime(this);if(isPrime!==undefined)return isPrime;var n=this.abs(),nPrev=n.prev();var a=[2,3,5,7,11,13,17,19],b=nPrev,d,t,i,x;while(b.isEven())b=b.divide(2);for(i=0;i-MAX_INT)return new SmallInteger(value-1);return new BigInteger(MAX_INT_ARR,true)};var powersOfTwo=[1];while(2*powersOfTwo[powersOfTwo.length-1]<=BASE)powersOfTwo.push(2*powersOfTwo[powersOfTwo.length-1]);var powers2Length=powersOfTwo.length,highestPower2=powersOfTwo[powers2Length-1];function shift_isSmall(n){return(typeof n==="number"||typeof n==="string")&&+Math.abs(n)<=BASE||n instanceof BigInteger&&n.value.length<=1}BigInteger.prototype.shiftLeft=function(n){if(!shift_isSmall(n)){throw new Error(String(n)+" is too large for shifting.")}n=+n;if(n<0)return this.shiftRight(-n);var result=this;while(n>=powers2Length){result=result.multiply(highestPower2);n-=powers2Length-1}return result.multiply(powersOfTwo[n])};SmallInteger.prototype.shiftLeft=BigInteger.prototype.shiftLeft;BigInteger.prototype.shiftRight=function(n){var remQuo;if(!shift_isSmall(n)){throw new Error(String(n)+" is too large for shifting.")}n=+n;if(n<0)return this.shiftLeft(-n);var result=this;while(n>=powers2Length){if(result.isZero())return result;remQuo=divModAny(result,highestPower2);result=remQuo[1].isNegative()?remQuo[0].prev():remQuo[0];n-=powers2Length-1}remQuo=divModAny(result,powersOfTwo[n]);return remQuo[1].isNegative()?remQuo[0].prev():remQuo[0]};SmallInteger.prototype.shiftRight=BigInteger.prototype.shiftRight;function bitwise(x,y,fn){y=parseValue(y);var xSign=x.isNegative(),ySign=y.isNegative();var xRem=xSign?x.not():x,yRem=ySign?y.not():y;var xDigit=0,yDigit=0;var xDivMod=null,yDivMod=null;var result=[];while(!xRem.isZero()||!yRem.isZero()){xDivMod=divModAny(xRem,highestPower2);xDigit=xDivMod[1].toJSNumber();if(xSign){xDigit=highestPower2-1-xDigit}yDivMod=divModAny(yRem,highestPower2);yDigit=yDivMod[1].toJSNumber();if(ySign){yDigit=highestPower2-1-yDigit}xRem=xDivMod[0];yRem=yDivMod[0];result.push(fn(xDigit,yDigit))}var sum=fn(xSign?1:0,ySign?1:0)!==0?bigInt(-1):bigInt(0);for(var i=result.length-1;i>=0;i-=1){sum=sum.multiply(highestPower2).add(bigInt(result[i]))}return sum}BigInteger.prototype.not=function(){return this.negate().prev()};SmallInteger.prototype.not=BigInteger.prototype.not;BigInteger.prototype.and=function(n){return bitwise(this,n,function(a,b){return a&b})};SmallInteger.prototype.and=BigInteger.prototype.and;BigInteger.prototype.or=function(n){return bitwise(this,n,function(a,b){return a|b})};SmallInteger.prototype.or=BigInteger.prototype.or;BigInteger.prototype.xor=function(n){return bitwise(this,n,function(a,b){return a^b})};SmallInteger.prototype.xor=BigInteger.prototype.xor;var LOBMASK_I=1<<30,LOBMASK_BI=(BASE&-BASE)*(BASE&-BASE)|LOBMASK_I;function roughLOB(n){var v=n.value,x=typeof v==="number"?v|LOBMASK_I:v[0]+v[1]*BASE|LOBMASK_BI;return x&-x}function max(a,b){a=parseValue(a);b=parseValue(b);return a.greater(b)?a:b}function min(a,b){a=parseValue(a);b=parseValue(b);return a.lesser(b)?a:b}function gcd(a,b){a=parseValue(a).abs();b=parseValue(b).abs();if(a.equals(b))return a;if(a.isZero())return b;if(b.isZero())return a;var c=Integer[1],d,t;while(a.isEven()&&b.isEven()){d=Math.min(roughLOB(a),roughLOB(b));a=a.divide(d);b=b.divide(d);c=c.multiply(d)}while(a.isEven()){a=a.divide(roughLOB(a))}do{while(b.isEven()){b=b.divide(roughLOB(b))}if(a.greater(b)){t=b;b=a;a=t}b=b.subtract(a)}while(!b.isZero());return c.isUnit()?a:a.multiply(c)}function lcm(a,b){a=parseValue(a).abs();b=parseValue(b).abs();return a.divide(gcd(a,b)).multiply(b)}function randBetween(a,b){a=parseValue(a);b=parseValue(b);var low=min(a,b),high=max(a,b);var range=high.subtract(low).add(1);if(range.isSmall)return low.add(Math.floor(Math.random()*range));var length=range.value.length-1;var result=[],restricted=true;for(var i=length;i>=0;i--){var top=restricted?range.value[i]:BASE;var digit=truncate(Math.random()*top);result.unshift(digit);if(digit=absBase){if(c==="1"&&absBase===1)continue;throw new Error(c+" is not a valid digit in base "+base+".")}else if(c.charCodeAt(0)-87>=absBase){throw new Error(c+" is not a valid digit in base "+base+".")}}}if(2<=base&&base<=36){if(length<=LOG_MAX_INT/Math.log(base)){var result=parseInt(text,base);if(isNaN(result)){throw new Error(c+" is not a valid digit in base "+base+".")}return new SmallInteger(parseInt(text,base))}}base=parseValue(base);var digits=[];var isNegative=text[0]==="-";for(i=isNegative?1:0;i");digits.push(parseValue(text.slice(start+1,i)))}else throw new Error(c+" is not a valid character")}return parseBaseFromArray(digits,base,isNegative)};function parseBaseFromArray(digits,base,isNegative){var val=Integer[0],pow=Integer[1],i;for(i=digits.length-1;i>=0;i--){val=val.add(digits[i].times(pow));pow=pow.times(base)}return isNegative?val.negate():val}function stringify(digit){var v=digit.value;if(typeof v==="number")v=[v];if(v.length===1&&v[0]<=35){return"0123456789abcdefghijklmnopqrstuvwxyz".charAt(v[0])}return"<"+v+">"}function toBase(n,base){base=bigInt(base);if(base.isZero()){if(n.isZero())return"0";throw new Error("Cannot convert nonzero numbers to base 0.")}if(base.equals(-1)){if(n.isZero())return"0";if(n.isNegative())return new Array(1-n).join("10");return"1"+new Array(+n).join("01")}var minusSign="";if(n.isNegative()&&base.isPositive()){minusSign="-";n=n.abs()}if(base.equals(1)){if(n.isZero())return"0";return minusSign+new Array(+n+1).join(1)}var out=[];var left=n,divmod;while(left.isNegative()||left.compareAbs(base)>=0){divmod=left.divmod(base);left=divmod.quotient;var digit=divmod.remainder;if(digit.isNegative()){digit=base.minus(digit).abs();left=left.next()}out.push(stringify(digit))}out.push(stringify(left));return minusSign+out.reverse().join("")}BigInteger.prototype.toString=function(radix){if(radix===undefined)radix=10;if(radix!==10)return toBase(this,radix);var v=this.value,l=v.length,str=String(v[--l]),zeros="0000000",digit;while(--l>=0){digit=String(v[l]);str+=zeros.slice(digit.length)+digit}var sign=this.sign?"-":"";return sign+str};SmallInteger.prototype.toString=function(radix){if(radix===undefined)radix=10;if(radix!=10)return toBase(this,radix);return String(this.value)};BigInteger.prototype.toJSON=SmallInteger.prototype.toJSON=function(){return this.toString()};BigInteger.prototype.valueOf=function(){return+this.toString()};BigInteger.prototype.toJSNumber=BigInteger.prototype.valueOf;SmallInteger.prototype.valueOf=function(){return this.value};SmallInteger.prototype.toJSNumber=SmallInteger.prototype.valueOf;function parseStringValue(v){if(isPrecise(+v)){var x=+v;if(x===truncate(x))return new SmallInteger(x);throw"Invalid integer: "+v}var sign=v[0]==="-";if(sign)v=v.slice(1);var split=v.split(/e/i);if(split.length>2)throw new Error("Invalid integer: "+split.join("e"));if(split.length===2){var exp=split[1];if(exp[0]==="+")exp=exp.slice(1);exp=+exp;if(exp!==truncate(exp)||!isPrecise(exp))throw new Error("Invalid integer: "+exp+" is not a valid exponent.");var text=split[0];var decimalPlace=text.indexOf(".");if(decimalPlace>=0){exp-=text.length-decimalPlace-1;text=text.slice(0,decimalPlace)+text.slice(decimalPlace+1)}if(exp<0)throw new Error("Cannot include negative exponent part for integers");text+=new Array(exp+1).join("0");v=text}var isValid=/^([0-9][0-9]*)$/.test(v);if(!isValid)throw new Error("Invalid integer: "+v);var r=[],max=v.length,l=LOG_BASE,min=max-l;while(max>0){r.push(+v.slice(min,max));min-=l;if(min<0)min=0;max-=l}trim(r);return new BigInteger(r,sign)}function parseNumberValue(v){if(isPrecise(v)){if(v!==truncate(v))throw new Error(v+" is not an integer.");return new SmallInteger(v)}return parseStringValue(v.toString())}function parseValue(v){if(typeof v==="number"){return parseNumberValue(v)}if(typeof v==="string"){return parseStringValue(v)}return v}for(var i=0;i<1e3;i++){Integer[i]=new SmallInteger(i);if(i>0)Integer[-i]=new SmallInteger(-i)}Integer.one=Integer[1];Integer.zero=Integer[0];Integer.minusOne=Integer[-1];Integer.max=max;Integer.min=min;Integer.gcd=gcd;Integer.lcm=lcm;Integer.isInstance=function(x){return x instanceof BigInteger||x instanceof SmallInteger};Integer.randBetween=randBetween;Integer.fromArray=function(digits,base,isNegative){return parseBaseFromArray(digits.map(parseValue),parseValue(base||10),isNegative)};return Integer}();if(typeof module!=="undefined"&&module.hasOwnProperty("exports")){module.exports=bigInt}if(typeof define==="function"&&define.amd){define("big-integer",[],function(){return bigInt})}; bigInt` diff --git a/eth/tracers/js/goja.go b/eth/tracers/js/goja.go deleted file mode 100644 index 92b9beeed4..0000000000 --- a/eth/tracers/js/goja.go +++ /dev/null @@ -1,1002 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package js - -import ( - "encoding/json" - "errors" - "fmt" - "math/big" - - "github.com/dop251/goja" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - jsassets "github.com/ava-labs/coreth/eth/tracers/js/internal/tracers" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" -) - -var assetTracers = make(map[string]string) - -// init retrieves the JavaScript transaction tracers included in go-ethereum. -func init() { - var err error - assetTracers, err = jsassets.Load() - if err != nil { - panic(err) - } - type ctorFn = func(*tracers.Context, json.RawMessage) (tracers.Tracer, error) - lookup := func(code string) ctorFn { - return func(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { - return newJsTracer(code, ctx, cfg) - } - } - for name, code := range assetTracers { - tracers.DefaultDirectory.Register(name, lookup(code), true) - } - tracers.DefaultDirectory.RegisterJSEval(newJsTracer) -} - -// bigIntProgram is compiled once and the exported function mostly invoked to convert -// hex strings into big ints. -var bigIntProgram = goja.MustCompile("bigInt", bigIntegerJS, false) - -type toBigFn = func(vm *goja.Runtime, val string) (goja.Value, error) -type toBufFn = func(vm *goja.Runtime, val []byte) (goja.Value, error) -type fromBufFn = func(vm *goja.Runtime, buf goja.Value, allowString bool) ([]byte, error) - -func toBuf(vm *goja.Runtime, bufType goja.Value, val []byte) (goja.Value, error) { - // bufType is usually Uint8Array. This is equivalent to `new Uint8Array(val)` in JS. - return vm.New(bufType, vm.ToValue(vm.NewArrayBuffer(val))) -} - -func fromBuf(vm *goja.Runtime, bufType goja.Value, buf goja.Value, allowString bool) ([]byte, error) { - obj := buf.ToObject(vm) - switch obj.ClassName() { - case "String": - if !allowString { - break - } - return common.FromHex(obj.String()), nil - - case "Array": - var b []byte - if err := vm.ExportTo(buf, &b); err != nil { - return nil, err - } - return b, nil - - case "Object": - if !obj.Get("constructor").SameAs(bufType) { - break - } - b := obj.Export().([]byte) - return b, nil - } - return nil, errors.New("invalid buffer type") -} - -// jsTracer is an implementation of the Tracer interface which evaluates -// JS functions on the relevant EVM hooks. It uses Goja as its JS engine. -type jsTracer struct { - vm *goja.Runtime - env *vm.EVM - toBig toBigFn // Converts a hex string into a JS bigint - toBuf toBufFn // Converts a []byte into a JS buffer - fromBuf fromBufFn // Converts an array, hex string or Uint8Array to a []byte - ctx map[string]goja.Value // KV-bag passed to JS in `result` - activePrecompiles []common.Address // List of active precompiles at current block - traceStep bool // True if tracer object exposes a `step()` method - traceFrame bool // True if tracer object exposes the `enter()` and `exit()` methods - gasLimit uint64 // Amount of gas bought for the whole tx - err error // Any error that should stop tracing - obj *goja.Object // Trace object - - // Methods exposed by tracer - result goja.Callable - fault goja.Callable - step goja.Callable - enter goja.Callable - exit goja.Callable - - // Underlying structs being passed into JS - log *steplog - frame *callframe - frameResult *callframeResult - - // Goja-wrapping of types prepared for JS consumption - logValue goja.Value - dbValue goja.Value - frameValue goja.Value - frameResultValue goja.Value -} - -// newJsTracer instantiates a new JS tracer instance. code is a -// Javascript snippet which evaluates to an expression returning -// an object with certain methods: -// -// The methods `result` and `fault` are required to be present. -// The methods `step`, `enter`, and `exit` are optional, but note that -// `enter` and `exit` always go together. -func newJsTracer(code string, ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { - vm := goja.New() - // By default field names are exported to JS as is, i.e. capitalized. - vm.SetFieldNameMapper(goja.UncapFieldNameMapper()) - t := &jsTracer{ - vm: vm, - ctx: make(map[string]goja.Value), - } - - t.setTypeConverters() - t.setBuiltinFunctions() - - if ctx == nil { - ctx = new(tracers.Context) - } - if ctx.BlockHash != (common.Hash{}) { - blockHash, err := t.toBuf(vm, ctx.BlockHash.Bytes()) - if err != nil { - return nil, err - } - t.ctx["blockHash"] = blockHash - if ctx.TxHash != (common.Hash{}) { - t.ctx["txIndex"] = vm.ToValue(ctx.TxIndex) - txHash, err := t.toBuf(vm, ctx.TxHash.Bytes()) - if err != nil { - return nil, err - } - t.ctx["txHash"] = txHash - } - } - - ret, err := vm.RunString("(" + code + ")") - if err != nil { - return nil, err - } - // Check tracer's interface for required and optional methods. - obj := ret.ToObject(vm) - result, ok := goja.AssertFunction(obj.Get("result")) - if !ok { - return nil, errors.New("trace object must expose a function result()") - } - fault, ok := goja.AssertFunction(obj.Get("fault")) - if !ok { - return nil, errors.New("trace object must expose a function fault()") - } - step, ok := goja.AssertFunction(obj.Get("step")) - t.traceStep = ok - enter, hasEnter := goja.AssertFunction(obj.Get("enter")) - exit, hasExit := goja.AssertFunction(obj.Get("exit")) - if hasEnter != hasExit { - return nil, errors.New("trace object must expose either both or none of enter() and exit()") - } - t.traceFrame = hasEnter - t.obj = obj - t.step = step - t.enter = enter - t.exit = exit - t.result = result - t.fault = fault - - // Pass in config - if setup, ok := goja.AssertFunction(obj.Get("setup")); ok { - cfgStr := "{}" - if cfg != nil { - cfgStr = string(cfg) - } - if _, err := setup(obj, vm.ToValue(cfgStr)); err != nil { - return nil, err - } - } - // Setup objects carrying data to JS. These are created once and re-used. - t.log = &steplog{ - vm: vm, - op: &opObj{vm: vm}, - memory: &memoryObj{vm: vm, toBig: t.toBig, toBuf: t.toBuf}, - stack: &stackObj{vm: vm, toBig: t.toBig}, - contract: &contractObj{vm: vm, toBig: t.toBig, toBuf: t.toBuf}, - } - t.frame = &callframe{vm: vm, toBig: t.toBig, toBuf: t.toBuf} - t.frameResult = &callframeResult{vm: vm, toBuf: t.toBuf} - t.frameValue = t.frame.setupObject() - t.frameResultValue = t.frameResult.setupObject() - t.logValue = t.log.setupObject() - return t, nil -} - -// CaptureTxStart implements the Tracer interface and is invoked at the beginning of -// transaction processing. -func (t *jsTracer) CaptureTxStart(gasLimit uint64) { - t.gasLimit = gasLimit -} - -// CaptureTxEnd implements the Tracer interface and is invoked at the end of -// transaction processing. -func (t *jsTracer) CaptureTxEnd(restGas uint64) { - t.ctx["gasUsed"] = t.vm.ToValue(t.gasLimit - restGas) -} - -// CaptureStart implements the Tracer interface to initialize the tracing operation. -func (t *jsTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - cancel := func(err error) { - t.err = err - t.env.Cancel() - } - t.env = env - db := &dbObj{db: env.StateDB, vm: t.vm, toBig: t.toBig, toBuf: t.toBuf, fromBuf: t.fromBuf} - t.dbValue = db.setupObject() - if create { - t.ctx["type"] = t.vm.ToValue("CREATE") - } else { - t.ctx["type"] = t.vm.ToValue("CALL") - } - fromVal, err := t.toBuf(t.vm, from.Bytes()) - if err != nil { - cancel(err) - return - } - t.ctx["from"] = fromVal - toVal, err := t.toBuf(t.vm, to.Bytes()) - if err != nil { - cancel(err) - return - } - t.ctx["to"] = toVal - inputVal, err := t.toBuf(t.vm, input) - if err != nil { - cancel(err) - return - } - t.ctx["input"] = inputVal - t.ctx["gas"] = t.vm.ToValue(t.gasLimit) - gasPriceBig, err := t.toBig(t.vm, env.TxContext.GasPrice.String()) - if err != nil { - cancel(err) - return - } - t.ctx["gasPrice"] = gasPriceBig - valueBig, err := t.toBig(t.vm, value.String()) - if err != nil { - cancel(err) - return - } - t.ctx["value"] = valueBig - t.ctx["block"] = t.vm.ToValue(env.Context.BlockNumber.Uint64()) - // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Time) - t.activePrecompiles = vm.ActivePrecompiles(rules) -} - -// CaptureState implements the Tracer interface to trace a single step of VM execution. -func (t *jsTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - if !t.traceStep { - return - } - if t.err != nil { - return - } - - log := t.log - log.op.op = op - log.memory.memory = scope.Memory - log.stack.stack = scope.Stack - log.contract.contract = scope.Contract - log.pc = pc - log.gas = gas - log.cost = cost - log.refund = t.env.StateDB.GetRefund() - log.depth = depth - log.err = err - if _, err := t.step(t.obj, t.logValue, t.dbValue); err != nil { - t.onError("step", err) - } -} - -// CaptureFault implements the Tracer interface to trace an execution fault -func (t *jsTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { - if t.err != nil { - return - } - // Other log fields have been already set as part of the last CaptureState. - t.log.err = err - if _, err := t.fault(t.obj, t.logValue, t.dbValue); err != nil { - t.onError("fault", err) - } -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *jsTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - if err != nil { - t.ctx["error"] = t.vm.ToValue(err.Error()) - } - outputVal, err := t.toBuf(t.vm, output) - if err != nil { - t.err = err - return - } - t.ctx["output"] = outputVal -} - -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *jsTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - if !t.traceFrame { - return - } - if t.err != nil { - return - } - - t.frame.typ = typ.String() - t.frame.from = from - t.frame.to = to - t.frame.input = common.CopyBytes(input) - t.frame.gas = uint(gas) - t.frame.value = nil - if value != nil { - t.frame.value = new(big.Int).SetBytes(value.Bytes()) - } - - if _, err := t.enter(t.obj, t.frameValue); err != nil { - t.onError("enter", err) - } -} - -// CaptureExit is called when EVM exits a scope, even if the scope didn't -// execute any code. -func (t *jsTracer) CaptureExit(output []byte, gasUsed uint64, err error) { - if !t.traceFrame { - return - } - - t.frameResult.gasUsed = uint(gasUsed) - t.frameResult.output = common.CopyBytes(output) - t.frameResult.err = err - - if _, err := t.exit(t.obj, t.frameResultValue); err != nil { - t.onError("exit", err) - } -} - -// GetResult calls the Javascript 'result' function and returns its value, or any accumulated error -func (t *jsTracer) GetResult() (json.RawMessage, error) { - ctx := t.vm.ToValue(t.ctx) - res, err := t.result(t.obj, ctx, t.dbValue) - if err != nil { - return nil, wrapError("result", err) - } - encoded, err := json.Marshal(res) - if err != nil { - return nil, err - } - return json.RawMessage(encoded), t.err -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *jsTracer) Stop(err error) { - t.vm.Interrupt(err) -} - -// onError is called anytime the running JS code is interrupted -// and returns an error. It in turn pings the EVM to cancel its -// execution. -func (t *jsTracer) onError(context string, err error) { - t.err = wrapError(context, err) - // `env` is set on CaptureStart which comes before any JS execution. - // So it should be non-nil. - t.env.Cancel() -} - -func wrapError(context string, err error) error { - return fmt.Errorf("%v in server-side tracer function '%v'", err, context) -} - -// setBuiltinFunctions injects Go functions which are available to tracers into the environment. -// It depends on type converters having been set up. -func (t *jsTracer) setBuiltinFunctions() { - vm := t.vm - // TODO: load console from goja-nodejs - vm.Set("toHex", func(v goja.Value) string { - b, err := t.fromBuf(vm, v, false) - if err != nil { - vm.Interrupt(err) - return "" - } - return hexutil.Encode(b) - }) - vm.Set("toWord", func(v goja.Value) goja.Value { - // TODO: add test with []byte len < 32 or > 32 - b, err := t.fromBuf(vm, v, true) - if err != nil { - vm.Interrupt(err) - return nil - } - b = common.BytesToHash(b).Bytes() - res, err := t.toBuf(vm, b) - if err != nil { - vm.Interrupt(err) - return nil - } - return res - }) - vm.Set("toAddress", func(v goja.Value) goja.Value { - a, err := t.fromBuf(vm, v, true) - if err != nil { - vm.Interrupt(err) - return nil - } - a = common.BytesToAddress(a).Bytes() - res, err := t.toBuf(vm, a) - if err != nil { - vm.Interrupt(err) - return nil - } - return res - }) - vm.Set("toContract", func(from goja.Value, nonce uint) goja.Value { - a, err := t.fromBuf(vm, from, true) - if err != nil { - vm.Interrupt(err) - return nil - } - addr := common.BytesToAddress(a) - b := crypto.CreateAddress(addr, uint64(nonce)).Bytes() - res, err := t.toBuf(vm, b) - if err != nil { - vm.Interrupt(err) - return nil - } - return res - }) - vm.Set("toContract2", func(from goja.Value, salt string, initcode goja.Value) goja.Value { - a, err := t.fromBuf(vm, from, true) - if err != nil { - vm.Interrupt(err) - return nil - } - addr := common.BytesToAddress(a) - code, err := t.fromBuf(vm, initcode, true) - if err != nil { - vm.Interrupt(err) - return nil - } - code = common.CopyBytes(code) - codeHash := crypto.Keccak256(code) - b := crypto.CreateAddress2(addr, common.HexToHash(salt), codeHash).Bytes() - res, err := t.toBuf(vm, b) - if err != nil { - vm.Interrupt(err) - return nil - } - return res - }) - vm.Set("isPrecompiled", func(v goja.Value) bool { - a, err := t.fromBuf(vm, v, true) - if err != nil { - vm.Interrupt(err) - return false - } - addr := common.BytesToAddress(a) - for _, p := range t.activePrecompiles { - if p == addr { - return true - } - } - return false - }) - vm.Set("slice", func(slice goja.Value, start, end int64) goja.Value { - b, err := t.fromBuf(vm, slice, false) - if err != nil { - vm.Interrupt(err) - return nil - } - if start < 0 || start > end || end > int64(len(b)) { - vm.Interrupt(fmt.Sprintf("Tracer accessed out of bound memory: available %d, offset %d, size %d", len(b), start, end-start)) - return nil - } - res, err := t.toBuf(vm, b[start:end]) - if err != nil { - vm.Interrupt(err) - return nil - } - return res - }) -} - -// setTypeConverters sets up utilities for converting Go types into those -// suitable for JS consumption. -func (t *jsTracer) setTypeConverters() error { - // Inject bigint logic. - // TODO: To be replaced after goja adds support for native JS bigint. - toBigCode, err := t.vm.RunProgram(bigIntProgram) - if err != nil { - return err - } - // Used to create JS bigint objects from go. - toBigFn, ok := goja.AssertFunction(toBigCode) - if !ok { - return errors.New("failed to bind bigInt func") - } - toBigWrapper := func(vm *goja.Runtime, val string) (goja.Value, error) { - return toBigFn(goja.Undefined(), vm.ToValue(val)) - } - t.toBig = toBigWrapper - // NOTE: We need this workaround to create JS buffers because - // goja doesn't at the moment expose constructors for typed arrays. - // - // Cache uint8ArrayType once to be used every time for less overhead. - uint8ArrayType := t.vm.Get("Uint8Array") - toBufWrapper := func(vm *goja.Runtime, val []byte) (goja.Value, error) { - return toBuf(vm, uint8ArrayType, val) - } - t.toBuf = toBufWrapper - fromBufWrapper := func(vm *goja.Runtime, buf goja.Value, allowString bool) ([]byte, error) { - return fromBuf(vm, uint8ArrayType, buf, allowString) - } - t.fromBuf = fromBufWrapper - return nil -} - -type opObj struct { - vm *goja.Runtime - op vm.OpCode -} - -func (o *opObj) ToNumber() int { - return int(o.op) -} - -func (o *opObj) ToString() string { - return o.op.String() -} - -func (o *opObj) IsPush() bool { - return o.op.IsPush() -} - -func (o *opObj) setupObject() *goja.Object { - obj := o.vm.NewObject() - obj.Set("toNumber", o.vm.ToValue(o.ToNumber)) - obj.Set("toString", o.vm.ToValue(o.ToString)) - obj.Set("isPush", o.vm.ToValue(o.IsPush)) - return obj -} - -type memoryObj struct { - memory *vm.Memory - vm *goja.Runtime - toBig toBigFn - toBuf toBufFn -} - -func (mo *memoryObj) Slice(begin, end int64) goja.Value { - b, err := mo.slice(begin, end) - if err != nil { - mo.vm.Interrupt(err) - return nil - } - res, err := mo.toBuf(mo.vm, b) - if err != nil { - mo.vm.Interrupt(err) - return nil - } - return res -} - -// slice returns the requested range of memory as a byte slice. -func (mo *memoryObj) slice(begin, end int64) ([]byte, error) { - if end == begin { - return []byte{}, nil - } - if end < begin || begin < 0 { - return nil, fmt.Errorf("tracer accessed out of bound memory: offset %d, end %d", begin, end) - } - slice, err := tracers.GetMemoryCopyPadded(mo.memory, begin, end-begin) - if err != nil { - return nil, err - } - return slice, nil -} - -func (mo *memoryObj) GetUint(addr int64) goja.Value { - value, err := mo.getUint(addr) - if err != nil { - mo.vm.Interrupt(err) - return nil - } - res, err := mo.toBig(mo.vm, value.String()) - if err != nil { - mo.vm.Interrupt(err) - return nil - } - return res -} - -// getUint returns the 32 bytes at the specified address interpreted as a uint. -func (mo *memoryObj) getUint(addr int64) (*big.Int, error) { - if mo.memory.Len() < int(addr)+32 || addr < 0 { - return nil, fmt.Errorf("tracer accessed out of bound memory: available %d, offset %d, size %d", mo.memory.Len(), addr, 32) - } - return new(big.Int).SetBytes(mo.memory.GetPtr(addr, 32)), nil -} - -func (mo *memoryObj) Length() int { - return mo.memory.Len() -} - -func (m *memoryObj) setupObject() *goja.Object { - o := m.vm.NewObject() - o.Set("slice", m.vm.ToValue(m.Slice)) - o.Set("getUint", m.vm.ToValue(m.GetUint)) - o.Set("length", m.vm.ToValue(m.Length)) - return o -} - -type stackObj struct { - stack *vm.Stack - vm *goja.Runtime - toBig toBigFn -} - -func (s *stackObj) Peek(idx int) goja.Value { - value, err := s.peek(idx) - if err != nil { - s.vm.Interrupt(err) - return nil - } - res, err := s.toBig(s.vm, value.String()) - if err != nil { - s.vm.Interrupt(err) - return nil - } - return res -} - -// peek returns the nth-from-the-top element of the stack. -func (s *stackObj) peek(idx int) (*big.Int, error) { - if len(s.stack.Data()) <= idx || idx < 0 { - return nil, fmt.Errorf("tracer accessed out of bound stack: size %d, index %d", len(s.stack.Data()), idx) - } - return s.stack.Back(idx).ToBig(), nil -} - -func (s *stackObj) Length() int { - return len(s.stack.Data()) -} - -func (s *stackObj) setupObject() *goja.Object { - o := s.vm.NewObject() - o.Set("peek", s.vm.ToValue(s.Peek)) - o.Set("length", s.vm.ToValue(s.Length)) - return o -} - -type dbObj struct { - db vm.StateDB - vm *goja.Runtime - toBig toBigFn - toBuf toBufFn - fromBuf fromBufFn -} - -func (do *dbObj) GetBalance(addrSlice goja.Value) goja.Value { - a, err := do.fromBuf(do.vm, addrSlice, false) - if err != nil { - do.vm.Interrupt(err) - return nil - } - addr := common.BytesToAddress(a) - value := do.db.GetBalance(addr) - res, err := do.toBig(do.vm, value.String()) - if err != nil { - do.vm.Interrupt(err) - return nil - } - return res -} - -func (do *dbObj) GetNonce(addrSlice goja.Value) uint64 { - a, err := do.fromBuf(do.vm, addrSlice, false) - if err != nil { - do.vm.Interrupt(err) - return 0 - } - addr := common.BytesToAddress(a) - return do.db.GetNonce(addr) -} - -func (do *dbObj) GetCode(addrSlice goja.Value) goja.Value { - a, err := do.fromBuf(do.vm, addrSlice, false) - if err != nil { - do.vm.Interrupt(err) - return nil - } - addr := common.BytesToAddress(a) - code := do.db.GetCode(addr) - res, err := do.toBuf(do.vm, code) - if err != nil { - do.vm.Interrupt(err) - return nil - } - return res -} - -func (do *dbObj) GetState(addrSlice goja.Value, hashSlice goja.Value) goja.Value { - a, err := do.fromBuf(do.vm, addrSlice, false) - if err != nil { - do.vm.Interrupt(err) - return nil - } - addr := common.BytesToAddress(a) - h, err := do.fromBuf(do.vm, hashSlice, false) - if err != nil { - do.vm.Interrupt(err) - return nil - } - hash := common.BytesToHash(h) - state := do.db.GetState(addr, hash).Bytes() - res, err := do.toBuf(do.vm, state) - if err != nil { - do.vm.Interrupt(err) - return nil - } - return res -} - -func (do *dbObj) Exists(addrSlice goja.Value) bool { - a, err := do.fromBuf(do.vm, addrSlice, false) - if err != nil { - do.vm.Interrupt(err) - return false - } - addr := common.BytesToAddress(a) - return do.db.Exist(addr) -} - -func (do *dbObj) setupObject() *goja.Object { - o := do.vm.NewObject() - o.Set("getBalance", do.vm.ToValue(do.GetBalance)) - o.Set("getNonce", do.vm.ToValue(do.GetNonce)) - o.Set("getCode", do.vm.ToValue(do.GetCode)) - o.Set("getState", do.vm.ToValue(do.GetState)) - o.Set("exists", do.vm.ToValue(do.Exists)) - return o -} - -type contractObj struct { - contract *vm.Contract - vm *goja.Runtime - toBig toBigFn - toBuf toBufFn -} - -func (co *contractObj) GetCaller() goja.Value { - caller := co.contract.Caller().Bytes() - res, err := co.toBuf(co.vm, caller) - if err != nil { - co.vm.Interrupt(err) - return nil - } - return res -} - -func (co *contractObj) GetAddress() goja.Value { - addr := co.contract.Address().Bytes() - res, err := co.toBuf(co.vm, addr) - if err != nil { - co.vm.Interrupt(err) - return nil - } - return res -} - -func (co *contractObj) GetValue() goja.Value { - value := co.contract.Value() - res, err := co.toBig(co.vm, value.String()) - if err != nil { - co.vm.Interrupt(err) - return nil - } - return res -} - -func (co *contractObj) GetInput() goja.Value { - input := common.CopyBytes(co.contract.Input) - res, err := co.toBuf(co.vm, input) - if err != nil { - co.vm.Interrupt(err) - return nil - } - return res -} - -func (c *contractObj) setupObject() *goja.Object { - o := c.vm.NewObject() - o.Set("getCaller", c.vm.ToValue(c.GetCaller)) - o.Set("getAddress", c.vm.ToValue(c.GetAddress)) - o.Set("getValue", c.vm.ToValue(c.GetValue)) - o.Set("getInput", c.vm.ToValue(c.GetInput)) - return o -} - -type callframe struct { - vm *goja.Runtime - toBig toBigFn - toBuf toBufFn - - typ string - from common.Address - to common.Address - input []byte - gas uint - value *big.Int -} - -func (f *callframe) GetType() string { - return f.typ -} - -func (f *callframe) GetFrom() goja.Value { - from := f.from.Bytes() - res, err := f.toBuf(f.vm, from) - if err != nil { - f.vm.Interrupt(err) - return nil - } - return res -} - -func (f *callframe) GetTo() goja.Value { - to := f.to.Bytes() - res, err := f.toBuf(f.vm, to) - if err != nil { - f.vm.Interrupt(err) - return nil - } - return res -} - -func (f *callframe) GetInput() goja.Value { - input := f.input - res, err := f.toBuf(f.vm, input) - if err != nil { - f.vm.Interrupt(err) - return nil - } - return res -} - -func (f *callframe) GetGas() uint { - return f.gas -} - -func (f *callframe) GetValue() goja.Value { - if f.value == nil { - return goja.Undefined() - } - res, err := f.toBig(f.vm, f.value.String()) - if err != nil { - f.vm.Interrupt(err) - return nil - } - return res -} - -func (f *callframe) setupObject() *goja.Object { - o := f.vm.NewObject() - o.Set("getType", f.vm.ToValue(f.GetType)) - o.Set("getFrom", f.vm.ToValue(f.GetFrom)) - o.Set("getTo", f.vm.ToValue(f.GetTo)) - o.Set("getInput", f.vm.ToValue(f.GetInput)) - o.Set("getGas", f.vm.ToValue(f.GetGas)) - o.Set("getValue", f.vm.ToValue(f.GetValue)) - return o -} - -type callframeResult struct { - vm *goja.Runtime - toBuf toBufFn - - gasUsed uint - output []byte - err error -} - -func (r *callframeResult) GetGasUsed() uint { - return r.gasUsed -} - -func (r *callframeResult) GetOutput() goja.Value { - res, err := r.toBuf(r.vm, r.output) - if err != nil { - r.vm.Interrupt(err) - return nil - } - return res -} - -func (r *callframeResult) GetError() goja.Value { - if r.err != nil { - return r.vm.ToValue(r.err.Error()) - } - return goja.Undefined() -} - -func (r *callframeResult) setupObject() *goja.Object { - o := r.vm.NewObject() - o.Set("getGasUsed", r.vm.ToValue(r.GetGasUsed)) - o.Set("getOutput", r.vm.ToValue(r.GetOutput)) - o.Set("getError", r.vm.ToValue(r.GetError)) - return o -} - -type steplog struct { - vm *goja.Runtime - - op *opObj - memory *memoryObj - stack *stackObj - contract *contractObj - - pc uint64 - gas uint64 - cost uint64 - depth int - refund uint64 - err error -} - -func (l *steplog) GetPC() uint64 { return l.pc } -func (l *steplog) GetGas() uint64 { return l.gas } -func (l *steplog) GetCost() uint64 { return l.cost } -func (l *steplog) GetDepth() int { return l.depth } -func (l *steplog) GetRefund() uint64 { return l.refund } - -func (l *steplog) GetError() goja.Value { - if l.err != nil { - return l.vm.ToValue(l.err.Error()) - } - return goja.Undefined() -} - -func (l *steplog) setupObject() *goja.Object { - o := l.vm.NewObject() - // Setup basic fields. - o.Set("getPC", l.vm.ToValue(l.GetPC)) - o.Set("getGas", l.vm.ToValue(l.GetGas)) - o.Set("getCost", l.vm.ToValue(l.GetCost)) - o.Set("getDepth", l.vm.ToValue(l.GetDepth)) - o.Set("getRefund", l.vm.ToValue(l.GetRefund)) - o.Set("getError", l.vm.ToValue(l.GetError)) - // Setup nested objects. - o.Set("op", l.op.setupObject()) - o.Set("stack", l.stack.setupObject()) - o.Set("memory", l.memory.setupObject()) - o.Set("contract", l.contract.setupObject()) - return o -} diff --git a/eth/tracers/js/internal/tracers/4byte_tracer_legacy.js b/eth/tracers/js/internal/tracers/4byte_tracer_legacy.js deleted file mode 100644 index e4714b8bfb..0000000000 --- a/eth/tracers/js/internal/tracers/4byte_tracer_legacy.js +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// 4byteTracer searches for 4byte-identifiers, and collects them for post-processing. -// It collects the methods identifiers along with the size of the supplied data, so -// a reversed signature can be matched against the size of the data. -// -// Example: -// > debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"}) -// { -// 0x27dc297e-128: 1, -// 0x38cc4831-0: 2, -// 0x524f3889-96: 1, -// 0xadf59f99-288: 1, -// 0xc281d19e-0: 1 -// } -{ - // ids aggregates the 4byte ids found. - ids : {}, - - // callType returns 'false' for non-calls, or the peek-index for the first param - // after 'value', i.e. meminstart. - callType: function(opstr){ - switch(opstr){ - case "CALL": case "CALLCODE": - // gas, addr, val, memin, meminsz, memout, memoutsz - return 3; // stack ptr to memin - - case "DELEGATECALL": case "STATICCALL": - // gas, addr, memin, meminsz, memout, memoutsz - return 2; // stack ptr to memin - } - return false; - }, - - // store save the given identifier and datasize. - store: function(id, size){ - var key = "" + toHex(id) + "-" + size; - this.ids[key] = this.ids[key] + 1 || 1; - }, - - // step is invoked for every opcode that the VM executes. - step: function(log, db) { - // Skip any opcodes that are not internal calls - var ct = this.callType(log.op.toString()); - if (!ct) { - return; - } - // Skip any pre-compile invocations, those are just fancy opcodes - if (isPrecompiled(toAddress(log.stack.peek(1).toString(16)))) { - return; - } - // Gather internal call details - var inSz = log.stack.peek(ct + 1).valueOf(); - if (inSz >= 4) { - var inOff = log.stack.peek(ct).valueOf(); - this.store(log.memory.slice(inOff, inOff + 4), inSz-4); - } - }, - - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) { }, - - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx) { - // Save the outer calldata also - if (ctx.input.length >= 4) { - this.store(slice(ctx.input, 0, 4), ctx.input.length-4) - } - return this.ids; - }, -} diff --git a/eth/tracers/js/internal/tracers/bigram_tracer.js b/eth/tracers/js/internal/tracers/bigram_tracer.js deleted file mode 100644 index 421c360af9..0000000000 --- a/eth/tracers/js/internal/tracers/bigram_tracer.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -{ - // hist is the counters of opcode bigrams - hist: {}, - // lastOp is last operation - lastOp: '', - // execution depth of last op - lastDepth: 0, - // step is invoked for every opcode that the VM executes. - step: function(log, db) { - var op = log.op.toString(); - var depth = log.getDepth(); - if (depth == this.lastDepth){ - var key = this.lastOp+'-'+op; - if (this.hist[key]){ - this.hist[key]++; - } - else { - this.hist[key] = 1; - } - } - this.lastOp = op; - this.lastDepth = depth; - }, - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) {}, - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx) { - return this.hist; - }, -} diff --git a/eth/tracers/js/internal/tracers/call_tracer_legacy.js b/eth/tracers/js/internal/tracers/call_tracer_legacy.js deleted file mode 100644 index 0760bb1e3f..0000000000 --- a/eth/tracers/js/internal/tracers/call_tracer_legacy.js +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// callTracer is a full blown transaction tracer that extracts and reports all -// the internal calls made by a transaction, along with any useful information. -{ - // callstack is the current recursive call stack of the EVM execution. - callstack: [{}], - - // descended tracks whether we've just descended from an outer transaction into - // an inner call. - descended: false, - - // step is invoked for every opcode that the VM executes. - step: function(log, db) { - // Capture any errors immediately - var error = log.getError(); - if (error !== undefined) { - this.fault(log, db); - return; - } - // We only care about system opcodes, faster if we pre-check once - var syscall = (log.op.toNumber() & 0xf0) == 0xf0; - if (syscall) { - var op = log.op.toString(); - } - // If a new contract is being created, add to the call stack - if (syscall && (op == 'CREATE' || op == "CREATE2")) { - var inOff = log.stack.peek(1).valueOf(); - var inEnd = inOff + log.stack.peek(2).valueOf(); - - // Assemble the internal call report and store for completion - var call = { - type: op, - from: toHex(log.contract.getAddress()), - input: toHex(log.memory.slice(inOff, inEnd)), - gasIn: log.getGas(), - gasCost: log.getCost(), - value: '0x' + log.stack.peek(0).toString(16) - }; - this.callstack.push(call); - this.descended = true - return; - } - // If a contract is being self destructed, gather that as a subcall too - if (syscall && op == 'SELFDESTRUCT') { - var left = this.callstack.length; - if (this.callstack[left-1].calls === undefined) { - this.callstack[left-1].calls = []; - } - this.callstack[left-1].calls.push({ - type: op, - from: toHex(log.contract.getAddress()), - to: toHex(toAddress(log.stack.peek(0).toString(16))), - gasIn: log.getGas(), - gasCost: log.getCost(), - value: '0x' + db.getBalance(log.contract.getAddress()).toString(16) - }); - return - } - // If a new method invocation is being done, add to the call stack - if (syscall && (op == 'CALL' || op == 'CALLCODE' || op == 'DELEGATECALL' || op == 'STATICCALL')) { - // Skip any pre-compile invocations, those are just fancy opcodes - var to = toAddress(log.stack.peek(1).toString(16)); - if (isPrecompiled(to)) { - return - } - var off = (op == 'DELEGATECALL' || op == 'STATICCALL' ? 0 : 1); - - var inOff = log.stack.peek(2 + off).valueOf(); - var inEnd = inOff + log.stack.peek(3 + off).valueOf(); - - // Assemble the internal call report and store for completion - var call = { - type: op, - from: toHex(log.contract.getAddress()), - to: toHex(to), - input: toHex(log.memory.slice(inOff, inEnd)), - gasIn: log.getGas(), - gasCost: log.getCost(), - outOff: log.stack.peek(4 + off).valueOf(), - outLen: log.stack.peek(5 + off).valueOf() - }; - if (op != 'DELEGATECALL' && op != 'STATICCALL') { - call.value = '0x' + log.stack.peek(2).toString(16); - } - this.callstack.push(call); - this.descended = true - return; - } - // If we've just descended into an inner call, retrieve it's true allowance. We - // need to extract if from within the call as there may be funky gas dynamics - // with regard to requested and actually given gas (2300 stipend, 63/64 rule). - if (this.descended) { - if (log.getDepth() >= this.callstack.length) { - this.callstack[this.callstack.length - 1].gas = log.getGas(); - } else { - // TODO(karalabe): The call was made to a plain account. We currently don't - // have access to the true gas amount inside the call and so any amount will - // mostly be wrong since it depends on a lot of input args. Skip gas for now. - } - this.descended = false; - } - // If an existing call is returning, pop off the call stack - if (syscall && op == 'REVERT') { - this.callstack[this.callstack.length - 1].error = "execution reverted"; - return; - } - if (log.getDepth() == this.callstack.length - 1) { - // Pop off the last call and get the execution results - var call = this.callstack.pop(); - - if (call.type == 'CREATE' || call.type == "CREATE2") { - // If the call was a CREATE, retrieve the contract address and output code - call.gasUsed = '0x' + bigInt(call.gasIn - call.gasCost - log.getGas()).toString(16); - delete call.gasIn; delete call.gasCost; - - var ret = log.stack.peek(0); - if (!ret.equals(0)) { - call.to = toHex(toAddress(ret.toString(16))); - call.output = toHex(db.getCode(toAddress(ret.toString(16)))); - } else if (call.error === undefined) { - call.error = "internal failure"; // TODO(karalabe): surface these faults somehow - } - } else { - // If the call was a contract call, retrieve the gas usage and output - if (call.gas !== undefined) { - call.gasUsed = '0x' + bigInt(call.gasIn - call.gasCost + call.gas - log.getGas()).toString(16); - } - var ret = log.stack.peek(0); - if (!ret.equals(0)) { - call.output = toHex(log.memory.slice(call.outOff, call.outOff + call.outLen)); - } else if (call.error === undefined) { - call.error = "internal failure"; // TODO(karalabe): surface these faults somehow - } - delete call.gasIn; delete call.gasCost; - delete call.outOff; delete call.outLen; - } - if (call.gas !== undefined) { - call.gas = '0x' + bigInt(call.gas).toString(16); - } - // Inject the call into the previous one - var left = this.callstack.length; - if (this.callstack[left-1].calls === undefined) { - this.callstack[left-1].calls = []; - } - this.callstack[left-1].calls.push(call); - } - }, - - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) { - // If the topmost call already reverted, don't handle the additional fault again - if (this.callstack[this.callstack.length - 1].error !== undefined) { - return; - } - // Pop off the just failed call - var call = this.callstack.pop(); - call.error = log.getError(); - - // Consume all available gas and clean any leftovers - if (call.gas !== undefined) { - call.gas = '0x' + bigInt(call.gas).toString(16); - call.gasUsed = call.gas - } - delete call.gasIn; delete call.gasCost; - delete call.outOff; delete call.outLen; - - // Flatten the failed call into its parent - var left = this.callstack.length; - if (left > 0) { - if (this.callstack[left-1].calls === undefined) { - this.callstack[left-1].calls = []; - } - this.callstack[left-1].calls.push(call); - return; - } - // Last call failed too, leave it in the stack - this.callstack.push(call); - }, - - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx, db) { - var result = { - type: ctx.type, - from: toHex(ctx.from), - to: toHex(ctx.to), - value: '0x' + ctx.value.toString(16), - gas: '0x' + bigInt(ctx.gas).toString(16), - gasUsed: '0x' + bigInt(ctx.gasUsed).toString(16), - input: toHex(ctx.input), - output: toHex(ctx.output), - }; - if (this.callstack[0].calls !== undefined) { - result.calls = this.callstack[0].calls; - } - if (this.callstack[0].error !== undefined) { - result.error = this.callstack[0].error; - } else if (ctx.error !== undefined) { - result.error = ctx.error; - } - if (result.error !== undefined && (result.error !== "execution reverted" || result.output ==="0x")) { - delete result.output; - } - return this.finalize(result); - }, - - // finalize recreates a call object using the final desired field order for json - // serialization. This is a nicety feature to pass meaningfully ordered results - // to users who don't interpret it, just display it. - finalize: function(call) { - var sorted = { - type: call.type, - from: call.from, - to: call.to, - value: call.value, - gas: call.gas, - gasUsed: call.gasUsed, - input: call.input, - output: call.output, - error: call.error, - calls: call.calls, - } - for (var key in sorted) { - if (sorted[key] === undefined) { - delete sorted[key]; - } - } - if (sorted.calls !== undefined) { - for (var i=0; i. - -// evmdisTracer returns sufficient information from a trace to perform evmdis-style -// disassembly. -{ - stack: [{ops: []}], - - npushes: {0: 0, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 1, 10: 1, 11: 1, 16: 1, 17: 1, 18: 1, 19: 1, 20: 1, 21: 1, 22: 1, 23: 1, 24: 1, 25: 1, 26: 1, 32: 1, 48: 1, 49: 1, 50: 1, 51: 1, 52: 1, 53: 1, 54: 1, 55: 0, 56: 1, 57: 0, 58: 1, 59: 1, 60: 0, 64: 1, 65: 1, 66: 1, 67: 1, 68: 1, 69: 1, 80: 0, 81: 1, 82: 0, 83: 0, 84: 1, 85: 0, 86: 0, 87: 0, 88: 1, 89: 1, 90: 1, 91: 0, 96: 1, 97: 1, 98: 1, 99: 1, 100: 1, 101: 1, 102: 1, 103: 1, 104: 1, 105: 1, 106: 1, 107: 1, 108: 1, 109: 1, 110: 1, 111: 1, 112: 1, 113: 1, 114: 1, 115: 1, 116: 1, 117: 1, 118: 1, 119: 1, 120: 1, 121: 1, 122: 1, 123: 1, 124: 1, 125: 1, 126: 1, 127: 1, 128: 2, 129: 3, 130: 4, 131: 5, 132: 6, 133: 7, 134: 8, 135: 9, 136: 10, 137: 11, 138: 12, 139: 13, 140: 14, 141: 15, 142: 16, 143: 17, 144: 2, 145: 3, 146: 4, 147: 5, 148: 6, 149: 7, 150: 8, 151: 9, 152: 10, 153: 11, 154: 12, 155: 13, 156: 14, 157: 15, 158: 16, 159: 17, 160: 0, 161: 0, 162: 0, 163: 0, 164: 0, 240: 1, 241: 1, 242: 1, 243: 0, 244: 0, 255: 0}, - - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function() { return this.stack[0].ops; }, - - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) { }, - - // step is invoked for every opcode that the VM executes. - step: function(log, db) { - var frame = this.stack[this.stack.length - 1]; - - var error = log.getError(); - if (error) { - frame["error"] = error; - } else if (log.getDepth() == this.stack.length) { - opinfo = { - op: log.op.toNumber(), - depth : log.getDepth(), - result: [], - }; - if (frame.ops.length > 0) { - var prevop = frame.ops[frame.ops.length - 1]; - for(var i = 0; i < this.npushes[prevop.op]; i++) - prevop.result.push(log.stack.peek(i).toString(16)); - } - switch(log.op.toString()) { - case "CALL": case "CALLCODE": - var instart = log.stack.peek(3).valueOf(); - var insize = log.stack.peek(4).valueOf(); - opinfo["gas"] = log.stack.peek(0).valueOf(); - opinfo["to"] = log.stack.peek(1).toString(16); - opinfo["value"] = log.stack.peek(2).toString(); - opinfo["input"] = log.memory.slice(instart, instart + insize); - opinfo["error"] = null; - opinfo["return"] = null; - opinfo["ops"] = []; - this.stack.push(opinfo); - break; - case "DELEGATECALL": case "STATICCALL": - var instart = log.stack.peek(2).valueOf(); - var insize = log.stack.peek(3).valueOf(); - opinfo["op"] = log.op.toString(); - opinfo["gas"] = log.stack.peek(0).valueOf(); - opinfo["to"] = log.stack.peek(1).toString(16); - opinfo["input"] = log.memory.slice(instart, instart + insize); - opinfo["error"] = null; - opinfo["return"] = null; - opinfo["ops"] = []; - this.stack.push(opinfo); - break; - case "RETURN": case "REVERT": - var out = log.stack.peek(0).valueOf(); - var outsize = log.stack.peek(1).valueOf(); - frame.return = log.memory.slice(out, out + outsize); - break; - case "STOP": case "SELFDESTRUCT": - frame.return = log.memory.slice(0, 0); - break; - case "JUMPDEST": - opinfo["pc"] = log.getPC(); - } - if(log.op.isPush()) { - opinfo["len"] = log.op.toNumber() - 0x5e; - } - frame.ops.push(opinfo); - } else { - this.stack = this.stack.slice(0, log.getDepth()); - } - } -} diff --git a/eth/tracers/js/internal/tracers/noop_tracer_legacy.js b/eth/tracers/js/internal/tracers/noop_tracer_legacy.js deleted file mode 100644 index fe7ddc85ab..0000000000 --- a/eth/tracers/js/internal/tracers/noop_tracer_legacy.js +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// noopTracer is just the barebone boilerplate code required from a JavaScript -// object to be usable as a transaction tracer. -{ - // step is invoked for every opcode that the VM executes. - step: function(log, db) { }, - - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) { }, - - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx, db) { return {}; } -} diff --git a/eth/tracers/js/internal/tracers/opcount_tracer.js b/eth/tracers/js/internal/tracers/opcount_tracer.js deleted file mode 100644 index f7984c741a..0000000000 --- a/eth/tracers/js/internal/tracers/opcount_tracer.js +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// opcountTracer is a sample tracer that just counts the number of instructions -// executed by the EVM before the transaction terminated. -{ - // count tracks the number of EVM instructions executed. - count: 0, - - // step is invoked for every opcode that the VM executes. - step: function(log, db) { this.count++ }, - - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) { }, - - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx, db) { return this.count } -} diff --git a/eth/tracers/js/internal/tracers/prestate_tracer_legacy.js b/eth/tracers/js/internal/tracers/prestate_tracer_legacy.js deleted file mode 100644 index 2757b8b141..0000000000 --- a/eth/tracers/js/internal/tracers/prestate_tracer_legacy.js +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// prestateTracer outputs sufficient information to create a local execution of -// the transaction from a custom assembled genesis block. -{ - // prestate is the genesis that we're building. - prestate: null, - - // lookupAccount injects the specified account into the prestate object. - lookupAccount: function(addr, db){ - var acc = toHex(addr); - if (this.prestate[acc] === undefined) { - this.prestate[acc] = { - balance: '0x' + db.getBalance(addr).toString(16), - nonce: db.getNonce(addr), - code: toHex(db.getCode(addr)), - storage: {} - }; - } - }, - - // lookupStorage injects the specified storage entry of the given account into - // the prestate object. - lookupStorage: function(addr, key, db){ - var acc = toHex(addr); - var idx = toHex(key); - - if (this.prestate[acc].storage[idx] === undefined) { - this.prestate[acc].storage[idx] = toHex(db.getState(addr, key)); - } - }, - - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx, db) { - if (this.prestate === null) { - this.prestate = {}; - // If tx is transfer-only, the recipient account - // hasn't been populated. - this.lookupAccount(ctx.to, db); - } - - // At this point, we need to deduct the 'value' from the - // outer transaction, and move it back to the origin - this.lookupAccount(ctx.from, db); - - var fromBal = bigInt(this.prestate[toHex(ctx.from)].balance.slice(2), 16); - var toBal = bigInt(this.prestate[toHex(ctx.to)].balance.slice(2), 16); - - this.prestate[toHex(ctx.to)].balance = '0x'+toBal.subtract(ctx.value).toString(16); - this.prestate[toHex(ctx.from)].balance = '0x'+fromBal.add(ctx.value).add(ctx.gasUsed * ctx.gasPrice).toString(16); - - // Decrement the caller's nonce, and remove empty create targets - this.prestate[toHex(ctx.from)].nonce--; - if (ctx.type == 'CREATE') { - // We can blibdly delete the contract prestate, as any existing state would - // have caused the transaction to be rejected as invalid in the first place. - delete this.prestate[toHex(ctx.to)]; - } - // Return the assembled allocations (prestate) - return this.prestate; - }, - - // step is invoked for every opcode that the VM executes. - step: function(log, db) { - // Add the current account if we just started tracing - if (this.prestate === null){ - this.prestate = {}; - // Balance will potentially be wrong here, since this will include the value - // sent along with the message. We fix that in 'result()'. - this.lookupAccount(log.contract.getAddress(), db); - } - // Whenever new state is accessed, add it to the prestate - switch (log.op.toString()) { - case "EXTCODECOPY": case "EXTCODESIZE": case "EXTCODEHASH": case "BALANCE": - this.lookupAccount(toAddress(log.stack.peek(0).toString(16)), db); - break; - case "CREATE": - var from = log.contract.getAddress(); - this.lookupAccount(toContract(from, db.getNonce(from)), db); - break; - case "CREATE2": - var from = log.contract.getAddress(); - // stack: salt, size, offset, endowment - var offset = log.stack.peek(1).valueOf() - var size = log.stack.peek(2).valueOf() - var end = offset + size - this.lookupAccount(toContract2(from, log.stack.peek(3).toString(16), log.memory.slice(offset, end)), db); - break; - case "CALL": case "CALLCODE": case "DELEGATECALL": case "STATICCALL": - this.lookupAccount(toAddress(log.stack.peek(1).toString(16)), db); - break; - case 'SSTORE':case 'SLOAD': - this.lookupStorage(log.contract.getAddress(), toWord(log.stack.peek(0).toString(16)), db); - break; - } - }, - - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) {} -} diff --git a/eth/tracers/js/internal/tracers/tracers.go b/eth/tracers/js/internal/tracers/tracers.go deleted file mode 100644 index 6547f1b088..0000000000 --- a/eth/tracers/js/internal/tracers/tracers.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package tracers contains the actual JavaScript tracer assets. -package tracers - -import ( - "embed" - "io/fs" - "strings" - "unicode" -) - -//go:embed *.js -var files embed.FS - -// Load reads the built-in JS tracer files embedded in the binary and -// returns a mapping of tracer name to source. -func Load() (map[string]string, error) { - var assetTracers = make(map[string]string) - err := fs.WalkDir(files, ".", func(path string, d fs.DirEntry, err error) error { - if err != nil { - return err - } - if d.IsDir() { - return nil - } - b, err := fs.ReadFile(files, path) - if err != nil { - return err - } - name := camel(strings.TrimSuffix(path, ".js")) - assetTracers[name] = string(b) - return nil - }) - return assetTracers, err -} - -// camel converts a snake cased input string into a camel cased output. -func camel(str string) string { - pieces := strings.Split(str, "_") - for i := 1; i < len(pieces); i++ { - pieces[i] = string(unicode.ToUpper(rune(pieces[i][0]))) + pieces[i][1:] - } - return strings.Join(pieces, "") -} diff --git a/eth/tracers/js/internal/tracers/trigram_tracer.js b/eth/tracers/js/internal/tracers/trigram_tracer.js deleted file mode 100644 index 8756490dfc..0000000000 --- a/eth/tracers/js/internal/tracers/trigram_tracer.js +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -{ - // hist is the map of trigram counters - hist: {}, - // lastOp is last operation - lastOps: ['',''], - lastDepth: 0, - // step is invoked for every opcode that the VM executes. - step: function(log, db) { - var depth = log.getDepth(); - if (depth != this.lastDepth){ - this.lastOps = ['','']; - this.lastDepth = depth; - return; - } - var op = log.op.toString(); - var key = this.lastOps[0]+'-'+this.lastOps[1]+'-'+op; - if (this.hist[key]){ - this.hist[key]++; - } - else { - this.hist[key] = 1; - } - this.lastOps[0] = this.lastOps[1]; - this.lastOps[1] = op; - }, - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) {}, - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx) { - return this.hist; - }, -} diff --git a/eth/tracers/js/internal/tracers/unigram_tracer.js b/eth/tracers/js/internal/tracers/unigram_tracer.js deleted file mode 100644 index 51107d8f3d..0000000000 --- a/eth/tracers/js/internal/tracers/unigram_tracer.js +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2018 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -{ - // hist is the map of opcodes to counters - hist: {}, - // nops counts number of ops - nops: 0, - // step is invoked for every opcode that the VM executes. - step: function(log, db) { - var op = log.op.toString(); - if (this.hist[op]){ - this.hist[op]++; - } - else { - this.hist[op] = 1; - } - this.nops++; - }, - // fault is invoked when the actual execution of an opcode fails. - fault: function(log, db) {}, - - // result is invoked when all the opcodes have been iterated over and returns - // the final result of the tracing. - result: function(ctx) { - return this.hist; - }, -} diff --git a/eth/tracers/js/tracer_test.go b/eth/tracers/js/tracer_test.go deleted file mode 100644 index 746fc0eb0e..0000000000 --- a/eth/tracers/js/tracer_test.go +++ /dev/null @@ -1,329 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package js - -import ( - "encoding/json" - "errors" - "math/big" - "strings" - "testing" - "time" - - "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -type account struct{} - -func (account) SubBalance(amount *big.Int) {} -func (account) AddBalance(amount *big.Int) {} -func (account) SetAddress(common.Address) {} -func (account) Value() *big.Int { return nil } -func (account) SetBalance(*uint256.Int) {} -func (account) SetNonce(uint64) {} -func (account) Balance() *uint256.Int { return nil } -func (account) Address() common.Address { return common.Address{} } -func (account) SetCode(common.Hash, []byte) {} -func (account) ForEachStorage(cb func(key, value common.Hash) bool) {} - -type dummyStatedb struct { - state.StateDB -} - -func (*dummyStatedb) GetRefund() uint64 { return 1337 } -func (*dummyStatedb) GetBalance(addr common.Address) *uint256.Int { return new(uint256.Int) } - -type vmContext struct { - blockCtx vm.BlockContext - txCtx vm.TxContext -} - -func testCtx() *vmContext { - return &vmContext{blockCtx: vm.BlockContext{BlockNumber: big.NewInt(1)}, txCtx: vm.TxContext{GasPrice: big.NewInt(100000)}} -} - -func runTrace(tracer tracers.Tracer, vmctx *vmContext, chaincfg *params.ChainConfig, contractCode []byte) (json.RawMessage, error) { - var ( - env = vm.NewEVM(vmctx.blockCtx, vmctx.txCtx, &dummyStatedb{}, chaincfg, vm.Config{Tracer: tracer}) - gasLimit uint64 = 31000 - startGas uint64 = 10000 - value = uint256.NewInt(0) - contract = vm.NewContract(account{}, account{}, value, startGas) - ) - contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x1, 0x0} - if contractCode != nil { - contract.Code = contractCode - } - - tracer.CaptureTxStart(gasLimit) - tracer.CaptureStart(env, contract.Caller(), contract.Address(), false, []byte{}, startGas, value.ToBig()) - ret, err := env.Interpreter().Run(contract, []byte{}, false) - tracer.CaptureEnd(ret, startGas-contract.Gas, err) - // Rest gas assumes no refund - tracer.CaptureTxEnd(contract.Gas) - if err != nil { - return nil, err - } - return tracer.GetResult() -} - -func TestTracer(t *testing.T) { - execTracer := func(code string, contract []byte) ([]byte, string) { - t.Helper() - tracer, err := newJsTracer(code, nil, nil) - if err != nil { - t.Fatal(err) - } - ret, err := runTrace(tracer, testCtx(), params.TestChainConfig, contract) - if err != nil { - return nil, err.Error() // Stringify to allow comparison without nil checks - } - return ret, "" - } - for i, tt := range []struct { - code string - want string - fail string - contract []byte - }{ - { // tests that we don't panic on bad arguments to memory access - code: "{depths: [], step: function(log) { this.depths.push(log.memory.slice(-1,-2)); }, fault: function() {}, result: function() { return this.depths; }}", - want: ``, - fail: "tracer accessed out of bound memory: offset -1, end -2 at step (:1:53(13)) in server-side tracer function 'step'", - }, { // tests that we don't panic on bad arguments to stack peeks - code: "{depths: [], step: function(log) { this.depths.push(log.stack.peek(-1)); }, fault: function() {}, result: function() { return this.depths; }}", - want: ``, - fail: "tracer accessed out of bound stack: size 0, index -1 at step (:1:53(11)) in server-side tracer function 'step'", - }, { // tests that we don't panic on bad arguments to memory getUint - code: "{ depths: [], step: function(log, db) { this.depths.push(log.memory.getUint(-64));}, fault: function() {}, result: function() { return this.depths; }}", - want: ``, - fail: "tracer accessed out of bound memory: available 0, offset -64, size 32 at step (:1:58(11)) in server-side tracer function 'step'", - }, { // tests some general counting - code: "{count: 0, step: function() { this.count += 1; }, fault: function() {}, result: function() { return this.count; }}", - want: `3`, - }, { // tests that depth is reported correctly - code: "{depths: [], step: function(log) { this.depths.push(log.stack.length()); }, fault: function() {}, result: function() { return this.depths; }}", - want: `[0,1,2]`, - }, { // tests memory length - code: "{lengths: [], step: function(log) { this.lengths.push(log.memory.length()); }, fault: function() {}, result: function() { return this.lengths; }}", - want: `[0,0,0]`, - }, { // tests to-string of opcodes - code: "{opcodes: [], step: function(log) { this.opcodes.push(log.op.toString()); }, fault: function() {}, result: function() { return this.opcodes; }}", - want: `["PUSH1","PUSH1","STOP"]`, - }, { // tests gasUsed - code: "{depths: [], step: function() {}, fault: function() {}, result: function(ctx) { return ctx.gasPrice+'.'+ctx.gasUsed; }}", - want: `"100000.21006"`, - }, { - code: "{res: null, step: function(log) {}, fault: function() {}, result: function() { return toWord('0xffaa') }}", - want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":255,"31":170}`, - }, { // test feeding a buffer back into go - code: "{res: null, step: function(log) { var address = log.contract.getAddress(); this.res = toAddress(address); }, fault: function() {}, result: function() { return this.res }}", - want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}`, - }, { - code: "{res: null, step: function(log) { var address = '0x0000000000000000000000000000000000000000'; this.res = toAddress(address); }, fault: function() {}, result: function() { return this.res }}", - want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}`, - }, { - code: "{res: null, step: function(log) { var address = Array.prototype.slice.call(log.contract.getAddress()); this.res = toAddress(address); }, fault: function() {}, result: function() { return this.res }}", - want: `{"0":0,"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0}`, - }, { - code: "{res: [], step: function(log) { var op = log.op.toString(); if (op === 'MSTORE8' || op === 'STOP') { this.res.push(log.memory.slice(0, 2)) } }, fault: function() {}, result: function() { return this.res }}", - want: `[{"0":0,"1":0},{"0":255,"1":0}]`, - contract: []byte{byte(vm.PUSH1), byte(0xff), byte(vm.PUSH1), byte(0x00), byte(vm.MSTORE8), byte(vm.STOP)}, - }, { - code: "{res: [], step: function(log) { if (log.op.toString() === 'STOP') { this.res.push(log.memory.slice(5, 1025 * 1024)) } }, fault: function() {}, result: function() { return this.res }}", - want: "", - fail: "reached limit for padding memory slice: 1049568 at step (:1:83(20)) in server-side tracer function 'step'", - contract: []byte{byte(vm.PUSH1), byte(0xff), byte(vm.PUSH1), byte(0x00), byte(vm.MSTORE8), byte(vm.STOP)}, - }, - } { - if have, err := execTracer(tt.code, tt.contract); tt.want != string(have) || tt.fail != err { - t.Errorf("testcase %d: expected return value to be \n'%s'\n\tgot\n'%s'\nerror to be\n'%s'\n\tgot\n'%s'\n\tcode: %v", i, tt.want, string(have), tt.fail, err, tt.code) - } - } -} - -func TestHalt(t *testing.T) { - timeout := errors.New("stahp") - tracer, err := newJsTracer("{step: function() { while(1); }, result: function() { return null; }, fault: function(){}}", nil, nil) - if err != nil { - t.Fatal(err) - } - go func() { - time.Sleep(1 * time.Second) - tracer.Stop(timeout) - }() - if _, err = runTrace(tracer, testCtx(), params.TestChainConfig, nil); !strings.Contains(err.Error(), "stahp") { - t.Errorf("Expected timeout error, got %v", err) - } -} - -func TestHaltBetweenSteps(t *testing.T) { - tracer, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }}", nil, nil) - if err != nil { - t.Fatal(err) - } - env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(1)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer}) - scope := &vm.ScopeContext{ - Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0), - } - tracer.CaptureStart(env, common.Address{}, common.Address{}, false, []byte{}, 0, big.NewInt(0)) - tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil) - timeout := errors.New("stahp") - tracer.Stop(timeout) - tracer.CaptureState(0, 0, 0, 0, scope, nil, 0, nil) - - if _, err := tracer.GetResult(); !strings.Contains(err.Error(), timeout.Error()) { - t.Errorf("Expected timeout error, got %v", err) - } -} - -// TestNoStepExec tests a regular value transfer (no exec), and accessing the statedb -// in 'result' -func TestNoStepExec(t *testing.T) { - execTracer := func(code string) []byte { - t.Helper() - tracer, err := newJsTracer(code, nil, nil) - if err != nil { - t.Fatal(err) - } - env := vm.NewEVM(vm.BlockContext{BlockNumber: big.NewInt(1)}, vm.TxContext{GasPrice: big.NewInt(100)}, &dummyStatedb{}, params.TestChainConfig, vm.Config{Tracer: tracer}) - tracer.CaptureStart(env, common.Address{}, common.Address{}, false, []byte{}, 1000, big.NewInt(0)) - tracer.CaptureEnd(nil, 0, nil) - ret, err := tracer.GetResult() - if err != nil { - t.Fatal(err) - } - return ret - } - for i, tt := range []struct { - code string - want string - }{ - { // tests that we don't panic on accessing the db methods - code: "{depths: [], step: function() {}, fault: function() {}, result: function(ctx, db){ return db.getBalance(ctx.to)} }", - want: `"0"`, - }, - } { - if have := execTracer(tt.code); tt.want != string(have) { - t.Errorf("testcase %d: expected return value to be %s got %s\n\tcode: %v", i, tt.want, string(have), tt.code) - } - } -} - -func TestIsPrecompile(t *testing.T) { - chaincfg := ¶ms.ChainConfig{ChainID: big.NewInt(1), HomesteadBlock: big.NewInt(0), DAOForkBlock: nil, DAOForkSupport: false, EIP150Block: big.NewInt(0), EIP155Block: big.NewInt(0), EIP158Block: big.NewInt(0), ByzantiumBlock: big.NewInt(100), ConstantinopleBlock: big.NewInt(0), PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(200), MuirGlacierBlock: big.NewInt(0)} - chaincfg.ByzantiumBlock = big.NewInt(100) - chaincfg.IstanbulBlock = big.NewInt(200) - txCtx := vm.TxContext{GasPrice: big.NewInt(100000)} - tracer, err := newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil) - if err != nil { - t.Fatal(err) - } - - blockCtx := vm.BlockContext{BlockNumber: big.NewInt(150)} - res, err := runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg, nil) - if err != nil { - t.Error(err) - } - if string(res) != "false" { - t.Errorf("tracer should not consider blake2f as precompile in byzantium") - } - - tracer, _ = newJsTracer("{addr: toAddress('0000000000000000000000000000000000000009'), res: null, step: function() { this.res = isPrecompiled(this.addr); }, fault: function() {}, result: function() { return this.res; }}", nil, nil) - blockCtx = vm.BlockContext{BlockNumber: big.NewInt(250)} - res, err = runTrace(tracer, &vmContext{blockCtx, txCtx}, chaincfg, nil) - if err != nil { - t.Error(err) - } - if string(res) != "true" { - t.Errorf("tracer should consider blake2f as precompile in istanbul") - } -} - -func TestEnterExit(t *testing.T) { - // test that either both or none of enter() and exit() are defined - if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}}", new(tracers.Context), nil); err == nil { - t.Fatal("tracer creation should've failed without exit() definition") - } - if _, err := newJsTracer("{step: function() {}, fault: function() {}, result: function() { return null; }, enter: function() {}, exit: function() {}}", new(tracers.Context), nil); err != nil { - t.Fatal(err) - } - // test that the enter and exit method are correctly invoked and the values passed - tracer, err := newJsTracer("{enters: 0, exits: 0, enterGas: 0, gasUsed: 0, step: function() {}, fault: function() {}, result: function() { return {enters: this.enters, exits: this.exits, enterGas: this.enterGas, gasUsed: this.gasUsed} }, enter: function(frame) { this.enters++; this.enterGas = frame.getGas(); }, exit: function(res) { this.exits++; this.gasUsed = res.getGasUsed(); }}", new(tracers.Context), nil) - if err != nil { - t.Fatal(err) - } - scope := &vm.ScopeContext{ - Contract: vm.NewContract(&account{}, &account{}, uint256.NewInt(0), 0), - } - tracer.CaptureEnter(vm.CALL, scope.Contract.Caller(), scope.Contract.Address(), []byte{}, 1000, new(big.Int)) - tracer.CaptureExit([]byte{}, 400, nil) - - have, err := tracer.GetResult() - if err != nil { - t.Fatal(err) - } - want := `{"enters":1,"exits":1,"enterGas":1000,"gasUsed":400}` - if string(have) != want { - t.Errorf("Number of invocations of enter() and exit() is wrong. Have %s, want %s\n", have, want) - } -} - -func TestSetup(t *testing.T) { - // Test empty config - _, err := newJsTracer(`{setup: function(cfg) { if (cfg !== "{}") { throw("invalid empty config") } }, fault: function() {}, result: function() {}}`, new(tracers.Context), nil) - if err != nil { - t.Error(err) - } - - cfg, err := json.Marshal(map[string]string{"foo": "bar"}) - if err != nil { - t.Fatal(err) - } - // Test no setup func - _, err = newJsTracer(`{fault: function() {}, result: function() {}}`, new(tracers.Context), cfg) - if err != nil { - t.Fatal(err) - } - // Test config value - tracer, err := newJsTracer("{config: null, setup: function(cfg) { this.config = JSON.parse(cfg) }, step: function() {}, fault: function() {}, result: function() { return this.config.foo }}", new(tracers.Context), cfg) - if err != nil { - t.Fatal(err) - } - have, err := tracer.GetResult() - if err != nil { - t.Fatal(err) - } - if string(have) != `"bar"` { - t.Errorf("tracer returned wrong result. have: %s, want: \"bar\"\n", string(have)) - } -} diff --git a/eth/tracers/logger/access_list_tracer.go b/eth/tracers/logger/access_list_tracer.go deleted file mode 100644 index d43198a2ff..0000000000 --- a/eth/tracers/logger/access_list_tracer.go +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package logger - -import ( - "math/big" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ethereum/go-ethereum/common" -) - -// accessList is an accumulator for the set of accounts and storage slots an EVM -// contract execution touches. -type accessList map[common.Address]accessListSlots - -// accessListSlots is an accumulator for the set of storage slots within a single -// contract that an EVM contract execution touches. -type accessListSlots map[common.Hash]struct{} - -// newAccessList creates a new accessList. -func newAccessList() accessList { - return make(map[common.Address]accessListSlots) -} - -// addAddress adds an address to the accesslist. -func (al accessList) addAddress(address common.Address) { - // Set address if not previously present - if _, present := al[address]; !present { - al[address] = make(map[common.Hash]struct{}) - } -} - -// addSlot adds a storage slot to the accesslist. -func (al accessList) addSlot(address common.Address, slot common.Hash) { - // Set address if not previously present - al.addAddress(address) - - // Set the slot on the surely existent storage set - al[address][slot] = struct{}{} -} - -// equal checks if the content of the current access list is the same as the -// content of the other one. -func (al accessList) equal(other accessList) bool { - // Cross reference the accounts first - if len(al) != len(other) { - return false - } - // Given that len(al) == len(other), we only need to check that - // all the items from al are in other. - for addr := range al { - if _, ok := other[addr]; !ok { - return false - } - } - - // Accounts match, cross reference the storage slots too - for addr, slots := range al { - otherslots := other[addr] - - if len(slots) != len(otherslots) { - return false - } - // Given that len(slots) == len(otherslots), we only need to check that - // all the items from slots are in otherslots. - for hash := range slots { - if _, ok := otherslots[hash]; !ok { - return false - } - } - } - return true -} - -// accessList converts the accesslist to a types.AccessList. -func (al accessList) accessList() types.AccessList { - acl := make(types.AccessList, 0, len(al)) - for addr, slots := range al { - tuple := types.AccessTuple{Address: addr, StorageKeys: []common.Hash{}} - for slot := range slots { - tuple.StorageKeys = append(tuple.StorageKeys, slot) - } - acl = append(acl, tuple) - } - return acl -} - -// AccessListTracer is a tracer that accumulates touched accounts and storage -// slots into an internal set. -type AccessListTracer struct { - excl map[common.Address]struct{} // Set of account to exclude from the list - list accessList // Set of accounts and storage slots touched -} - -// NewAccessListTracer creates a new tracer that can generate AccessLists. -// An optional AccessList can be specified to occupy slots and addresses in -// the resulting accesslist. -func NewAccessListTracer(acl types.AccessList, from, to common.Address, precompiles []common.Address) *AccessListTracer { - excl := map[common.Address]struct{}{ - from: {}, to: {}, - } - for _, addr := range precompiles { - excl[addr] = struct{}{} - } - list := newAccessList() - for _, al := range acl { - if _, ok := excl[al.Address]; !ok { - list.addAddress(al.Address) - } - for _, slot := range al.StorageKeys { - list.addSlot(al.Address, slot) - } - } - return &AccessListTracer{ - excl: excl, - list: list, - } -} - -func (a *AccessListTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { -} - -// CaptureState captures all opcodes that touch storage or addresses and adds them to the accesslist. -func (a *AccessListTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - stack := scope.Stack - stackData := stack.Data() - stackLen := len(stackData) - if (op == vm.SLOAD || op == vm.SSTORE) && stackLen >= 1 { - slot := common.Hash(stackData[stackLen-1].Bytes32()) - a.list.addSlot(scope.Contract.Address(), slot) - } - if (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT) && stackLen >= 1 { - addr := common.Address(stackData[stackLen-1].Bytes20()) - if _, ok := a.excl[addr]; !ok { - a.list.addAddress(addr) - } - } - if (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE) && stackLen >= 5 { - addr := common.Address(stackData[stackLen-2].Bytes20()) - if _, ok := a.excl[addr]; !ok { - a.list.addAddress(addr) - } - } -} - -func (*AccessListTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -func (*AccessListTracer) CaptureEnd(output []byte, gasUsed uint64, err error) {} - -func (*AccessListTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -func (*AccessListTracer) CaptureExit(output []byte, gasUsed uint64, err error) {} - -func (*AccessListTracer) CaptureTxStart(gasLimit uint64) {} - -func (*AccessListTracer) CaptureTxEnd(restGas uint64) {} - -// AccessList returns the current accesslist maintained by the tracer. -func (a *AccessListTracer) AccessList() types.AccessList { - return a.list.accessList() -} - -// Equal returns if the content of two access list traces are equal. -func (a *AccessListTracer) Equal(other *AccessListTracer) bool { - return a.list.equal(other.list) -} diff --git a/eth/tracers/logger/gen_structlog.go b/eth/tracers/logger/gen_structlog.go deleted file mode 100644 index c41d569a96..0000000000 --- a/eth/tracers/logger/gen_structlog.go +++ /dev/null @@ -1,118 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package logger - -import ( - "encoding/json" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/holiman/uint256" -) - -var _ = (*structLogMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (s StructLog) MarshalJSON() ([]byte, error) { - type StructLog struct { - Pc uint64 `json:"pc"` - Op vm.OpCode `json:"op"` - Gas math.HexOrDecimal64 `json:"gas"` - GasCost math.HexOrDecimal64 `json:"gasCost"` - Memory hexutil.Bytes `json:"memory,omitempty"` - MemorySize int `json:"memSize"` - Stack []hexutil.U256 `json:"stack"` - ReturnData hexutil.Bytes `json:"returnData,omitempty"` - Storage map[common.Hash]common.Hash `json:"-"` - Depth int `json:"depth"` - RefundCounter uint64 `json:"refund"` - Err error `json:"-"` - OpName string `json:"opName"` - ErrorString string `json:"error,omitempty"` - } - var enc StructLog - enc.Pc = s.Pc - enc.Op = s.Op - enc.Gas = math.HexOrDecimal64(s.Gas) - enc.GasCost = math.HexOrDecimal64(s.GasCost) - enc.Memory = s.Memory - enc.MemorySize = s.MemorySize - if s.Stack != nil { - enc.Stack = make([]hexutil.U256, len(s.Stack)) - for k, v := range s.Stack { - enc.Stack[k] = hexutil.U256(v) - } - } - enc.ReturnData = s.ReturnData - enc.Storage = s.Storage - enc.Depth = s.Depth - enc.RefundCounter = s.RefundCounter - enc.Err = s.Err - enc.OpName = s.OpName() - enc.ErrorString = s.ErrorString() - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (s *StructLog) UnmarshalJSON(input []byte) error { - type StructLog struct { - Pc *uint64 `json:"pc"` - Op *vm.OpCode `json:"op"` - Gas *math.HexOrDecimal64 `json:"gas"` - GasCost *math.HexOrDecimal64 `json:"gasCost"` - Memory *hexutil.Bytes `json:"memory,omitempty"` - MemorySize *int `json:"memSize"` - Stack []hexutil.U256 `json:"stack"` - ReturnData *hexutil.Bytes `json:"returnData,omitempty"` - Storage map[common.Hash]common.Hash `json:"-"` - Depth *int `json:"depth"` - RefundCounter *uint64 `json:"refund"` - Err error `json:"-"` - } - var dec StructLog - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Pc != nil { - s.Pc = *dec.Pc - } - if dec.Op != nil { - s.Op = *dec.Op - } - if dec.Gas != nil { - s.Gas = uint64(*dec.Gas) - } - if dec.GasCost != nil { - s.GasCost = uint64(*dec.GasCost) - } - if dec.Memory != nil { - s.Memory = *dec.Memory - } - if dec.MemorySize != nil { - s.MemorySize = *dec.MemorySize - } - if dec.Stack != nil { - s.Stack = make([]uint256.Int, len(dec.Stack)) - for k, v := range dec.Stack { - s.Stack[k] = uint256.Int(v) - } - } - if dec.ReturnData != nil { - s.ReturnData = *dec.ReturnData - } - if dec.Storage != nil { - s.Storage = dec.Storage - } - if dec.Depth != nil { - s.Depth = *dec.Depth - } - if dec.RefundCounter != nil { - s.RefundCounter = *dec.RefundCounter - } - if dec.Err != nil { - s.Err = dec.Err - } - return nil -} diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go deleted file mode 100644 index c6d3f1b0fb..0000000000 --- a/eth/tracers/logger/logger.go +++ /dev/null @@ -1,468 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package logger - -import ( - "encoding/hex" - "encoding/json" - "fmt" - "io" - "math/big" - "strings" - "sync/atomic" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/holiman/uint256" -) - -// Storage represents a contract's storage. -type Storage map[common.Hash]common.Hash - -// Copy duplicates the current storage. -func (s Storage) Copy() Storage { - cpy := make(Storage, len(s)) - for key, value := range s { - cpy[key] = value - } - return cpy -} - -// Config are the configuration options for structured logger the EVM -type Config struct { - EnableMemory bool // enable memory capture - DisableStack bool // disable stack capture - DisableStorage bool // disable storage capture - EnableReturnData bool // enable return data capture - Debug bool // print output during capture end - Limit int // maximum length of output, but zero means unlimited - // Chain overrides, can be used to execute a trace using future fork rules - Overrides *params.ChainConfig `json:"overrides,omitempty"` -} - -//go:generate gencodec -type StructLog -field-override structLogMarshaling -out gen_structlog.go - -// StructLog is emitted to the EVM each cycle and lists information about the current internal state -// prior to the execution of the statement. -type StructLog struct { - Pc uint64 `json:"pc"` - Op vm.OpCode `json:"op"` - Gas uint64 `json:"gas"` - GasCost uint64 `json:"gasCost"` - Memory []byte `json:"memory,omitempty"` - MemorySize int `json:"memSize"` - Stack []uint256.Int `json:"stack"` - ReturnData []byte `json:"returnData,omitempty"` - Storage map[common.Hash]common.Hash `json:"-"` - Depth int `json:"depth"` - RefundCounter uint64 `json:"refund"` - Err error `json:"-"` -} - -// overrides for gencodec -type structLogMarshaling struct { - Gas math.HexOrDecimal64 - GasCost math.HexOrDecimal64 - Memory hexutil.Bytes - ReturnData hexutil.Bytes - Stack []hexutil.U256 - OpName string `json:"opName"` // adds call to OpName() in MarshalJSON - ErrorString string `json:"error,omitempty"` // adds call to ErrorString() in MarshalJSON -} - -// OpName formats the operand name in a human-readable format. -func (s *StructLog) OpName() string { - return s.Op.String() -} - -// ErrorString formats the log's error as a string. -func (s *StructLog) ErrorString() string { - if s.Err != nil { - return s.Err.Error() - } - return "" -} - -// StructLogger is an EVM state logger and implements EVMLogger. -// -// StructLogger can capture state based on the given Log configuration and also keeps -// a track record of modified storage which is used in reporting snapshots of the -// contract their storage. -type StructLogger struct { - cfg Config - env *vm.EVM - - storage map[common.Address]Storage - logs []StructLog - output []byte - err error - gasLimit uint64 - usedGas uint64 - - interrupt atomic.Bool // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption -} - -// NewStructLogger returns a new logger -func NewStructLogger(cfg *Config) *StructLogger { - logger := &StructLogger{ - storage: make(map[common.Address]Storage), - } - if cfg != nil { - logger.cfg = *cfg - } - return logger -} - -// Reset clears the data held by the logger. -func (l *StructLogger) Reset() { - l.storage = make(map[common.Address]Storage) - l.output = make([]byte, 0) - l.logs = l.logs[:0] - l.err = nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (l *StructLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - l.env = env -} - -// CaptureState logs a new structured log message and pushes it out to the environment -// -// CaptureState also tracks SLOAD/SSTORE ops to track storage change. -func (l *StructLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - // If tracing was interrupted, set the error and stop - if l.interrupt.Load() { - return - } - // check if already accumulated the specified number of logs - if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) { - return - } - - memory := scope.Memory - stack := scope.Stack - contract := scope.Contract - // Copy a snapshot of the current memory state to a new buffer - var mem []byte - if l.cfg.EnableMemory { - mem = make([]byte, len(memory.Data())) - copy(mem, memory.Data()) - } - // Copy a snapshot of the current stack state to a new buffer - var stck []uint256.Int - if !l.cfg.DisableStack { - stck = make([]uint256.Int, len(stack.Data())) - for i, item := range stack.Data() { - stck[i] = item - } - } - stackData := stack.Data() - stackLen := len(stackData) - // Copy a snapshot of the current storage to a new container - var storage Storage - if !l.cfg.DisableStorage && (op == vm.SLOAD || op == vm.SSTORE) { - // initialise new changed values storage container for this contract - // if not present. - if l.storage[contract.Address()] == nil { - l.storage[contract.Address()] = make(Storage) - } - // capture SLOAD opcodes and record the read entry in the local storage - if op == vm.SLOAD && stackLen >= 1 { - var ( - address = common.Hash(stackData[stackLen-1].Bytes32()) - value = l.env.StateDB.GetState(contract.Address(), address) - ) - l.storage[contract.Address()][address] = value - storage = l.storage[contract.Address()].Copy() - } else if op == vm.SSTORE && stackLen >= 2 { - // capture SSTORE opcodes and record the written entry in the local storage. - var ( - value = common.Hash(stackData[stackLen-2].Bytes32()) - address = common.Hash(stackData[stackLen-1].Bytes32()) - ) - l.storage[contract.Address()][address] = value - storage = l.storage[contract.Address()].Copy() - } - } - var rdata []byte - if l.cfg.EnableReturnData { - rdata = make([]byte, len(rData)) - copy(rdata, rData) - } - // create a new snapshot of the EVM. - log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, rdata, storage, depth, l.env.StateDB.GetRefund(), err} - l.logs = append(l.logs, log) -} - -// CaptureFault implements the EVMLogger interface to trace an execution fault -// while running an opcode. -func (l *StructLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (l *StructLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { - l.output = output - l.err = err - if l.cfg.Debug { - fmt.Printf("%#x\n", output) - if err != nil { - fmt.Printf(" error: %v\n", err) - } - } -} - -func (l *StructLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) { -} - -func (l *StructLogger) GetResult() (json.RawMessage, error) { - // Tracing aborted - if l.reason != nil { - return nil, l.reason - } - failed := l.err != nil - returnData := common.CopyBytes(l.output) - // Return data when successful and revert reason when reverted, otherwise empty. - returnVal := fmt.Sprintf("%x", returnData) - if failed && l.err != vmerrs.ErrExecutionReverted { - returnVal = "" - } - return json.Marshal(&ExecutionResult{ - Gas: l.usedGas, - Failed: failed, - ReturnValue: returnVal, - StructLogs: formatLogs(l.StructLogs()), - }) -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (l *StructLogger) Stop(err error) { - l.reason = err - l.interrupt.Store(true) -} - -func (l *StructLogger) CaptureTxStart(gasLimit uint64) { - l.gasLimit = gasLimit -} - -func (l *StructLogger) CaptureTxEnd(restGas uint64) { - l.usedGas = l.gasLimit - restGas -} - -// StructLogs returns the captured log entries. -func (l *StructLogger) StructLogs() []StructLog { return l.logs } - -// Error returns the VM error captured by the trace. -func (l *StructLogger) Error() error { return l.err } - -// Output returns the VM return value captured by the trace. -func (l *StructLogger) Output() []byte { return l.output } - -// WriteTrace writes a formatted trace to the given writer -func WriteTrace(writer io.Writer, logs []StructLog) { - for _, log := range logs { - fmt.Fprintf(writer, "%-16spc=%08d gas=%v cost=%v", log.Op, log.Pc, log.Gas, log.GasCost) - if log.Err != nil { - fmt.Fprintf(writer, " ERROR: %v", log.Err) - } - fmt.Fprintln(writer) - - if len(log.Stack) > 0 { - fmt.Fprintln(writer, "Stack:") - for i := len(log.Stack) - 1; i >= 0; i-- { - fmt.Fprintf(writer, "%08d %s\n", len(log.Stack)-i-1, log.Stack[i].Hex()) - } - } - if len(log.Memory) > 0 { - fmt.Fprintln(writer, "Memory:") - fmt.Fprint(writer, hex.Dump(log.Memory)) - } - if len(log.Storage) > 0 { - fmt.Fprintln(writer, "Storage:") - for h, item := range log.Storage { - fmt.Fprintf(writer, "%x: %x\n", h, item) - } - } - if len(log.ReturnData) > 0 { - fmt.Fprintln(writer, "ReturnData:") - fmt.Fprint(writer, hex.Dump(log.ReturnData)) - } - fmt.Fprintln(writer) - } -} - -// WriteLogs writes vm logs in a readable format to the given writer -func WriteLogs(writer io.Writer, logs []*types.Log) { - for _, log := range logs { - fmt.Fprintf(writer, "LOG%d: %x bn=%d txi=%x\n", len(log.Topics), log.Address, log.BlockNumber, log.TxIndex) - - for i, topic := range log.Topics { - fmt.Fprintf(writer, "%08d %x\n", i, topic) - } - - fmt.Fprint(writer, hex.Dump(log.Data)) - fmt.Fprintln(writer) - } -} - -type mdLogger struct { - out io.Writer - cfg *Config - env *vm.EVM -} - -// NewMarkdownLogger creates a logger which outputs information in a format adapted -// for human readability, and is also a valid markdown table -func NewMarkdownLogger(cfg *Config, writer io.Writer) *mdLogger { - l := &mdLogger{out: writer, cfg: cfg} - if l.cfg == nil { - l.cfg = &Config{} - } - return l -} - -func (t *mdLogger) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - t.env = env - if !create { - fmt.Fprintf(t.out, "From: `%v`\nTo: `%v`\nData: `%#x`\nGas: `%d`\nValue `%v` wei\n", - from.String(), to.String(), - input, gas, value) - } else { - fmt.Fprintf(t.out, "From: `%v`\nCreate at: `%v`\nData: `%#x`\nGas: `%d`\nValue `%v` wei\n", - from.String(), to.String(), - input, gas, value) - } - - fmt.Fprintf(t.out, ` -| Pc | Op | Cost | Stack | RStack | Refund | -|-------|-------------|------|-----------|-----------|---------| -`) -} - -// CaptureState also tracks SLOAD/SSTORE ops to track storage change. -func (t *mdLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - stack := scope.Stack - fmt.Fprintf(t.out, "| %4d | %10v | %3d |", pc, op, cost) - - if !t.cfg.DisableStack { - // format stack - var a []string - for _, elem := range stack.Data() { - a = append(a, elem.Hex()) - } - b := fmt.Sprintf("[%v]", strings.Join(a, ",")) - fmt.Fprintf(t.out, "%10v |", b) - } - fmt.Fprintf(t.out, "%10v |", t.env.StateDB.GetRefund()) - fmt.Fprintln(t.out, "") - if err != nil { - fmt.Fprintf(t.out, "Error: %v\n", err) - } -} - -func (t *mdLogger) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { - fmt.Fprintf(t.out, "\nError: at pc=%d, op=%v: %v\n", pc, op, err) -} - -func (t *mdLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { - fmt.Fprintf(t.out, "\nOutput: `%#x`\nConsumed gas: `%d`\nError: `%v`\n", - output, gasUsed, err) -} - -func (t *mdLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -func (t *mdLogger) CaptureExit(output []byte, gasUsed uint64, err error) {} - -func (*mdLogger) CaptureTxStart(gasLimit uint64) {} - -func (*mdLogger) CaptureTxEnd(restGas uint64) {} - -// ExecutionResult groups all structured logs emitted by the EVM -// while replaying a transaction in debug mode as well as transaction -// execution status, the amount of gas used and the return value -type ExecutionResult struct { - Gas uint64 `json:"gas"` - Failed bool `json:"failed"` - ReturnValue string `json:"returnValue"` - StructLogs []StructLogRes `json:"structLogs"` -} - -// StructLogRes stores a structured log emitted by the EVM while replaying a -// transaction in debug mode -type StructLogRes struct { - Pc uint64 `json:"pc"` - Op string `json:"op"` - Gas uint64 `json:"gas"` - GasCost uint64 `json:"gasCost"` - Depth int `json:"depth"` - Error string `json:"error,omitempty"` - Stack *[]string `json:"stack,omitempty"` - ReturnData string `json:"returnData,omitempty"` - Memory *[]string `json:"memory,omitempty"` - Storage *map[string]string `json:"storage,omitempty"` - RefundCounter uint64 `json:"refund,omitempty"` -} - -// formatLogs formats EVM returned structured logs for json output -func formatLogs(logs []StructLog) []StructLogRes { - formatted := make([]StructLogRes, len(logs)) - for index, trace := range logs { - formatted[index] = StructLogRes{ - Pc: trace.Pc, - Op: trace.Op.String(), - Gas: trace.Gas, - GasCost: trace.GasCost, - Depth: trace.Depth, - Error: trace.ErrorString(), - RefundCounter: trace.RefundCounter, - } - if trace.Stack != nil { - stack := make([]string, len(trace.Stack)) - for i, stackValue := range trace.Stack { - stack[i] = stackValue.Hex() - } - formatted[index].Stack = &stack - } - if len(trace.ReturnData) > 0 { - formatted[index].ReturnData = hexutil.Bytes(trace.ReturnData).String() - } - if trace.Memory != nil { - memory := make([]string, 0, (len(trace.Memory)+31)/32) - for i := 0; i+32 <= len(trace.Memory); i += 32 { - memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) - } - formatted[index].Memory = &memory - } - if trace.Storage != nil { - storage := make(map[string]string) - for i, storageValue := range trace.Storage { - storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) - } - formatted[index].Storage = &storage - } - } - return formatted -} diff --git a/eth/tracers/logger/logger_json.go b/eth/tracers/logger/logger_json.go deleted file mode 100644 index 3b2b783252..0000000000 --- a/eth/tracers/logger/logger_json.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package logger - -import ( - "encoding/json" - "io" - "math/big" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" -) - -type JSONLogger struct { - encoder *json.Encoder - cfg *Config - env *vm.EVM -} - -// NewJSONLogger creates a new EVM tracer that prints execution steps as JSON objects -// into the provided stream. -func NewJSONLogger(cfg *Config, writer io.Writer) *JSONLogger { - l := &JSONLogger{encoder: json.NewEncoder(writer), cfg: cfg} - if l.cfg == nil { - l.cfg = &Config{} - } - return l -} - -func (l *JSONLogger) CaptureStart(env *vm.EVM, from, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - l.env = env -} - -func (l *JSONLogger) CaptureFault(pc uint64, op vm.OpCode, gas uint64, cost uint64, scope *vm.ScopeContext, depth int, err error) { - // TODO: Add rData to this interface as well - l.CaptureState(pc, op, gas, cost, scope, nil, depth, err) -} - -// CaptureState outputs state information on the logger. -func (l *JSONLogger) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - memory := scope.Memory - stack := scope.Stack - - log := StructLog{ - Pc: pc, - Op: op, - Gas: gas, - GasCost: cost, - MemorySize: memory.Len(), - Depth: depth, - RefundCounter: l.env.StateDB.GetRefund(), - Err: err, - } - if l.cfg.EnableMemory { - log.Memory = memory.Data() - } - if !l.cfg.DisableStack { - log.Stack = stack.Data() - } - if l.cfg.EnableReturnData { - log.ReturnData = rData - } - l.encoder.Encode(log) -} - -// CaptureEnd is triggered at end of execution. -func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, err error) { - type endLog struct { - Output string `json:"output"` - GasUsed math.HexOrDecimal64 `json:"gasUsed"` - Err string `json:"error,omitempty"` - } - var errMsg string - if err != nil { - errMsg = err.Error() - } - l.encoder.Encode(endLog{common.Bytes2Hex(output), math.HexOrDecimal64(gasUsed), errMsg}) -} - -func (l *JSONLogger) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -func (l *JSONLogger) CaptureExit(output []byte, gasUsed uint64, err error) {} - -func (l *JSONLogger) CaptureTxStart(gasLimit uint64) {} - -func (l *JSONLogger) CaptureTxEnd(restGas uint64) {} diff --git a/eth/tracers/logger/logger_test.go b/eth/tracers/logger/logger_test.go deleted file mode 100644 index 0a2becf947..0000000000 --- a/eth/tracers/logger/logger_test.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package logger - -import ( - "encoding/json" - "errors" - "math/big" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -type dummyContractRef struct { - calledForEach bool -} - -func (dummyContractRef) Address() common.Address { return common.Address{} } -func (dummyContractRef) Value() *big.Int { return new(big.Int) } -func (dummyContractRef) SetCode(common.Hash, []byte) {} -func (d *dummyContractRef) ForEachStorage(callback func(key, value common.Hash) bool) { - d.calledForEach = true -} -func (d *dummyContractRef) SubBalance(amount *big.Int) {} -func (d *dummyContractRef) AddBalance(amount *big.Int) {} -func (d *dummyContractRef) SetBalance(*big.Int) {} -func (d *dummyContractRef) SetNonce(uint64) {} -func (d *dummyContractRef) Balance() *big.Int { return new(big.Int) } - -func TestStoreCapture(t *testing.T) { - var ( - logger = NewStructLogger(nil) - statedb, _ = state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) - env = vm.NewEVM(vm.BlockContext{}, vm.TxContext{}, statedb, params.TestChainConfig, vm.Config{Tracer: logger}) - contract = vm.NewContract(&dummyContractRef{}, &dummyContractRef{}, new(uint256.Int), 100000) - ) - contract.Code = []byte{byte(vm.PUSH1), 0x1, byte(vm.PUSH1), 0x0, byte(vm.SSTORE)} - var index common.Hash - logger.CaptureStart(env, common.Address{}, contract.Address(), false, nil, 0, nil) - statedb.Prepare(params.TestRules, common.Address{}, common.Address{}, nil, nil, nil) - _, err := env.Interpreter().Run(contract, []byte{}, false) - if err != nil { - t.Fatal(err) - } - if len(logger.storage[contract.Address()]) == 0 { - t.Fatalf("expected exactly 1 changed value on address %x, got %d", contract.Address(), - len(logger.storage[contract.Address()])) - } - exp := common.BigToHash(big.NewInt(1)) - if logger.storage[contract.Address()][index] != exp { - t.Errorf("expected %x, got %x", exp, logger.storage[contract.Address()][index]) - } -} - -// Tests that blank fields don't appear in logs when JSON marshalled, to reduce -// logs bloat and confusion. See https://github.com/ethereum/go-ethereum/issues/24487 -func TestStructLogMarshalingOmitEmpty(t *testing.T) { - tests := []struct { - name string - log *StructLog - want string - }{ - {"empty err and no fields", &StructLog{}, - `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memSize":0,"stack":null,"depth":0,"refund":0,"opName":"STOP"}`}, - {"with err", &StructLog{Err: errors.New("this failed")}, - `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memSize":0,"stack":null,"depth":0,"refund":0,"opName":"STOP","error":"this failed"}`}, - {"with mem", &StructLog{Memory: make([]byte, 2), MemorySize: 2}, - `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memory":"0x0000","memSize":2,"stack":null,"depth":0,"refund":0,"opName":"STOP"}`}, - {"with 0-size mem", &StructLog{Memory: make([]byte, 0)}, - `{"pc":0,"op":0,"gas":"0x0","gasCost":"0x0","memSize":0,"stack":null,"depth":0,"refund":0,"opName":"STOP"}`}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - blob, err := json.Marshal(tt.log) - if err != nil { - t.Fatal(err) - } - if have, want := string(blob), tt.want; have != want { - t.Fatalf("mismatched results\n\thave: %v\n\twant: %v", have, want) - } - }) - } -} diff --git a/eth/tracers/native/4byte.go b/eth/tracers/native/4byte.go deleted file mode 100644 index 113dfa3a4a..0000000000 --- a/eth/tracers/native/4byte.go +++ /dev/null @@ -1,142 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package native - -import ( - "encoding/json" - "math/big" - "strconv" - "sync/atomic" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ethereum/go-ethereum/common" -) - -func init() { - tracers.DefaultDirectory.Register("4byteTracer", newFourByteTracer, false) -} - -// fourByteTracer searches for 4byte-identifiers, and collects them for post-processing. -// It collects the methods identifiers along with the size of the supplied data, so -// a reversed signature can be matched against the size of the data. -// -// Example: -// -// > debug.traceTransaction( "0x214e597e35da083692f5386141e69f47e973b2c56e7a8073b1ea08fd7571e9de", {tracer: "4byteTracer"}) -// { -// 0x27dc297e-128: 1, -// 0x38cc4831-0: 2, -// 0x524f3889-96: 1, -// 0xadf59f99-288: 1, -// 0xc281d19e-0: 1 -// } -type fourByteTracer struct { - noopTracer - ids map[string]int // ids aggregates the 4byte ids found - interrupt atomic.Bool // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption - activePrecompiles []common.Address // Updated on CaptureStart based on given rules -} - -// newFourByteTracer returns a native go tracer which collects -// 4 byte-identifiers of a tx, and implements vm.EVMLogger. -func newFourByteTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) { - t := &fourByteTracer{ - ids: make(map[string]int), - } - return t, nil -} - -// isPrecompiled returns whether the addr is a precompile. Logic borrowed from newJsTracer in eth/tracers/js/tracer.go -func (t *fourByteTracer) isPrecompiled(addr common.Address) bool { - for _, p := range t.activePrecompiles { - if p == addr { - return true - } - } - return false -} - -// store saves the given identifier and datasize. -func (t *fourByteTracer) store(id []byte, size int) { - key := bytesToHex(id) + "-" + strconv.Itoa(size) - t.ids[key] += 1 -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *fourByteTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Time) - t.activePrecompiles = vm.ActivePrecompiles(rules) - - // Save the outer calldata also - if len(input) >= 4 { - t.store(input[0:4], len(input)-4) - } -} - -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *fourByteTracer) CaptureEnter(op vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - // Skip if tracing was interrupted - if t.interrupt.Load() { - return - } - if len(input) < 4 { - return - } - // primarily we want to avoid CREATE/CREATE2/SELFDESTRUCT - if op != vm.DELEGATECALL && op != vm.STATICCALL && - op != vm.CALL && op != vm.CALLCODE { - return - } - // Skip any pre-compile invocations, those are just fancy opcodes - if t.isPrecompiled(to) { - return - } - t.store(input[0:4], len(input)-4) -} - -// GetResult returns the json-encoded nested list of call traces, and any -// error arising from the encoding or forceful termination (via `Stop`). -func (t *fourByteTracer) GetResult() (json.RawMessage, error) { - res, err := json.Marshal(t.ids) - if err != nil { - return nil, err - } - return res, t.reason -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *fourByteTracer) Stop(err error) { - t.reason = err - t.interrupt.Store(true) -} - -func bytesToHex(s []byte) string { - return "0x" + common.Bytes2Hex(s) -} diff --git a/eth/tracers/native/call.go b/eth/tracers/native/call.go deleted file mode 100644 index ea2f0f8980..0000000000 --- a/eth/tracers/native/call.go +++ /dev/null @@ -1,300 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package native - -import ( - "encoding/json" - "errors" - "math/big" - "sync/atomic" - - "github.com/ava-labs/coreth/accounts/abi" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/log" -) - -//go:generate go run github.com/fjl/gencodec -type callFrame -field-override callFrameMarshaling -out gen_callframe_json.go - -func init() { - tracers.DefaultDirectory.Register("callTracer", newCallTracer, false) -} - -type callLog struct { - Address common.Address `json:"address"` - Topics []common.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` - // Position of the log relative to subcalls within the same trace - // See https://github.com/ethereum/go-ethereum/pull/28389 for details - Position hexutil.Uint `json:"position"` -} - -type callFrame struct { - Type vm.OpCode `json:"-"` - From common.Address `json:"from"` - Gas uint64 `json:"gas"` - GasUsed uint64 `json:"gasUsed"` - To *common.Address `json:"to,omitempty" rlp:"optional"` - Input []byte `json:"input" rlp:"optional"` - Output []byte `json:"output,omitempty" rlp:"optional"` - Error string `json:"error,omitempty" rlp:"optional"` - RevertReason string `json:"revertReason,omitempty"` - Calls []callFrame `json:"calls,omitempty" rlp:"optional"` - Logs []callLog `json:"logs,omitempty" rlp:"optional"` - // Placed at end on purpose. The RLP will be decoded to 0 instead of - // nil if there are non-empty elements after in the struct. - Value *big.Int `json:"value,omitempty" rlp:"optional"` -} - -func (f callFrame) TypeString() string { - return f.Type.String() -} - -func (f callFrame) failed() bool { - return len(f.Error) > 0 -} - -func (f *callFrame) processOutput(output []byte, err error) { - output = common.CopyBytes(output) - if err == nil { - f.Output = output - return - } - f.Error = err.Error() - if f.Type == vm.CREATE || f.Type == vm.CREATE2 { - f.To = nil - } - if !errors.Is(err, vmerrs.ErrExecutionReverted) || len(output) == 0 { - return - } - f.Output = output - if len(output) < 4 { - return - } - if unpacked, err := abi.UnpackRevert(output); err == nil { - f.RevertReason = unpacked - } -} - -type callFrameMarshaling struct { - TypeString string `json:"type"` - Gas hexutil.Uint64 - GasUsed hexutil.Uint64 - Value *hexutil.Big - Input hexutil.Bytes - Output hexutil.Bytes -} - -type callTracer struct { - noopTracer - callstack []callFrame - config callTracerConfig - gasLimit uint64 - interrupt atomic.Bool // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption -} - -type callTracerConfig struct { - OnlyTopCall bool `json:"onlyTopCall"` // If true, call tracer won't collect any subcalls - WithLog bool `json:"withLog"` // If true, call tracer will collect event logs -} - -// newCallTracer returns a native go tracer which tracks -// call frames of a tx, and implements vm.EVMLogger. -func newCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { - var config callTracerConfig - if cfg != nil { - if err := json.Unmarshal(cfg, &config); err != nil { - return nil, err - } - } - // First callframe contains tx context info - // and is populated on start and end. - return &callTracer{callstack: make([]callFrame, 1), config: config}, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *callTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - toCopy := to - t.callstack[0] = callFrame{ - Type: vm.CALL, - From: from, - To: &toCopy, - Input: common.CopyBytes(input), - Gas: t.gasLimit, - Value: value, - } - if create { - t.callstack[0].Type = vm.CREATE - } -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *callTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - t.callstack[0].processOutput(output, err) -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *callTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - // skip if the previous op caused an error - if err != nil { - return - } - // Only logs need to be captured via opcode processing - if !t.config.WithLog { - return - } - // Avoid processing nested calls when only caring about top call - if t.config.OnlyTopCall && depth > 1 { - return - } - // Skip if tracing was interrupted - if t.interrupt.Load() { - return - } - switch op { - case vm.LOG0, vm.LOG1, vm.LOG2, vm.LOG3, vm.LOG4: - size := int(op - vm.LOG0) - - stack := scope.Stack - stackData := stack.Data() - - // Don't modify the stack - mStart := stackData[len(stackData)-1] - mSize := stackData[len(stackData)-2] - topics := make([]common.Hash, size) - for i := 0; i < size; i++ { - topic := stackData[len(stackData)-2-(i+1)] - topics[i] = common.Hash(topic.Bytes32()) - } - - data, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(mStart.Uint64()), int64(mSize.Uint64())) - if err != nil { - // mSize was unrealistically large - log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "callTracer", "offset", mStart, "size", mSize) - return - } - - log := callLog{ - Address: scope.Contract.Address(), - Topics: topics, - Data: hexutil.Bytes(data), - Position: hexutil.Uint(len(t.callstack[len(t.callstack)-1].Calls)), - } - t.callstack[len(t.callstack)-1].Logs = append(t.callstack[len(t.callstack)-1].Logs, log) - } -} - -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *callTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - if t.config.OnlyTopCall { - return - } - // Skip if tracing was interrupted - if t.interrupt.Load() { - return - } - - toCopy := to - call := callFrame{ - Type: typ, - From: from, - To: &toCopy, - Input: common.CopyBytes(input), - Gas: gas, - Value: value, - } - t.callstack = append(t.callstack, call) -} - -// CaptureExit is called when EVM exits a scope, even if the scope didn't -// execute any code. -func (t *callTracer) CaptureExit(output []byte, gasUsed uint64, err error) { - if t.config.OnlyTopCall { - return - } - size := len(t.callstack) - if size <= 1 { - return - } - // pop call - call := t.callstack[size-1] - t.callstack = t.callstack[:size-1] - size -= 1 - - call.GasUsed = gasUsed - call.processOutput(output, err) - t.callstack[size-1].Calls = append(t.callstack[size-1].Calls, call) -} - -func (t *callTracer) CaptureTxStart(gasLimit uint64) { - t.gasLimit = gasLimit -} - -func (t *callTracer) CaptureTxEnd(restGas uint64) { - t.callstack[0].GasUsed = t.gasLimit - restGas - if t.config.WithLog { - // Logs are not emitted when the call fails - clearFailedLogs(&t.callstack[0], false) - } -} - -// GetResult returns the json-encoded nested list of call traces, and any -// error arising from the encoding or forceful termination (via `Stop`). -func (t *callTracer) GetResult() (json.RawMessage, error) { - if len(t.callstack) != 1 { - return nil, errors.New("incorrect number of top-level calls") - } - - res, err := json.Marshal(t.callstack[0]) - if err != nil { - return nil, err - } - return json.RawMessage(res), t.reason -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *callTracer) Stop(err error) { - t.reason = err - t.interrupt.Store(true) -} - -// clearFailedLogs clears the logs of a callframe and all its children -// in case of execution failure. -func clearFailedLogs(cf *callFrame, parentFailed bool) { - failed := cf.failed() || parentFailed - // Clear own logs - if failed { - cf.Logs = nil - } - for i := range cf.Calls { - clearFailedLogs(&cf.Calls[i], failed) - } -} diff --git a/eth/tracers/native/call_flat.go b/eth/tracers/native/call_flat.go deleted file mode 100644 index 7f5f2ca287..0000000000 --- a/eth/tracers/native/call_flat.go +++ /dev/null @@ -1,392 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package native - -import ( - "encoding/json" - "errors" - "fmt" - "math/big" - "strings" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -//go:generate go run github.com/fjl/gencodec -type flatCallAction -field-override flatCallActionMarshaling -out gen_flatcallaction_json.go -//go:generate go run github.com/fjl/gencodec -type flatCallResult -field-override flatCallResultMarshaling -out gen_flatcallresult_json.go - -func init() { - tracers.DefaultDirectory.Register("flatCallTracer", newFlatCallTracer, false) -} - -var parityErrorMapping = map[string]string{ - "contract creation code storage out of gas": "Out of gas", - "out of gas": "Out of gas", - "gas uint64 overflow": "Out of gas", - "max code size exceeded": "Out of gas", - "invalid jump destination": "Bad jump destination", - "execution reverted": "Reverted", - "return data out of bounds": "Out of bounds", - "stack limit reached 1024 (1023)": "Out of stack", - "precompiled failed": "Built-in failed", - "invalid input length": "Built-in failed", -} - -var parityErrorMappingStartingWith = map[string]string{ - "invalid opcode:": "Bad instruction", - "stack underflow": "Stack underflow", -} - -// flatCallFrame is a standalone callframe. -type flatCallFrame struct { - Action flatCallAction `json:"action"` - BlockHash *common.Hash `json:"blockHash"` - BlockNumber uint64 `json:"blockNumber"` - Error string `json:"error,omitempty"` - Result *flatCallResult `json:"result,omitempty"` - Subtraces int `json:"subtraces"` - TraceAddress []int `json:"traceAddress"` - TransactionHash *common.Hash `json:"transactionHash"` - TransactionPosition uint64 `json:"transactionPosition"` - Type string `json:"type"` -} - -type flatCallAction struct { - Author *common.Address `json:"author,omitempty"` - RewardType string `json:"rewardType,omitempty"` - SelfDestructed *common.Address `json:"address,omitempty"` - Balance *big.Int `json:"balance,omitempty"` - CallType string `json:"callType,omitempty"` - CreationMethod string `json:"creationMethod,omitempty"` - From *common.Address `json:"from,omitempty"` - Gas *uint64 `json:"gas,omitempty"` - Init *[]byte `json:"init,omitempty"` - Input *[]byte `json:"input,omitempty"` - RefundAddress *common.Address `json:"refundAddress,omitempty"` - To *common.Address `json:"to,omitempty"` - Value *big.Int `json:"value,omitempty"` -} - -type flatCallActionMarshaling struct { - Balance *hexutil.Big - Gas *hexutil.Uint64 - Init *hexutil.Bytes - Input *hexutil.Bytes - Value *hexutil.Big -} - -type flatCallResult struct { - Address *common.Address `json:"address,omitempty"` - Code *[]byte `json:"code,omitempty"` - GasUsed *uint64 `json:"gasUsed,omitempty"` - Output *[]byte `json:"output,omitempty"` -} - -type flatCallResultMarshaling struct { - Code *hexutil.Bytes - GasUsed *hexutil.Uint64 - Output *hexutil.Bytes -} - -// flatCallTracer reports call frame information of a tx in a flat format, i.e. -// as opposed to the nested format of `callTracer`. -type flatCallTracer struct { - tracer *callTracer - config flatCallTracerConfig - ctx *tracers.Context // Holds tracer context data - reason error // Textual reason for the interruption - activePrecompiles []common.Address // Updated on CaptureStart based on given rules -} - -type flatCallTracerConfig struct { - ConvertParityErrors bool `json:"convertParityErrors"` // If true, call tracer converts errors to parity format - IncludePrecompiles bool `json:"includePrecompiles"` // If true, call tracer includes calls to precompiled contracts -} - -// newFlatCallTracer returns a new flatCallTracer. -func newFlatCallTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { - var config flatCallTracerConfig - if cfg != nil { - if err := json.Unmarshal(cfg, &config); err != nil { - return nil, err - } - } - - // Create inner call tracer with default configuration, don't forward - // the OnlyTopCall or WithLog to inner for now - tracer, err := tracers.DefaultDirectory.New("callTracer", ctx, nil) - if err != nil { - return nil, err - } - t, ok := tracer.(*callTracer) - if !ok { - return nil, errors.New("internal error: embedded tracer has wrong type") - } - - return &flatCallTracer{tracer: t, ctx: ctx, config: config}, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *flatCallTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - t.tracer.CaptureStart(env, from, to, create, input, gas, value) - // Update list of precompiles based on current block - rules := env.ChainConfig().Rules(env.Context.BlockNumber, env.Context.Time) - t.activePrecompiles = vm.ActivePrecompiles(rules) -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *flatCallTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - t.tracer.CaptureEnd(output, gasUsed, err) -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *flatCallTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - t.tracer.CaptureState(pc, op, gas, cost, scope, rData, depth, err) -} - -// CaptureFault implements the EVMLogger interface to trace an execution fault. -func (t *flatCallTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { - t.tracer.CaptureFault(pc, op, gas, cost, scope, depth, err) -} - -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *flatCallTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - t.tracer.CaptureEnter(typ, from, to, input, gas, value) - - // Child calls must have a value, even if it's zero. - // Practically speaking, only STATICCALL has nil value. Set it to zero. - if t.tracer.callstack[len(t.tracer.callstack)-1].Value == nil && value == nil { - t.tracer.callstack[len(t.tracer.callstack)-1].Value = big.NewInt(0) - } -} - -// CaptureExit is called when EVM exits a scope, even if the scope didn't -// execute any code. -func (t *flatCallTracer) CaptureExit(output []byte, gasUsed uint64, err error) { - t.tracer.CaptureExit(output, gasUsed, err) - - // Parity traces don't include CALL/STATICCALLs to precompiles. - // By default we remove them from the callstack. - if t.config.IncludePrecompiles { - return - } - var ( - // call has been nested in parent - parent = t.tracer.callstack[len(t.tracer.callstack)-1] - call = parent.Calls[len(parent.Calls)-1] - typ = call.Type - to = call.To - ) - if typ == vm.CALL || typ == vm.STATICCALL { - if t.isPrecompiled(*to) { - t.tracer.callstack[len(t.tracer.callstack)-1].Calls = parent.Calls[:len(parent.Calls)-1] - } - } -} - -func (t *flatCallTracer) CaptureTxStart(gasLimit uint64) { - t.tracer.CaptureTxStart(gasLimit) -} - -func (t *flatCallTracer) CaptureTxEnd(restGas uint64) { - t.tracer.CaptureTxEnd(restGas) -} - -// GetResult returns an empty json object. -func (t *flatCallTracer) GetResult() (json.RawMessage, error) { - if len(t.tracer.callstack) < 1 { - return nil, errors.New("invalid number of calls") - } - - flat, err := flatFromNested(&t.tracer.callstack[0], []int{}, t.config.ConvertParityErrors, t.ctx) - if err != nil { - return nil, err - } - - res, err := json.Marshal(flat) - if err != nil { - return nil, err - } - return res, t.reason -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *flatCallTracer) Stop(err error) { - t.tracer.Stop(err) -} - -// isPrecompiled returns whether the addr is a precompile. -func (t *flatCallTracer) isPrecompiled(addr common.Address) bool { - for _, p := range t.activePrecompiles { - if p == addr { - return true - } - } - return false -} - -func flatFromNested(input *callFrame, traceAddress []int, convertErrs bool, ctx *tracers.Context) (output []flatCallFrame, err error) { - var frame *flatCallFrame - switch input.Type { - case vm.CREATE, vm.CREATE2: - frame = newFlatCreate(input) - case vm.SELFDESTRUCT: - frame = newFlatSelfdestruct(input) - case vm.CALL, vm.STATICCALL, vm.CALLCODE, vm.DELEGATECALL: - frame = newFlatCall(input) - default: - return nil, fmt.Errorf("unrecognized call frame type: %s", input.Type) - } - - frame.TraceAddress = traceAddress - frame.Error = input.Error - frame.Subtraces = len(input.Calls) - fillCallFrameFromContext(frame, ctx) - if convertErrs { - convertErrorToParity(frame) - } - - // Revert output contains useful information (revert reason). - // Otherwise discard result. - if input.Error != "" && input.Error != vmerrs.ErrExecutionReverted.Error() { - frame.Result = nil - } - - output = append(output, *frame) - if len(input.Calls) > 0 { - for i, childCall := range input.Calls { - childAddr := childTraceAddress(traceAddress, i) - childCallCopy := childCall - flat, err := flatFromNested(&childCallCopy, childAddr, convertErrs, ctx) - if err != nil { - return nil, err - } - output = append(output, flat...) - } - } - - return output, nil -} - -func newFlatCreate(input *callFrame) *flatCallFrame { - var ( - actionInit = input.Input[:] - resultCode = input.Output[:] - ) - - return &flatCallFrame{ - Type: strings.ToLower(vm.CREATE.String()), - Action: flatCallAction{ - From: &input.From, - Gas: &input.Gas, - Value: input.Value, - Init: &actionInit, - }, - Result: &flatCallResult{ - GasUsed: &input.GasUsed, - Address: input.To, - Code: &resultCode, - }, - } -} - -func newFlatCall(input *callFrame) *flatCallFrame { - var ( - actionInput = input.Input[:] - resultOutput = input.Output[:] - ) - - return &flatCallFrame{ - Type: strings.ToLower(vm.CALL.String()), - Action: flatCallAction{ - From: &input.From, - To: input.To, - Gas: &input.Gas, - Value: input.Value, - CallType: strings.ToLower(input.Type.String()), - Input: &actionInput, - }, - Result: &flatCallResult{ - GasUsed: &input.GasUsed, - Output: &resultOutput, - }, - } -} - -func newFlatSelfdestruct(input *callFrame) *flatCallFrame { - return &flatCallFrame{ - Type: "suicide", - Action: flatCallAction{ - SelfDestructed: &input.From, - Balance: input.Value, - RefundAddress: input.To, - }, - } -} - -func fillCallFrameFromContext(callFrame *flatCallFrame, ctx *tracers.Context) { - if ctx == nil { - return - } - if ctx.BlockHash != (common.Hash{}) { - callFrame.BlockHash = &ctx.BlockHash - } - if ctx.BlockNumber != nil { - callFrame.BlockNumber = ctx.BlockNumber.Uint64() - } - if ctx.TxHash != (common.Hash{}) { - callFrame.TransactionHash = &ctx.TxHash - } - callFrame.TransactionPosition = uint64(ctx.TxIndex) -} - -func convertErrorToParity(call *flatCallFrame) { - if call.Error == "" { - return - } - - if parityError, ok := parityErrorMapping[call.Error]; ok { - call.Error = parityError - } else { - for gethError, parityError := range parityErrorMappingStartingWith { - if strings.HasPrefix(call.Error, gethError) { - call.Error = parityError - } - } - } -} - -func childTraceAddress(a []int, i int) []int { - child := make([]int, 0, len(a)+1) - child = append(child, a...) - child = append(child, i) - return child -} diff --git a/eth/tracers/native/gen_account_json.go b/eth/tracers/native/gen_account_json.go deleted file mode 100644 index 4c39cbc38c..0000000000 --- a/eth/tracers/native/gen_account_json.go +++ /dev/null @@ -1,56 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package native - -import ( - "encoding/json" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*accountMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (a account) MarshalJSON() ([]byte, error) { - type account struct { - Balance *hexutil.Big `json:"balance,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` - Nonce uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` - } - var enc account - enc.Balance = (*hexutil.Big)(a.Balance) - enc.Code = a.Code - enc.Nonce = a.Nonce - enc.Storage = a.Storage - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (a *account) UnmarshalJSON(input []byte) error { - type account struct { - Balance *hexutil.Big `json:"balance,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` - Nonce *uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` - } - var dec account - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Balance != nil { - a.Balance = (*big.Int)(dec.Balance) - } - if dec.Code != nil { - a.Code = *dec.Code - } - if dec.Nonce != nil { - a.Nonce = *dec.Nonce - } - if dec.Storage != nil { - a.Storage = dec.Storage - } - return nil -} diff --git a/eth/tracers/native/gen_callframe_json.go b/eth/tracers/native/gen_callframe_json.go deleted file mode 100644 index 15e9f09654..0000000000 --- a/eth/tracers/native/gen_callframe_json.go +++ /dev/null @@ -1,107 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package native - -import ( - "encoding/json" - "math/big" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*callFrameMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (c callFrame) MarshalJSON() ([]byte, error) { - type callFrame0 struct { - Type vm.OpCode `json:"-"` - From common.Address `json:"from"` - Gas hexutil.Uint64 `json:"gas"` - GasUsed hexutil.Uint64 `json:"gasUsed"` - To *common.Address `json:"to,omitempty" rlp:"optional"` - Input hexutil.Bytes `json:"input" rlp:"optional"` - Output hexutil.Bytes `json:"output,omitempty" rlp:"optional"` - Error string `json:"error,omitempty" rlp:"optional"` - RevertReason string `json:"revertReason,omitempty"` - Calls []callFrame `json:"calls,omitempty" rlp:"optional"` - Logs []callLog `json:"logs,omitempty" rlp:"optional"` - Value *hexutil.Big `json:"value,omitempty" rlp:"optional"` - TypeString string `json:"type"` - } - var enc callFrame0 - enc.Type = c.Type - enc.From = c.From - enc.Gas = hexutil.Uint64(c.Gas) - enc.GasUsed = hexutil.Uint64(c.GasUsed) - enc.To = c.To - enc.Input = c.Input - enc.Output = c.Output - enc.Error = c.Error - enc.RevertReason = c.RevertReason - enc.Calls = c.Calls - enc.Logs = c.Logs - enc.Value = (*hexutil.Big)(c.Value) - enc.TypeString = c.TypeString() - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (c *callFrame) UnmarshalJSON(input []byte) error { - type callFrame0 struct { - Type *vm.OpCode `json:"-"` - From *common.Address `json:"from"` - Gas *hexutil.Uint64 `json:"gas"` - GasUsed *hexutil.Uint64 `json:"gasUsed"` - To *common.Address `json:"to,omitempty" rlp:"optional"` - Input *hexutil.Bytes `json:"input" rlp:"optional"` - Output *hexutil.Bytes `json:"output,omitempty" rlp:"optional"` - Error *string `json:"error,omitempty" rlp:"optional"` - RevertReason *string `json:"revertReason,omitempty"` - Calls []callFrame `json:"calls,omitempty" rlp:"optional"` - Logs []callLog `json:"logs,omitempty" rlp:"optional"` - Value *hexutil.Big `json:"value,omitempty" rlp:"optional"` - } - var dec callFrame0 - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Type != nil { - c.Type = *dec.Type - } - if dec.From != nil { - c.From = *dec.From - } - if dec.Gas != nil { - c.Gas = uint64(*dec.Gas) - } - if dec.GasUsed != nil { - c.GasUsed = uint64(*dec.GasUsed) - } - if dec.To != nil { - c.To = dec.To - } - if dec.Input != nil { - c.Input = *dec.Input - } - if dec.Output != nil { - c.Output = *dec.Output - } - if dec.Error != nil { - c.Error = *dec.Error - } - if dec.RevertReason != nil { - c.RevertReason = *dec.RevertReason - } - if dec.Calls != nil { - c.Calls = dec.Calls - } - if dec.Logs != nil { - c.Logs = dec.Logs - } - if dec.Value != nil { - c.Value = (*big.Int)(dec.Value) - } - return nil -} diff --git a/eth/tracers/native/gen_flatcallaction_json.go b/eth/tracers/native/gen_flatcallaction_json.go deleted file mode 100644 index c075606983..0000000000 --- a/eth/tracers/native/gen_flatcallaction_json.go +++ /dev/null @@ -1,110 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package native - -import ( - "encoding/json" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*flatCallActionMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (f flatCallAction) MarshalJSON() ([]byte, error) { - type flatCallAction struct { - Author *common.Address `json:"author,omitempty"` - RewardType string `json:"rewardType,omitempty"` - SelfDestructed *common.Address `json:"address,omitempty"` - Balance *hexutil.Big `json:"balance,omitempty"` - CallType string `json:"callType,omitempty"` - CreationMethod string `json:"creationMethod,omitempty"` - From *common.Address `json:"from,omitempty"` - Gas *hexutil.Uint64 `json:"gas,omitempty"` - Init *hexutil.Bytes `json:"init,omitempty"` - Input *hexutil.Bytes `json:"input,omitempty"` - RefundAddress *common.Address `json:"refundAddress,omitempty"` - To *common.Address `json:"to,omitempty"` - Value *hexutil.Big `json:"value,omitempty"` - } - var enc flatCallAction - enc.Author = f.Author - enc.RewardType = f.RewardType - enc.SelfDestructed = f.SelfDestructed - enc.Balance = (*hexutil.Big)(f.Balance) - enc.CallType = f.CallType - enc.CreationMethod = f.CreationMethod - enc.From = f.From - enc.Gas = (*hexutil.Uint64)(f.Gas) - enc.Init = (*hexutil.Bytes)(f.Init) - enc.Input = (*hexutil.Bytes)(f.Input) - enc.RefundAddress = f.RefundAddress - enc.To = f.To - enc.Value = (*hexutil.Big)(f.Value) - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (f *flatCallAction) UnmarshalJSON(input []byte) error { - type flatCallAction struct { - Author *common.Address `json:"author,omitempty"` - RewardType *string `json:"rewardType,omitempty"` - SelfDestructed *common.Address `json:"address,omitempty"` - Balance *hexutil.Big `json:"balance,omitempty"` - CallType *string `json:"callType,omitempty"` - CreationMethod *string `json:"creationMethod,omitempty"` - From *common.Address `json:"from,omitempty"` - Gas *hexutil.Uint64 `json:"gas,omitempty"` - Init *hexutil.Bytes `json:"init,omitempty"` - Input *hexutil.Bytes `json:"input,omitempty"` - RefundAddress *common.Address `json:"refundAddress,omitempty"` - To *common.Address `json:"to,omitempty"` - Value *hexutil.Big `json:"value,omitempty"` - } - var dec flatCallAction - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Author != nil { - f.Author = dec.Author - } - if dec.RewardType != nil { - f.RewardType = *dec.RewardType - } - if dec.SelfDestructed != nil { - f.SelfDestructed = dec.SelfDestructed - } - if dec.Balance != nil { - f.Balance = (*big.Int)(dec.Balance) - } - if dec.CallType != nil { - f.CallType = *dec.CallType - } - if dec.CreationMethod != nil { - f.CreationMethod = *dec.CreationMethod - } - if dec.From != nil { - f.From = dec.From - } - if dec.Gas != nil { - f.Gas = (*uint64)(dec.Gas) - } - if dec.Init != nil { - f.Init = (*[]byte)(dec.Init) - } - if dec.Input != nil { - f.Input = (*[]byte)(dec.Input) - } - if dec.RefundAddress != nil { - f.RefundAddress = dec.RefundAddress - } - if dec.To != nil { - f.To = dec.To - } - if dec.Value != nil { - f.Value = (*big.Int)(dec.Value) - } - return nil -} diff --git a/eth/tracers/native/gen_flatcallresult_json.go b/eth/tracers/native/gen_flatcallresult_json.go deleted file mode 100644 index e9fa5e44da..0000000000 --- a/eth/tracers/native/gen_flatcallresult_json.go +++ /dev/null @@ -1,55 +0,0 @@ -// Code generated by github.com/fjl/gencodec. DO NOT EDIT. - -package native - -import ( - "encoding/json" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" -) - -var _ = (*flatCallResultMarshaling)(nil) - -// MarshalJSON marshals as JSON. -func (f flatCallResult) MarshalJSON() ([]byte, error) { - type flatCallResult struct { - Address *common.Address `json:"address,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` - GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"` - Output *hexutil.Bytes `json:"output,omitempty"` - } - var enc flatCallResult - enc.Address = f.Address - enc.Code = (*hexutil.Bytes)(f.Code) - enc.GasUsed = (*hexutil.Uint64)(f.GasUsed) - enc.Output = (*hexutil.Bytes)(f.Output) - return json.Marshal(&enc) -} - -// UnmarshalJSON unmarshals from JSON. -func (f *flatCallResult) UnmarshalJSON(input []byte) error { - type flatCallResult struct { - Address *common.Address `json:"address,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` - GasUsed *hexutil.Uint64 `json:"gasUsed,omitempty"` - Output *hexutil.Bytes `json:"output,omitempty"` - } - var dec flatCallResult - if err := json.Unmarshal(input, &dec); err != nil { - return err - } - if dec.Address != nil { - f.Address = dec.Address - } - if dec.Code != nil { - f.Code = (*[]byte)(dec.Code) - } - if dec.GasUsed != nil { - f.GasUsed = (*uint64)(dec.GasUsed) - } - if dec.Output != nil { - f.Output = (*[]byte)(dec.Output) - } - return nil -} diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go deleted file mode 100644 index 02a606e21d..0000000000 --- a/eth/tracers/native/mux.go +++ /dev/null @@ -1,148 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package native - -import ( - "encoding/json" - "math/big" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ethereum/go-ethereum/common" -) - -func init() { - tracers.DefaultDirectory.Register("muxTracer", newMuxTracer, false) -} - -// muxTracer is a go implementation of the Tracer interface which -// runs multiple tracers in one go. -type muxTracer struct { - names []string - tracers []tracers.Tracer -} - -// newMuxTracer returns a new mux tracer. -func newMuxTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { - var config map[string]json.RawMessage - if cfg != nil { - if err := json.Unmarshal(cfg, &config); err != nil { - return nil, err - } - } - objects := make([]tracers.Tracer, 0, len(config)) - names := make([]string, 0, len(config)) - for k, v := range config { - t, err := tracers.DefaultDirectory.New(k, ctx, v) - if err != nil { - return nil, err - } - objects = append(objects, t) - names = append(names, k) - } - - return &muxTracer{names: names, tracers: objects}, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *muxTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - for _, t := range t.tracers { - t.CaptureStart(env, from, to, create, input, gas, value) - } -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *muxTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - for _, t := range t.tracers { - t.CaptureEnd(output, gasUsed, err) - } -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *muxTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - for _, t := range t.tracers { - t.CaptureState(pc, op, gas, cost, scope, rData, depth, err) - } -} - -// CaptureFault implements the EVMLogger interface to trace an execution fault. -func (t *muxTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, depth int, err error) { - for _, t := range t.tracers { - t.CaptureFault(pc, op, gas, cost, scope, depth, err) - } -} - -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *muxTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { - for _, t := range t.tracers { - t.CaptureEnter(typ, from, to, input, gas, value) - } -} - -// CaptureExit is called when EVM exits a scope, even if the scope didn't -// execute any code. -func (t *muxTracer) CaptureExit(output []byte, gasUsed uint64, err error) { - for _, t := range t.tracers { - t.CaptureExit(output, gasUsed, err) - } -} - -func (t *muxTracer) CaptureTxStart(gasLimit uint64) { - for _, t := range t.tracers { - t.CaptureTxStart(gasLimit) - } -} - -func (t *muxTracer) CaptureTxEnd(restGas uint64) { - for _, t := range t.tracers { - t.CaptureTxEnd(restGas) - } -} - -// GetResult returns an empty json object. -func (t *muxTracer) GetResult() (json.RawMessage, error) { - resObject := make(map[string]json.RawMessage) - for i, tt := range t.tracers { - r, err := tt.GetResult() - if err != nil { - return nil, err - } - resObject[t.names[i]] = r - } - res, err := json.Marshal(resObject) - if err != nil { - return nil, err - } - return res, nil -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *muxTracer) Stop(err error) { - for _, t := range t.tracers { - t.Stop(err) - } -} diff --git a/eth/tracers/native/noop.go b/eth/tracers/native/noop.go deleted file mode 100644 index 11daa94aa4..0000000000 --- a/eth/tracers/native/noop.go +++ /dev/null @@ -1,87 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2021 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package native - -import ( - "encoding/json" - "math/big" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ethereum/go-ethereum/common" -) - -func init() { - tracers.DefaultDirectory.Register("noopTracer", newNoopTracer, false) -} - -// noopTracer is a go implementation of the Tracer interface which -// performs no action. It's mostly useful for testing purposes. -type noopTracer struct{} - -// newNoopTracer returns a new noop tracer. -func newNoopTracer(ctx *tracers.Context, _ json.RawMessage) (tracers.Tracer, error) { - return &noopTracer{}, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *noopTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *noopTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *noopTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { -} - -// CaptureFault implements the EVMLogger interface to trace an execution fault. -func (t *noopTracer) CaptureFault(pc uint64, op vm.OpCode, gas, cost uint64, _ *vm.ScopeContext, depth int, err error) { -} - -// CaptureEnter is called when EVM enters a new scope (via call, create or selfdestruct). -func (t *noopTracer) CaptureEnter(typ vm.OpCode, from common.Address, to common.Address, input []byte, gas uint64, value *big.Int) { -} - -// CaptureExit is called when EVM exits a scope, even if the scope didn't -// execute any code. -func (t *noopTracer) CaptureExit(output []byte, gasUsed uint64, err error) { -} - -func (*noopTracer) CaptureTxStart(gasLimit uint64) {} - -func (*noopTracer) CaptureTxEnd(restGas uint64) {} - -// GetResult returns an empty json object. -func (t *noopTracer) GetResult() (json.RawMessage, error) { - return json.RawMessage(`{}`), nil -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *noopTracer) Stop(err error) { -} diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go deleted file mode 100644 index 76ed4be967..0000000000 --- a/eth/tracers/native/prestate.go +++ /dev/null @@ -1,315 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package native - -import ( - "bytes" - "encoding/json" - "math/big" - "sync/atomic" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" -) - -//go:generate go run github.com/fjl/gencodec -type account -field-override accountMarshaling -out gen_account_json.go - -func init() { - tracers.DefaultDirectory.Register("prestateTracer", newPrestateTracer, false) -} - -type state = map[common.Address]*account - -type account struct { - Balance *big.Int `json:"balance,omitempty"` - Code []byte `json:"code,omitempty"` - Nonce uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` -} - -func (a *account) exists() bool { - return a.Nonce > 0 || len(a.Code) > 0 || len(a.Storage) > 0 || (a.Balance != nil && a.Balance.Sign() != 0) -} - -type accountMarshaling struct { - Balance *hexutil.Big - Code hexutil.Bytes -} - -type prestateTracer struct { - noopTracer - env *vm.EVM - pre state - post state - create bool - to common.Address - gasLimit uint64 // Amount of gas bought for the whole tx - config prestateTracerConfig - interrupt atomic.Bool // Atomic flag to signal execution interruption - reason error // Textual reason for the interruption - created map[common.Address]bool - deleted map[common.Address]bool -} - -type prestateTracerConfig struct { - DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications -} - -func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage) (tracers.Tracer, error) { - var config prestateTracerConfig - if cfg != nil { - if err := json.Unmarshal(cfg, &config); err != nil { - return nil, err - } - } - return &prestateTracer{ - pre: state{}, - post: state{}, - config: config, - created: make(map[common.Address]bool), - deleted: make(map[common.Address]bool), - }, nil -} - -// CaptureStart implements the EVMLogger interface to initialize the tracing operation. -func (t *prestateTracer) CaptureStart(env *vm.EVM, from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) { - t.env = env - t.create = create - t.to = to - - t.lookupAccount(from) - t.lookupAccount(to) - t.lookupAccount(env.Context.Coinbase) - - // The recipient balance includes the value transferred. - toBal := new(big.Int).Sub(t.pre[to].Balance, value) - t.pre[to].Balance = toBal - - // The sender balance is after reducing: value and gasLimit. - // We need to re-add them to get the pre-tx balance. - fromBal := new(big.Int).Set(t.pre[from].Balance) - gasPrice := env.TxContext.GasPrice - consumedGas := new(big.Int).Mul(gasPrice, new(big.Int).SetUint64(t.gasLimit)) - fromBal.Add(fromBal, new(big.Int).Add(value, consumedGas)) - t.pre[from].Balance = fromBal - t.pre[from].Nonce-- - - if create && t.config.DiffMode { - t.created[to] = true - } -} - -// CaptureEnd is called after the call finishes to finalize the tracing. -func (t *prestateTracer) CaptureEnd(output []byte, gasUsed uint64, err error) { - if t.config.DiffMode { - return - } - - if t.create { - // Keep existing account prior to contract creation at that address - if s := t.pre[t.to]; s != nil && !s.exists() { - // Exclude newly created contract. - delete(t.pre, t.to) - } - } -} - -// CaptureState implements the EVMLogger interface to trace a single step of VM execution. -func (t *prestateTracer) CaptureState(pc uint64, op vm.OpCode, gas, cost uint64, scope *vm.ScopeContext, rData []byte, depth int, err error) { - if err != nil { - return - } - // Skip if tracing was interrupted - if t.interrupt.Load() { - return - } - stack := scope.Stack - stackData := stack.Data() - stackLen := len(stackData) - caller := scope.Contract.Address() - switch { - case stackLen >= 1 && (op == vm.SLOAD || op == vm.SSTORE): - slot := common.Hash(stackData[stackLen-1].Bytes32()) - t.lookupStorage(caller, slot) - case stackLen >= 1 && (op == vm.EXTCODECOPY || op == vm.EXTCODEHASH || op == vm.EXTCODESIZE || op == vm.BALANCE || op == vm.SELFDESTRUCT): - addr := common.Address(stackData[stackLen-1].Bytes20()) - t.lookupAccount(addr) - if op == vm.SELFDESTRUCT { - t.deleted[caller] = true - } - case stackLen >= 5 && (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE): - addr := common.Address(stackData[stackLen-2].Bytes20()) - t.lookupAccount(addr) - case op == vm.CREATE: - nonce := t.env.StateDB.GetNonce(caller) - addr := crypto.CreateAddress(caller, nonce) - t.lookupAccount(addr) - t.created[addr] = true - case stackLen >= 4 && op == vm.CREATE2: - offset := stackData[stackLen-2] - size := stackData[stackLen-3] - init, err := tracers.GetMemoryCopyPadded(scope.Memory, int64(offset.Uint64()), int64(size.Uint64())) - if err != nil { - log.Warn("failed to copy CREATE2 input", "err", err, "tracer", "prestateTracer", "offset", offset, "size", size) - return - } - inithash := crypto.Keccak256(init) - salt := stackData[stackLen-4] - addr := crypto.CreateAddress2(caller, salt.Bytes32(), inithash) - t.lookupAccount(addr) - t.created[addr] = true - } -} - -func (t *prestateTracer) CaptureTxStart(gasLimit uint64) { - t.gasLimit = gasLimit -} - -func (t *prestateTracer) CaptureTxEnd(restGas uint64) { - if !t.config.DiffMode { - return - } - - for addr, state := range t.pre { - // The deleted account's state is pruned from `post` but kept in `pre` - if _, ok := t.deleted[addr]; ok { - continue - } - modified := false - postAccount := &account{Storage: make(map[common.Hash]common.Hash)} - newBalance := t.env.StateDB.GetBalance(addr).ToBig() - newNonce := t.env.StateDB.GetNonce(addr) - newCode := t.env.StateDB.GetCode(addr) - - if newBalance.Cmp(t.pre[addr].Balance) != 0 { - modified = true - postAccount.Balance = newBalance - } - if newNonce != t.pre[addr].Nonce { - modified = true - postAccount.Nonce = newNonce - } - if !bytes.Equal(newCode, t.pre[addr].Code) { - modified = true - postAccount.Code = newCode - } - - for key, val := range state.Storage { - // don't include the empty slot - if val == (common.Hash{}) { - delete(t.pre[addr].Storage, key) - } - - newVal := t.env.StateDB.GetState(addr, key) - if val == newVal { - // Omit unchanged slots - delete(t.pre[addr].Storage, key) - } else { - modified = true - if newVal != (common.Hash{}) { - postAccount.Storage[key] = newVal - } - } - } - - if modified { - t.post[addr] = postAccount - } else { - // if state is not modified, then no need to include into the pre state - delete(t.pre, addr) - } - } - // the new created contracts' prestate were empty, so delete them - for a := range t.created { - // the created contract maybe exists in statedb before the creating tx - if s := t.pre[a]; s != nil && !s.exists() { - delete(t.pre, a) - } - } -} - -// GetResult returns the json-encoded nested list of call traces, and any -// error arising from the encoding or forceful termination (via `Stop`). -func (t *prestateTracer) GetResult() (json.RawMessage, error) { - var res []byte - var err error - if t.config.DiffMode { - res, err = json.Marshal(struct { - Post state `json:"post"` - Pre state `json:"pre"` - }{t.post, t.pre}) - } else { - res, err = json.Marshal(t.pre) - } - if err != nil { - return nil, err - } - return json.RawMessage(res), t.reason -} - -// Stop terminates execution of the tracer at the first opportune moment. -func (t *prestateTracer) Stop(err error) { - t.reason = err - t.interrupt.Store(true) -} - -// lookupAccount fetches details of an account and adds it to the prestate -// if it doesn't exist there. -func (t *prestateTracer) lookupAccount(addr common.Address) { - if _, ok := t.pre[addr]; ok { - return - } - - t.pre[addr] = &account{ - Balance: t.env.StateDB.GetBalance(addr).ToBig(), - Nonce: t.env.StateDB.GetNonce(addr), - Code: t.env.StateDB.GetCode(addr), - Storage: make(map[common.Hash]common.Hash), - } -} - -// lookupStorage fetches the requested storage slot and adds -// it to the prestate of the given contract. It assumes `lookupAccount` -// has been performed on the contract before. -func (t *prestateTracer) lookupStorage(addr common.Address, key common.Hash) { - // lookupStorage assumes that lookupAccount has already been called. - // This assumption is violated for some historical blocks by the NativeAssetCall - // precompile. To fix this, we perform an extra call to lookupAccount here to ensure - // that the pre-state account is populated before attempting to read from the Storage - // map. When the invariant is maintained properly (since de-activation of the precompile), - // lookupAccount is a no-op. When the invariant is broken by the precompile, this avoids - // the panic and correctly captures the account prestate before the next opcode is executed. - t.lookupAccount(addr) - if _, ok := t.pre[addr].Storage[key]; ok { - return - } - t.pre[addr].Storage[key] = t.env.StateDB.GetState(addr, key) -} diff --git a/eth/tracers/tracers.go b/eth/tracers/tracers.go index 7a754fa824..2f0a0a8dab 100644 --- a/eth/tracers/tracers.go +++ b/eth/tracers/tracers.go @@ -18,106 +18,20 @@ package tracers import ( - "encoding/json" - "errors" - "fmt" - "math/big" - - "github.com/ava-labs/coreth/core/vm" - "github.com/ethereum/go-ethereum/common" + ethtracers "github.com/ava-labs/libevm/eth/tracers" ) // Context contains some contextual infos for a transaction execution that is not // available from within the EVM object. -type Context struct { - BlockHash common.Hash // Hash of the block the tx is contained within (zero if dangling tx or call) - BlockNumber *big.Int // Number of the block the tx is contained within (zero if dangling tx or call) - TxIndex int // Index of the transaction within a block (zero if dangling tx or call) - TxHash common.Hash // Hash of the transaction being traced (zero if dangling call) -} +type Context = ethtracers.Context // Tracer interface extends vm.EVMLogger and additionally // allows collecting the tracing result. -type Tracer interface { - vm.EVMLogger - GetResult() (json.RawMessage, error) - // Stop terminates execution of the tracer at the first opportune moment. - Stop(err error) -} - -type ctorFn func(*Context, json.RawMessage) (Tracer, error) -type jsCtorFn func(string, *Context, json.RawMessage) (Tracer, error) - -type elem struct { - ctor ctorFn - isJS bool -} +type Tracer = ethtracers.Tracer // DefaultDirectory is the collection of tracers bundled by default. -var DefaultDirectory = directory{elems: make(map[string]elem)} - -// directory provides functionality to lookup a tracer by name -// and a function to instantiate it. It falls back to a JS code evaluator -// if no tracer of the given name exists. -type directory struct { - elems map[string]elem - jsEval jsCtorFn -} - -// Register registers a method as a lookup for tracers, meaning that -// users can invoke a named tracer through that lookup. -func (d *directory) Register(name string, f ctorFn, isJS bool) { - d.elems[name] = elem{ctor: f, isJS: isJS} -} - -// RegisterJSEval registers a tracer that is able to parse -// dynamic user-provided JS code. -func (d *directory) RegisterJSEval(f jsCtorFn) { - d.jsEval = f -} - -// New returns a new instance of a tracer, by iterating through the -// registered lookups. Name is either name of an existing tracer -// or an arbitrary JS code. -func (d *directory) New(name string, ctx *Context, cfg json.RawMessage) (Tracer, error) { - if elem, ok := d.elems[name]; ok { - return elem.ctor(ctx, cfg) - } - // Assume JS code - return d.jsEval(name, ctx, cfg) -} - -// IsJS will return true if the given tracer will evaluate -// JS code. Because code evaluation has high overhead, this -// info will be used in determining fast and slow code paths. -func (d *directory) IsJS(name string) bool { - if elem, ok := d.elems[name]; ok { - return elem.isJS - } - // JS eval will execute JS code - return true -} - -const ( - memoryPadLimit = 1024 * 1024 -) +var DefaultDirectory = ethtracers.DefaultDirectory // GetMemoryCopyPadded returns offset + size as a new slice. // It zero-pads the slice if it extends beyond memory bounds. -func GetMemoryCopyPadded(m *vm.Memory, offset, size int64) ([]byte, error) { - if offset < 0 || size < 0 { - return nil, errors.New("offset or size must not be negative") - } - if int(offset+size) < m.Len() { // slice fully inside memory - return m.GetCopy(offset, size), nil - } - paddingNeeded := int(offset+size) - m.Len() - if paddingNeeded > memoryPadLimit { - return nil, fmt.Errorf("reached limit for padding memory slice: %d", paddingNeeded) - } - cpy := make([]byte, size) - if overlap := int64(m.Len()) - offset; overlap > 0 { - copy(cpy, m.GetPtr(offset, overlap)) - } - return cpy, nil -} +var GetMemoryCopyPadded = ethtracers.GetMemoryCopyPadded diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index e5a2c92047..f463d4bdee 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -31,14 +31,14 @@ import ( "testing" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" - "github.com/ava-labs/coreth/eth/tracers/logger" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/tests" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/eth/tracers/logger" ) func BenchmarkTransactionTrace(b *testing.B) { @@ -79,12 +79,12 @@ func BenchmarkTransactionTrace(b *testing.B) { byte(vm.PUSH1), 0, // jumpdestination byte(vm.JUMP), } - alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = types.GenesisAccount{ + alloc[common.HexToAddress("0x00000000000000000000000000000000deadbeef")] = types.Account{ Nonce: 1, Code: loop, Balance: big.NewInt(1), } - alloc[from] = types.GenesisAccount{ + alloc[from] = types.Account{ Nonce: 1, Code: []byte{}, Balance: big.NewInt(500000000000000), diff --git a/ethclient/corethclient/corethclient.go b/ethclient/corethclient/corethclient.go index 448b10b6af..2c72456049 100644 --- a/ethclient/corethclient/corethclient.go +++ b/ethclient/corethclient/corethclient.go @@ -33,12 +33,12 @@ import ( "runtime" "runtime/debug" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/ethclient" - "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" ) // Client is a wrapper around rpc.Client that implements geth-specific functionality. @@ -55,7 +55,7 @@ func New(c *rpc.Client) *Client { // CreateAccessList tries to create an access list for a specific transaction based on the // current pending state of the blockchain. -func (ec *Client) CreateAccessList(ctx context.Context, msg interfaces.CallMsg) (*types.AccessList, uint64, string, error) { +func (ec *Client) CreateAccessList(ctx context.Context, msg ethereum.CallMsg) (*types.AccessList, uint64, string, error) { type accessListResult struct { Accesslist *types.AccessList `json:"accessList"` Error string `json:"error,omitempty"` @@ -152,7 +152,7 @@ type OverrideAccount struct { // overrides specifies a map of contract states that should be overwritten before executing // the message call. // Please use ethclient.CallContract instead if you don't need the override functionality. -func (ec *Client) CallContract(ctx context.Context, msg interfaces.CallMsg, blockNumber *big.Int, overrides *map[common.Address]OverrideAccount) ([]byte, error) { +func (ec *Client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int, overrides *map[common.Address]OverrideAccount) ([]byte, error) { var hex hexutil.Bytes err := ec.c.CallContext( ctx, &hex, "eth_call", toCallArg(msg), @@ -180,7 +180,7 @@ func (ec *Client) SubscribePendingTransactions(ctx context.Context, ch chan<- co return ec.c.EthSubscribe(ctx, ch, "newPendingTransactions") } -func toCallArg(msg interfaces.CallMsg) interface{} { +func toCallArg(msg ethereum.CallMsg) interface{} { arg := map[string]interface{}{ "from": msg.From, "to": msg.To, diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 422cf37fcb..3470ea4d1d 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -35,11 +35,13 @@ import ( "math/big" "github.com/ava-labs/coreth/accounts/abi/bind" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/interfaces" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" // Force-load precompiles to trigger registration _ "github.com/ava-labs/coreth/precompile/registry" @@ -53,14 +55,14 @@ var ( _ bind.ContractTransactor = (*client)(nil) _ bind.DeployBackend = (*client)(nil) - _ interfaces.ChainReader = (*client)(nil) - _ interfaces.ChainStateReader = (*client)(nil) - _ interfaces.TransactionReader = (*client)(nil) - _ interfaces.TransactionSender = (*client)(nil) - _ interfaces.ContractCaller = (*client)(nil) - _ interfaces.GasEstimator = (*client)(nil) - _ interfaces.GasPricer = (*client)(nil) - _ interfaces.LogFilterer = (*client)(nil) + _ ethereum.ChainReader = (*client)(nil) + _ ethereum.ChainStateReader = (*client)(nil) + _ ethereum.TransactionReader = (*client)(nil) + _ ethereum.TransactionSender = (*client)(nil) + _ ethereum.ContractCaller = (*client)(nil) + _ ethereum.GasEstimator = (*client)(nil) + _ ethereum.GasPricer = (*client)(nil) + _ ethereum.LogFilterer = (*client)(nil) _ interfaces.AcceptedStateReader = (*client)(nil) _ interfaces.AcceptedContractCaller = (*client)(nil) @@ -84,9 +86,9 @@ type Client interface { TransactionInBlock(context.Context, common.Hash, uint) (*types.Transaction, error) TransactionReceipt(context.Context, common.Hash) (*types.Receipt, error) SyncProgress(ctx context.Context) error - SubscribeNewAcceptedTransactions(context.Context, chan<- *common.Hash) (interfaces.Subscription, error) - SubscribeNewPendingTransactions(context.Context, chan<- *common.Hash) (interfaces.Subscription, error) - SubscribeNewHead(context.Context, chan<- *types.Header) (interfaces.Subscription, error) + SubscribeNewAcceptedTransactions(context.Context, chan<- *common.Hash) (ethereum.Subscription, error) + SubscribeNewPendingTransactions(context.Context, chan<- *common.Hash) (ethereum.Subscription, error) + SubscribeNewHead(context.Context, chan<- *types.Header) (ethereum.Subscription, error) NetworkID(context.Context) (*big.Int, error) BalanceAt(context.Context, common.Address, *big.Int) (*big.Int, error) BalanceAtHash(ctx context.Context, account common.Address, blockHash common.Hash) (*big.Int, error) @@ -96,17 +98,17 @@ type Client interface { CodeAtHash(ctx context.Context, account common.Address, blockHash common.Hash) ([]byte, error) NonceAt(context.Context, common.Address, *big.Int) (uint64, error) NonceAtHash(ctx context.Context, account common.Address, blockHash common.Hash) (uint64, error) - FilterLogs(context.Context, interfaces.FilterQuery) ([]types.Log, error) - SubscribeFilterLogs(context.Context, interfaces.FilterQuery, chan<- types.Log) (interfaces.Subscription, error) + FilterLogs(context.Context, ethereum.FilterQuery) ([]types.Log, error) + SubscribeFilterLogs(context.Context, ethereum.FilterQuery, chan<- types.Log) (ethereum.Subscription, error) AcceptedCodeAt(context.Context, common.Address) ([]byte, error) AcceptedNonceAt(context.Context, common.Address) (uint64, error) - AcceptedCallContract(context.Context, interfaces.CallMsg) ([]byte, error) - CallContract(context.Context, interfaces.CallMsg, *big.Int) ([]byte, error) - CallContractAtHash(ctx context.Context, msg interfaces.CallMsg, blockHash common.Hash) ([]byte, error) + AcceptedCallContract(context.Context, ethereum.CallMsg) ([]byte, error) + CallContract(context.Context, ethereum.CallMsg, *big.Int) ([]byte, error) + CallContractAtHash(ctx context.Context, msg ethereum.CallMsg, blockHash common.Hash) ([]byte, error) SuggestGasPrice(context.Context) (*big.Int, error) SuggestGasTipCap(context.Context) (*big.Int, error) - FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*interfaces.FeeHistory, error) - EstimateGas(context.Context, interfaces.CallMsg) (uint64, error) + FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*ethereum.FeeHistory, error) + EstimateGas(context.Context, ethereum.CallMsg) (uint64, error) EstimateBaseFee(context.Context) (*big.Int, error) SendTransaction(context.Context, *types.Transaction) error } @@ -186,7 +188,7 @@ func (ec *client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumb var r []*types.Receipt err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", blockNrOrHash.String()) if err == nil && r == nil { - return nil, interfaces.NotFound + return nil, ethereum.NotFound } return r, err } @@ -213,7 +215,7 @@ func (ec *client) getBlock(ctx context.Context, method string, args ...interface } // When the block is not found, the API returns JSON null. if head == nil { - return nil, interfaces.NotFound + return nil, ethereum.NotFound } var body rpcBlock @@ -265,7 +267,18 @@ func (ec *client) getBlock(ctx context.Context, method string, args ...interface } txs[i] = tx.tx } - return types.NewBlockWithHeader(head).WithBody(txs, uncles).WithExtData(body.Version, (*[]byte)(body.BlockExtraData)), nil + + block := types.NewBlockWithHeader(head).WithBody( + types.Body{ + Transactions: txs, + Uncles: uncles, + }) + extra := &customtypes.BlockBodyExtra{ + Version: body.Version, + ExtData: (*[]byte)(body.BlockExtraData), + } + customtypes.SetBlockExtra(block, extra) + return block, nil } // HeaderByHash returns the block header with the given hash. @@ -273,7 +286,7 @@ func (ec *client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.He var head *types.Header err := ec.c.CallContext(ctx, &head, "eth_getBlockByHash", hash, false) if err == nil && head == nil { - err = interfaces.NotFound + err = ethereum.NotFound } return head, err } @@ -284,7 +297,7 @@ func (ec *client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.H var head *types.Header err := ec.c.CallContext(ctx, &head, "eth_getBlockByNumber", ToBlockNumArg(number), false) if err == nil && head == nil { - err = interfaces.NotFound + err = ethereum.NotFound } return head, err } @@ -314,7 +327,7 @@ func (ec *client) TransactionByHash(ctx context.Context, hash common.Hash) (tx * if err != nil { return nil, false, err } else if json == nil { - return nil, false, interfaces.NotFound + return nil, false, ethereum.NotFound } else if _, r, _ := json.tx.RawSignatureValues(); r == nil { return nil, false, errors.New("server returned transaction without signature") } @@ -366,7 +379,7 @@ func (ec *client) TransactionInBlock(ctx context.Context, blockHash common.Hash, return nil, err } if json == nil { - return nil, interfaces.NotFound + return nil, ethereum.NotFound } else if _, r, _ := json.tx.RawSignatureValues(); r == nil { return nil, errors.New("server returned transaction without signature") } @@ -382,7 +395,7 @@ func (ec *client) TransactionReceipt(ctx context.Context, txHash common.Hash) (* var r *types.Receipt err := ec.c.CallContext(ctx, &r, "eth_getTransactionReceipt", txHash) if err == nil && r == nil { - return nil, interfaces.NotFound + return nil, ethereum.NotFound } return r, err } @@ -406,7 +419,7 @@ func (ec *client) SyncProgress(ctx context.Context) error { } // SubscribeNewAcceptedTransactions subscribes to notifications about the accepted transaction hashes on the given channel. -func (ec *client) SubscribeNewAcceptedTransactions(ctx context.Context, ch chan<- *common.Hash) (interfaces.Subscription, error) { +func (ec *client) SubscribeNewAcceptedTransactions(ctx context.Context, ch chan<- *common.Hash) (ethereum.Subscription, error) { sub, err := ec.c.EthSubscribe(ctx, ch, "newAcceptedTransactions") if err != nil { // Defensively prefer returning nil interface explicitly on error-path, instead @@ -418,7 +431,7 @@ func (ec *client) SubscribeNewAcceptedTransactions(ctx context.Context, ch chan< } // SubscribeNewPendingTransactions subscribes to notifications about the pending transaction hashes on the given channel. -func (ec *client) SubscribeNewPendingTransactions(ctx context.Context, ch chan<- *common.Hash) (interfaces.Subscription, error) { +func (ec *client) SubscribeNewPendingTransactions(ctx context.Context, ch chan<- *common.Hash) (ethereum.Subscription, error) { sub, err := ec.c.EthSubscribe(ctx, ch, "newPendingTransactions") if err != nil { // Defensively prefer returning nil interface explicitly on error-path, instead @@ -431,7 +444,7 @@ func (ec *client) SubscribeNewPendingTransactions(ctx context.Context, ch chan<- // SubscribeNewHead subscribes to notifications about the current blockchain head // on the given channel. -func (ec *client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (interfaces.Subscription, error) { +func (ec *client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error) { sub, err := ec.c.EthSubscribe(ctx, ch, "newHeads") if err != nil { // Defensively prefer returning nil interface explicitly on error-path, instead @@ -520,7 +533,7 @@ func (ec *client) NonceAtHash(ctx context.Context, account common.Address, block // Filters // FilterLogs executes a filter query. -func (ec *client) FilterLogs(ctx context.Context, q interfaces.FilterQuery) ([]types.Log, error) { +func (ec *client) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error) { var result []types.Log arg, err := toFilterArg(q) if err != nil { @@ -531,7 +544,7 @@ func (ec *client) FilterLogs(ctx context.Context, q interfaces.FilterQuery) ([]t } // SubscribeFilterLogs subscribes to the results of a streaming filter query. -func (ec *client) SubscribeFilterLogs(ctx context.Context, q interfaces.FilterQuery, ch chan<- types.Log) (interfaces.Subscription, error) { +func (ec *client) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) { arg, err := toFilterArg(q) if err != nil { return nil, err @@ -546,7 +559,7 @@ func (ec *client) SubscribeFilterLogs(ctx context.Context, q interfaces.FilterQu return sub, nil } -func toFilterArg(q interfaces.FilterQuery) (interface{}, error) { +func toFilterArg(q ethereum.FilterQuery) (interface{}, error) { arg := map[string]interface{}{ "address": q.Addresses, "topics": q.Topics, @@ -580,7 +593,7 @@ func (ec *client) AcceptedNonceAt(ctx context.Context, account common.Address) ( // AcceptedCallContract executes a message call transaction in the accepted // state. -func (ec *client) AcceptedCallContract(ctx context.Context, msg interfaces.CallMsg) ([]byte, error) { +func (ec *client) AcceptedCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { return ec.CallContract(ctx, msg, nil) } @@ -592,7 +605,7 @@ func (ec *client) AcceptedCallContract(ctx context.Context, msg interfaces.CallM // blockNumber selects the block height at which the call runs. It can be nil, in which // case the code is taken from the latest known block. Note that state from very old // blocks might not be available. -func (ec *client) CallContract(ctx context.Context, msg interfaces.CallMsg, blockNumber *big.Int) ([]byte, error) { +func (ec *client) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { var hex hexutil.Bytes err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), ToBlockNumArg(blockNumber)) if err != nil { @@ -603,7 +616,7 @@ func (ec *client) CallContract(ctx context.Context, msg interfaces.CallMsg, bloc // CallContractAtHash is almost the same as CallContract except that it selects // the block by block hash instead of block height. -func (ec *client) CallContractAtHash(ctx context.Context, msg interfaces.CallMsg, blockHash common.Hash) ([]byte, error) { +func (ec *client) CallContractAtHash(ctx context.Context, msg ethereum.CallMsg, blockHash common.Hash) ([]byte, error) { var hex hexutil.Bytes err := ec.c.CallContext(ctx, &hex, "eth_call", toCallArg(msg), rpc.BlockNumberOrHashWithHash(blockHash, false)) if err != nil { @@ -640,7 +653,7 @@ type feeHistoryResultMarshaling struct { } // FeeHistory retrieves the fee market history. -func (ec *client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*interfaces.FeeHistory, error) { +func (ec *client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*ethereum.FeeHistory, error) { var res feeHistoryResultMarshaling if err := ec.c.CallContext(ctx, &res, "eth_feeHistory", hexutil.Uint(blockCount), ToBlockNumArg(lastBlock), rewardPercentiles); err != nil { return nil, err @@ -656,7 +669,7 @@ func (ec *client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock * for i, b := range res.BaseFee { baseFee[i] = (*big.Int)(b) } - return &interfaces.FeeHistory{ + return ðereum.FeeHistory{ OldestBlock: (*big.Int)(res.OldestBlock), Reward: reward, BaseFee: baseFee, @@ -668,7 +681,7 @@ func (ec *client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock * // the current pending state of the backend blockchain. There is no guarantee that this is // the true gas limit requirement as other transactions may be added or removed by miners, // but it should provide a basis for setting a reasonable default. -func (ec *client) EstimateGas(ctx context.Context, msg interfaces.CallMsg) (uint64, error) { +func (ec *client) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) { var hex hexutil.Uint64 err := ec.c.CallContext(ctx, &hex, "eth_estimateGas", toCallArg(msg)) if err != nil { @@ -716,7 +729,7 @@ func ToBlockNumArg(number *big.Int) string { return fmt.Sprintf("", number) } -func toCallArg(msg interfaces.CallMsg) interface{} { +func toCallArg(msg ethereum.CallMsg) interface{} { arg := map[string]interface{}{ "from": msg.From, "to": msg.To, diff --git a/ethclient/signer.go b/ethclient/signer.go index ba647de1a6..b570896a35 100644 --- a/ethclient/signer.go +++ b/ethclient/signer.go @@ -30,8 +30,8 @@ import ( "errors" "math/big" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // senderFromServer is a types.Signer that remembers the sender address returned by the RPC diff --git a/ethclient/simulated/backend.go b/ethclient/simulated/backend.go index c4a3cb8971..0802506b7f 100644 --- a/ethclient/simulated/backend.go +++ b/ethclient/simulated/backend.go @@ -25,8 +25,6 @@ import ( "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/constants" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth" "github.com/ava-labs/coreth/eth/ethconfig" "github.com/ava-labs/coreth/ethclient" @@ -34,7 +32,10 @@ import ( "github.com/ava-labs/coreth/node" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" ) var _ eth.PushGossiper = (*fakePushGossiper)(nil) @@ -45,20 +46,20 @@ func (*fakePushGossiper) Add(*types.Transaction) {} // Client exposes the methods provided by the Ethereum RPC client. type Client interface { - interfaces.BlockNumberReader - interfaces.ChainReader - interfaces.ChainStateReader - interfaces.ContractCaller - interfaces.GasEstimator - interfaces.GasPricer - interfaces.GasPricer1559 - interfaces.FeeHistoryReader - interfaces.LogFilterer + ethereum.BlockNumberReader + ethereum.ChainReader + ethereum.ChainStateReader + ethereum.ContractCaller + ethereum.GasEstimator + ethereum.GasPricer + ethereum.GasPricer1559 + ethereum.FeeHistoryReader + ethereum.LogFilterer interfaces.AcceptedStateReader interfaces.AcceptedContractCaller - interfaces.TransactionReader - interfaces.TransactionSender - interfaces.ChainIDReader + ethereum.TransactionReader + ethereum.TransactionSender + ethereum.ChainIDReader } // simClient wraps ethclient. This exists to prevent extracting ethclient.Client diff --git a/ethclient/simulated/backend_test.go b/ethclient/simulated/backend_test.go index 34a4855cfb..5afb2cb96c 100644 --- a/ethclient/simulated/backend_test.go +++ b/ethclient/simulated/backend_test.go @@ -25,11 +25,11 @@ import ( "time" "github.com/ava-labs/coreth/accounts/abi/bind" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" ) diff --git a/ethclient/simulated/options_test.go b/ethclient/simulated/options_test.go index cabf038eba..0b27fbbd48 100644 --- a/ethclient/simulated/options_test.go +++ b/ethclient/simulated/options_test.go @@ -23,10 +23,10 @@ import ( "testing" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/interfaces" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/core/types" ) // Tests that the simulator starts with the initial gas limit in the genesis block, @@ -64,7 +64,7 @@ func TestWithCallGasLimitOption(t *testing.T) { defer sim.Close() client := sim.Client() - _, err := client.CallContract(context.Background(), interfaces.CallMsg{ + _, err := client.CallContract(context.Background(), ethereum.CallMsg{ From: testAddr, To: &testAddr, Gas: 21000, diff --git a/go.mod b/go.mod index 3629a31d11..051b9d2a93 100644 --- a/go.mod +++ b/go.mod @@ -4,18 +4,12 @@ go 1.23.6 require ( github.com/VictoriaMetrics/fastcache v1.12.1 - github.com/ava-labs/avalanchego v1.13.1-0.20250321174807-6c72dfc4254a - github.com/ava-labs/libevm v0.0.0-20250320152422-7be6bee7ab32 - github.com/cespare/cp v0.1.0 - github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 + github.com/ava-labs/avalanchego v1.13.1-0.20250327151600-3a6bfac46f43 + github.com/ava-labs/libevm v1.13.14-0.2.0.rc.4 github.com/davecgh/go-spew v1.1.1 github.com/deckarep/golang-set/v2 v2.1.0 - github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 - github.com/ethereum/go-ethereum v1.13.14 - github.com/fsnotify/fsnotify v1.6.0 - github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 - github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 - github.com/google/uuid v1.6.0 + github.com/fjl/gencodec v0.1.1 + github.com/google/go-cmp v0.7.0 github.com/gorilla/rpc v1.2.0 github.com/gorilla/websocket v1.5.0 github.com/hashicorp/go-bexpr v0.1.10 @@ -23,33 +17,30 @@ require ( github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 github.com/holiman/bloomfilter/v2 v2.0.3 github.com/holiman/uint256 v1.2.4 - github.com/kylelemons/godebug v1.1.0 github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-isatty v0.0.17 - github.com/olekukonko/tablewriter v0.0.5 github.com/prometheus/client_golang v1.16.0 github.com/prometheus/client_model v0.3.0 github.com/spf13/cast v1.5.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.12.0 - github.com/status-im/keycard-go v0.2.0 github.com/stretchr/testify v1.10.0 github.com/tyler-smith/go-bip39 v1.1.0 github.com/urfave/cli/v2 v2.25.7 go.uber.org/goleak v1.3.0 go.uber.org/mock v0.5.0 - golang.org/x/crypto v0.35.0 + golang.org/x/crypto v0.32.0 golang.org/x/exp v0.0.0-20241215155358-4a5509556b9e - golang.org/x/sync v0.11.0 - golang.org/x/text v0.22.0 + golang.org/x/sync v0.10.0 golang.org/x/time v0.3.0 - golang.org/x/tools v0.28.0 + golang.org/x/tools v0.29.0 google.golang.org/protobuf v1.35.2 gopkg.in/natefinch/lumberjack.v2 v2.0.0 ) require ( github.com/DataDog/zstd v1.5.2 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/StephenButtolph/canoto v0.15.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect @@ -65,23 +56,33 @@ require ( github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect + github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect + github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect + github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.18.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect github.com/google/renameio/v2 v2.0.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/huin/goupnp v1.3.0 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/klauspost/compress v1.15.15 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -92,6 +93,7 @@ require ( github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -104,6 +106,7 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/status-im/keycard-go v0.2.0 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/supranational/blst v0.3.14 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect @@ -122,9 +125,10 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/net v0.36.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/term v0.29.0 // indirect + golang.org/x/net v0.34.0 // indirect + golang.org/x/sys v0.29.0 // indirect + golang.org/x/term v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect gonum.org/v1/gonum v0.11.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240604185151-ef581f913117 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect diff --git a/go.sum b/go.sum index d483e9f4f0..27987ede3e 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,8 @@ github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMd github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StephenButtolph/canoto v0.15.0 h1:3iGdyTSQZ7/y09WaJCe0O/HIi53ZyTrnmVzfCqt64mM= github.com/StephenButtolph/canoto v0.15.0/go.mod h1:IcnAHC6nJUfQFVR9y60ko2ecUqqHHSB6UwI9NnBFZnE= @@ -56,10 +58,10 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/ava-labs/avalanchego v1.13.1-0.20250321174807-6c72dfc4254a h1:JiXcmzcosrMp35ow+lQ9DQxrWvX9y+AGgGFhAGZcfgA= -github.com/ava-labs/avalanchego v1.13.1-0.20250321174807-6c72dfc4254a/go.mod h1:fpV/GmbfIB3P53gkq6zFpyeQtyAsJIuZCCKnm7TJ4sQ= -github.com/ava-labs/libevm v0.0.0-20250320152422-7be6bee7ab32 h1:l8Q4JyvTY+22e6lMLcd6WamMYFJc36MfJmeKflis7nQ= -github.com/ava-labs/libevm v0.0.0-20250320152422-7be6bee7ab32/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= +github.com/ava-labs/avalanchego v1.13.1-0.20250327151600-3a6bfac46f43 h1:N7C2AEHTSme0+MMa6n0TPDD11VbTqSNeT4eG2UKg610= +github.com/ava-labs/avalanchego v1.13.1-0.20250327151600-3a6bfac46f43/go.mod h1:jSJtHEp/1AGaruY53bQhDxbc/8UXh0n01yNTlggX3wk= +github.com/ava-labs/libevm v1.13.14-0.2.0.rc.4 h1:wnq3x3OE8DnBTBeKFjiywRO/MfnEXWjoSgnZtTQ1LS8= +github.com/ava-labs/libevm v1.13.14-0.2.0.rc.4/go.mod h1:+Iol+sVQ1KyoBsHf3veyrBmHCXr3xXRWq6ZXkgVfNLU= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -171,10 +173,10 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= -github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/fjl/gencodec v0.1.1 h1:DhQY29Q6JLXB/GgMqE86NbOEuvckiYcJCbXFu02toms= +github.com/fjl/gencodec v0.1.1/go.mod h1:chDHL3wKXuBgauP8x3XNZkl5EIAR5SoCTmmmDTZRzmw= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -182,6 +184,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 h1:IZqZOB2fydHte3kUgxrzK5E1fW7RQGeDwE8F/ZZnUYc= +github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -270,10 +274,12 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -326,6 +332,8 @@ github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iU github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -337,6 +345,8 @@ github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/ github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -603,8 +613,8 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= -golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= +golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -689,8 +699,8 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= -golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -712,8 +722,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -780,12 +790,12 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= +golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -796,8 +806,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -859,8 +869,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= -golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= +golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE= +golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/interfaces/interfaces.go b/interfaces/interfaces.go index 6e715808c1..39f8dcd371 100644 --- a/interfaces/interfaces.go +++ b/interfaces/interfaces.go @@ -1,202 +1,15 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. -// Package ethereum defines interfaces for interacting with Ethereum. package interfaces import ( "context" - "errors" - "math/big" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + ethereum "github.com/ava-labs/libevm" + "github.com/ava-labs/libevm/common" ) -// NotFound is returned by API methods if the requested item does not exist. -var NotFound = errors.New("not found") - -// Subscription represents an event subscription where events are -// delivered on a data channel. -type Subscription interface { - // Unsubscribe cancels the sending of events to the data channel - // and closes the error channel. - Unsubscribe() - // Err returns the subscription error channel. The error channel receives - // a value if there is an issue with the subscription (e.g. the network connection - // delivering the events has been closed). Only one value will ever be sent. - // The error channel is closed by Unsubscribe. - Err() <-chan error -} - -// ChainReader provides access to the blockchain. The methods in this interface access raw -// data from either the canonical chain (when requesting by block number) or any -// blockchain fork that was previously downloaded and processed by the node. The block -// number argument can be nil to select the latest canonical block. Reading block headers -// should be preferred over full blocks whenever possible. -// -// The returned error is NotFound if the requested item does not exist. -type ChainReader interface { - BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) - BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) - HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) - HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) - TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) - TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) - - // This method subscribes to notifications about changes of the head block of - // the canonical chain. - SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (Subscription, error) -} - -// TransactionReader provides access to past transactions and their receipts. -// Implementations may impose arbitrary restrictions on the transactions and receipts that -// can be retrieved. Historic transactions may not be available. -// -// Avoid relying on this interface if possible. Contract logs (through the LogFilterer -// interface) are more reliable and usually safer in the presence of chain -// reorganisations. -// -// The returned error is NotFound if the requested item does not exist. -type TransactionReader interface { - // TransactionByHash checks the pool of pending transactions in addition to the - // blockchain. The isPending return value indicates whether the transaction has been - // mined yet. Note that the transaction may not be part of the canonical chain even if - // it's not pending. - TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, isPending bool, err error) - // TransactionReceipt returns the receipt of a mined transaction. Note that the - // transaction may not be included in the current canonical chain even if a receipt - // exists. - TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) -} - -// ChainStateReader wraps access to the state trie of the canonical blockchain. Note that -// implementations of the interface may be unable to return state values for old blocks. -// In many cases, using CallContract can be preferable to reading raw contract storage. -type ChainStateReader interface { - BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) - StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) - CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) - NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) -} - -// CallMsg contains parameters for contract calls. -type CallMsg struct { - From common.Address // the sender of the 'transaction' - To *common.Address // the destination contract (nil for contract creation) - Gas uint64 // if 0, the call executes with near-infinite gas - GasPrice *big.Int // wei <-> gas exchange ratio - GasFeeCap *big.Int // EIP-1559 fee cap per gas. - GasTipCap *big.Int // EIP-1559 tip per gas. - Value *big.Int // amount of wei sent along with the call - Data []byte // input data, usually an ABI-encoded contract method invocation - - AccessList types.AccessList // EIP-2930 access list. - - // For BlobTxType - BlobGasFeeCap *big.Int - BlobHashes []common.Hash -} - -// A ContractCaller provides contract calls, essentially transactions that are executed by -// the EVM but not mined into the blockchain. ContractCall is a low-level method to -// execute such calls. For applications which are structured around specific contracts, -// the abigen tool provides a nicer, properly typed way to perform calls. -type ContractCaller interface { - CallContract(ctx context.Context, call CallMsg, blockNumber *big.Int) ([]byte, error) -} - -// FilterQuery contains options for contract log filtering. -type FilterQuery struct { - BlockHash *common.Hash // used by eth_getLogs, return logs only from block with this hash - FromBlock *big.Int // beginning of the queried range, nil means genesis block - ToBlock *big.Int // end of the range, nil means latest block - Addresses []common.Address // restricts matches to events created by specific contracts - - // The Topic list restricts matches to particular event topics. Each event has a list - // of topics. Topics matches a prefix of that list. An empty element slice matches any - // topic. Non-empty elements represent an alternative that matches any of the - // contained topics. - // - // Examples: - // {} or nil matches any topic list - // {{A}} matches topic A in first position - // {{}, {B}} matches any topic in first position AND B in second position - // {{A}, {B}} matches topic A in first position AND B in second position - // {{A, B}, {C, D}} matches topic (A OR B) in first position AND (C OR D) in second position - Topics [][]common.Hash -} - -// LogFilterer provides access to contract log events using a one-off query or continuous -// event subscription. -// -// Logs received through a streaming query subscription may have Removed set to true, -// indicating that the log was reverted due to a chain reorganisation. -type LogFilterer interface { - FilterLogs(ctx context.Context, q FilterQuery) ([]types.Log, error) - SubscribeFilterLogs(ctx context.Context, q FilterQuery, ch chan<- types.Log) (Subscription, error) -} - -// TransactionSender wraps transaction sending. The SendTransaction method injects a -// signed transaction into the pending transaction pool for execution. If the transaction -// was a contract creation, the TransactionReceipt method can be used to retrieve the -// contract address after the transaction has been mined. -// -// The transaction must be signed and have a valid nonce to be included. Consumers of the -// API can use package accounts to maintain local private keys and need can retrieve the -// next available nonce using AcceptedNonceAt. -type TransactionSender interface { - SendTransaction(ctx context.Context, tx *types.Transaction) error -} - -// GasPricer wraps the gas price oracle, which monitors the blockchain to determine the -// optimal gas price given current fee market conditions. -type GasPricer interface { - SuggestGasPrice(ctx context.Context) (*big.Int, error) -} - -// GasPricer1559 provides access to the EIP-1559 gas price oracle. -type GasPricer1559 interface { - SuggestGasTipCap(ctx context.Context) (*big.Int, error) -} - -// FeeHistoryReader provides access to the fee history oracle. -type FeeHistoryReader interface { - FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*FeeHistory, error) -} - -// FeeHistory provides recent fee market data that consumers can use to determine -// a reasonable maxPriorityFeePerGas value. -type FeeHistory struct { - OldestBlock *big.Int // block corresponding to first response value - Reward [][]*big.Int // list every txs priority fee per block - BaseFee []*big.Int // list of each block's base fee - GasUsedRatio []float64 // ratio of gas used out of the total available limit -} - // An AcceptedStateReceiver provides access to the accepted state ie. the state of the // most recently accepted block. type AcceptedStateReader interface { @@ -206,29 +19,5 @@ type AcceptedStateReader interface { // AcceptedContractCaller can be used to perform calls against the accepted state. type AcceptedContractCaller interface { - AcceptedCallContract(ctx context.Context, call CallMsg) ([]byte, error) -} - -// GasEstimator wraps EstimateGas, which tries to estimate the gas needed to execute a -// specific transaction based on the pending state. There is no guarantee that this is the -// true gas limit requirement as other transactions may be added or removed by miners, but -// it should provide a basis for setting a reasonable default. -type GasEstimator interface { - EstimateGas(ctx context.Context, call CallMsg) (uint64, error) -} - -// A PendingStateEventer provides access to real time notifications about changes to the -// pending state. -type PendingStateEventer interface { - SubscribePendingTransactions(ctx context.Context, ch chan<- *types.Transaction) (Subscription, error) -} - -// BlockNumberReader provides access to the current block number. -type BlockNumberReader interface { - BlockNumber(ctx context.Context) (uint64, error) -} - -// ChainIDReader provides access to the chain ID. -type ChainIDReader interface { - ChainID(ctx context.Context) (*big.Int, error) + AcceptedCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) } diff --git a/internal/blocktest/test_hash.go b/internal/blocktest/test_hash.go index 014e9ff4b0..4dae6f75f7 100644 --- a/internal/blocktest/test_hash.go +++ b/internal/blocktest/test_hash.go @@ -35,7 +35,7 @@ package blocktest import ( "hash" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "golang.org/x/crypto/sha3" ) diff --git a/internal/debug/api.go b/internal/debug/api.go index 6ac4f5110b..044a601f3c 100644 --- a/internal/debug/api.go +++ b/internal/debug/api.go @@ -45,7 +45,7 @@ import ( "sync" "time" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" "github.com/hashicorp/go-bexpr" "golang.org/x/exp/slog" ) diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 94cffe5a0e..bb148bf40e 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -37,7 +37,7 @@ import ( "runtime" "github.com/ava-labs/coreth/internal/flags" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" "github.com/mattn/go-colorable" "github.com/mattn/go-isatty" "github.com/urfave/cli/v2" diff --git a/internal/debug/trace.go b/internal/debug/trace.go index 12f7bfdb05..dd9a873595 100644 --- a/internal/debug/trace.go +++ b/internal/debug/trace.go @@ -31,7 +31,7 @@ import ( "os" "runtime/trace" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) // StartGoTrace turns on tracing, writing to the given file. diff --git a/internal/ethapi/addrlock.go b/internal/ethapi/addrlock.go index 2d00fdd2e7..2cd32605c1 100644 --- a/internal/ethapi/addrlock.go +++ b/internal/ethapi/addrlock.go @@ -29,7 +29,7 @@ package ethapi import ( "sync" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) type AddrLocker struct { diff --git a/internal/ethapi/api.coreth.go b/internal/ethapi/api.coreth.go index e97aa09abe..6948105214 100644 --- a/internal/ethapi/api.coreth.go +++ b/internal/ethapi/api.coreth.go @@ -8,10 +8,11 @@ import ( "fmt" "math/big" + "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/etna" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/common/math" ) const ( @@ -64,7 +65,7 @@ func (s *EthereumAPI) SuggestPriceOptions(ctx context.Context) (*PriceOptions, e // Find min base fee based on chain config // TODO: This can be removed after Fortuna is activated time := s.b.CurrentHeader().Time - chainConfig := s.b.ChainConfig() + chainConfig := params.GetExtra(s.b.ChainConfig()) minBaseFee := new(big.Int) if chainConfig.IsFortuna(time) { minBaseFee.SetUint64(acp176.MinGasPrice) diff --git a/internal/ethapi/api.coreth_test.go b/internal/ethapi/api.coreth_test.go index 376b0b38c1..8c919d04dc 100644 --- a/internal/ethapi/api.coreth_test.go +++ b/internal/ethapi/api.coreth_test.go @@ -8,12 +8,12 @@ import ( "math/big" "testing" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/etna" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" ) diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index f9101825ea..82a228f064 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -35,26 +35,27 @@ import ( "strings" "time" - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/accounts/keystore" - "github.com/ava-labs/coreth/accounts/scwallet" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/eth/gasestimator" - "github.com/ava-labs/coreth/eth/tracers/logger" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/rpc" - "github.com/ava-labs/coreth/trie" + "github.com/ava-labs/libevm/accounts" + "github.com/ava-labs/libevm/accounts/keystore" + "github.com/ava-labs/libevm/accounts/scwallet" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/eth/tracers/logger" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/uint256" "github.com/tyler-smith/go-bip39" ) @@ -1232,6 +1233,7 @@ func (s *BlockChainAPI) EstimateGas(ctx context.Context, args TransactionArgs, b // RPCMarshalHeader converts the given header to the RPC output . func RPCMarshalHeader(head *types.Header) map[string]interface{} { + headExtra := customtypes.GetHeaderExtra(head) result := map[string]interface{}{ "number": (*hexutil.Big)(head.Number), "hash": head.Hash(), @@ -1249,16 +1251,16 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { "timestamp": hexutil.Uint64(head.Time), "transactionsRoot": head.TxHash, "receiptsRoot": head.ReceiptHash, - "extDataHash": head.ExtDataHash, + "extDataHash": headExtra.ExtDataHash, } if head.BaseFee != nil { result["baseFeePerGas"] = (*hexutil.Big)(head.BaseFee) } - if head.ExtDataGasUsed != nil { - result["extDataGasUsed"] = (*hexutil.Big)(head.ExtDataGasUsed) + if headExtra.ExtDataGasUsed != nil { + result["extDataGasUsed"] = (*hexutil.Big)(headExtra.ExtDataGasUsed) } - if head.BlockGasCost != nil { - result["blockGasCost"] = (*hexutil.Big)(head.BlockGasCost) + if headExtra.BlockGasCost != nil { + result["blockGasCost"] = (*hexutil.Big)(headExtra.BlockGasCost) } if head.BlobGasUsed != nil { result["blobGasUsed"] = hexutil.Uint64(*head.BlobGasUsed) @@ -1278,7 +1280,7 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} { func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool, config *params.ChainConfig) map[string]interface{} { fields := RPCMarshalHeader(block.Header()) fields["size"] = hexutil.Uint64(block.Size()) - fields["blockExtraData"] = hexutil.Bytes(block.ExtData()) + fields["blockExtraData"] = hexutil.Bytes(customtypes.BlockExtData(block)) if inclTx { formatTx := func(idx int, tx *types.Transaction) interface{} { @@ -1523,7 +1525,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH to = crypto.CreateAddress(args.from(), uint64(*args.Nonce)) } // Retrieve the precompiles since they don't need to be added to the access list - precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number, header.Time)) + precompiles := vm.ActivePrecompiles(b.ChainConfig().Rules(header.Number, params.IsMergeTODO, header.Time)) // Create an initial tracer prevTracer := logger.NewAccessListTracer(nil, args.from(), to, precompiles) diff --git a/internal/ethapi/api_extra.go b/internal/ethapi/api_extra.go index 44a6fa37cb..5a71fc0789 100644 --- a/internal/ethapi/api_extra.go +++ b/internal/ethapi/api_extra.go @@ -11,9 +11,9 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/rlp" ) // GetChainConfig returns the chain config. diff --git a/internal/ethapi/api_extra_test.go b/internal/ethapi/api_extra_test.go index 5d72617662..2d0b07d601 100644 --- a/internal/ethapi/api_extra_test.go +++ b/internal/ethapi/api_extra_test.go @@ -8,9 +8,9 @@ import ( "math/big" "testing" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" ) diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index ef916ae277..3155805247 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -41,27 +41,27 @@ import ( "testing" "time" - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/accounts/keystore" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/bloombits" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/internal/blocktest" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/rpc" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/accounts" + "github.com/ava-labs/libevm/accounts/keystore" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/crypto/kzg4844" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" "github.com/holiman/uint256" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" @@ -452,7 +452,7 @@ func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.E } ) accman, acc := newTestAccountManager(t) - gspec.Alloc[acc.Address] = types.GenesisAccount{Balance: big.NewInt(params.Ether)} + gspec.Alloc[acc.Address] = types.Account{Balance: big.NewInt(params.Ether)} // Generate blocks for testing db, blocks, _, _ := core.GenerateChainWithGenesis(gspec, engine, n, 10, generator) chain, err := core.NewBlockChain(db, cacheConfig, gspec, engine, vm.Config{}, gspec.ToBlock().Hash(), false) diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index e598a1d5dc..f94c0955a6 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -32,18 +32,18 @@ import ( "math/big" "time" - "github.com/ava-labs/coreth/accounts" "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/bloombits" "github.com/ava-labs/coreth/core/state" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/accounts" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/event" ) // Backend interface provides the common API services (that are provided by diff --git a/internal/ethapi/errors.go b/internal/ethapi/errors.go index 928dded8b7..3597bec085 100644 --- a/internal/ethapi/errors.go +++ b/internal/ethapi/errors.go @@ -30,8 +30,8 @@ import ( "fmt" "github.com/ava-labs/coreth/accounts/abi" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/vm" ) // revertError is an API error that encompasses an EVM revert with JSON error @@ -54,11 +54,11 @@ func (e *revertError) ErrorData() interface{} { // newRevertError creates a revertError instance with the provided revert data. func newRevertError(revert []byte) *revertError { - err := vmerrs.ErrExecutionReverted + err := vm.ErrExecutionReverted reason, errUnpack := abi.UnpackRevert(revert) if errUnpack == nil { - err = fmt.Errorf("%w: %v", vmerrs.ErrExecutionReverted, reason) + err = fmt.Errorf("%w: %v", vm.ErrExecutionReverted, reason) } return &revertError{ error: err, diff --git a/internal/ethapi/mocks_test.go b/internal/ethapi/mocks_test.go index 2abb9f46ba..06466f05d6 100644 --- a/internal/ethapi/mocks_test.go +++ b/internal/ethapi/mocks_test.go @@ -15,18 +15,18 @@ import ( reflect "reflect" time "time" - accounts "github.com/ava-labs/coreth/accounts" consensus "github.com/ava-labs/coreth/consensus" core "github.com/ava-labs/coreth/core" bloombits "github.com/ava-labs/coreth/core/bloombits" state "github.com/ava-labs/coreth/core/state" - types "github.com/ava-labs/coreth/core/types" - vm "github.com/ava-labs/coreth/core/vm" params "github.com/ava-labs/coreth/params" rpc "github.com/ava-labs/coreth/rpc" - common "github.com/ethereum/go-ethereum/common" - ethdb "github.com/ethereum/go-ethereum/ethdb" - event "github.com/ethereum/go-ethereum/event" + accounts "github.com/ava-labs/libevm/accounts" + common "github.com/ava-labs/libevm/common" + types "github.com/ava-labs/libevm/core/types" + vm "github.com/ava-labs/libevm/core/vm" + ethdb "github.com/ava-labs/libevm/ethdb" + event "github.com/ava-labs/libevm/event" gomock "go.uber.org/mock/gomock" ) diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index f253a41bdf..30e7d25234 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -36,14 +36,14 @@ import ( "github.com/ava-labs/coreth/consensus/misc/eip4844" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto/kzg4844" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto/kzg4844" + "github.com/ava-labs/libevm/log" "github.com/holiman/uint256" ) @@ -229,7 +229,7 @@ func (args *TransactionArgs) setFeeDefaults(ctx context.Context, b feeBackend) e } // Sanity check the non-EIP-1559 fee parameters. - isLondon := b.ChainConfig().IsApricotPhase3(head.Time) + isLondon := b.ChainConfig().IsLondon(head.Number) if args.GasPrice != nil && !eip1559ParamsSet { // Zero gas-price is not allowed after London fork if args.GasPrice.ToInt().Sign() == 0 && isLondon { diff --git a/internal/ethapi/transaction_args_test.go b/internal/ethapi/transaction_args_test.go index 7f2b0661fd..db754d1f87 100644 --- a/internal/ethapi/transaction_args_test.go +++ b/internal/ethapi/transaction_args_test.go @@ -33,11 +33,10 @@ import ( "reflect" "testing" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" ) var _ feeBackend = &backendMock{} @@ -276,10 +275,8 @@ func newBackendMock() *backendMock { PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(0), MuirGlacierBlock: big.NewInt(0), + LondonBlock: big.NewInt(1100), CancunTime: &cancunTime, - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase3BlockTimestamp: utils.NewUint64(100), - }, } return &backendMock{ current: &types.Header{ @@ -297,9 +294,11 @@ func newBackendMock() *backendMock { func (b *backendMock) setFork(fork string) error { if fork == "legacy" { - b.current.Time = uint64(90) // Before ApricotPhase3BlockTimestamp + b.current.Number = big.NewInt(900) + b.current.Time = 555 } else if fork == "london" { - b.current.Time = uint64(110) // After ApricotPhase3BlockTimestamp + b.current.Number = big.NewInt(1100) + b.current.Time = 555 } else if fork == "cancun" { b.current.Number = big.NewInt(1100) b.current.Time = 700 diff --git a/internal/shutdowncheck/shutdown_tracker.go b/internal/shutdowncheck/shutdown_tracker.go index 35382305c4..29e2ac9017 100644 --- a/internal/shutdowncheck/shutdown_tracker.go +++ b/internal/shutdowncheck/shutdown_tracker.go @@ -29,10 +29,10 @@ package shutdowncheck import ( "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" ) // ShutdownTracker is a service that reports previous unclean shutdowns diff --git a/libevm/options/options.go b/libevm/options/options.go deleted file mode 100644 index af7bc751a9..0000000000 --- a/libevm/options/options.go +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2024 the libevm authors. -// -// The libevm additions to go-ethereum are free software: you can redistribute -// them and/or modify them under the terms of the GNU Lesser General Public License -// as published by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// The libevm additions are distributed in the hope that they will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -// General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see -// . - -// Package options provides a generic mechanism for defining configuration of -// arbitrary types. -package options - -// An Option configures values of arbitrary type. -type Option[T any] interface { - Configure(*T) -} - -// As applies Options to a zero-value T, which it then returns. -func As[T any](opts ...Option[T]) *T { - var t T - for _, o := range opts { - o.Configure(&t) - } - return &t -} - -// A Func converts a function into an [Option], using itself as the Configure -// method. -type Func[T any] func(*T) - -var _ Option[struct{}] = Func[struct{}](nil) - -// Configure implements the [Option] interface. -func (f Func[T]) Configure(t *T) { f(t) } diff --git a/libevm/sync/sync.go b/libevm/sync/sync.go deleted file mode 100644 index e280f4bbe9..0000000000 --- a/libevm/sync/sync.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2024 the coreth authors. -// -// The libevm additions to go-ethereum are free software: you can redistribute -// them and/or modify them under the terms of the GNU Lesser General Public License -// as published by the Free Software Foundation, either version 3 of the License, -// or (at your option) any later version. -// -// The libevm additions are distributed in the hope that they will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser -// General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see -// . - -// Package sync extends the standard library's sync package. -package sync - -import "sync" - -// Aliases of stdlib sync's types to avoid having to import it alongside this -// package. -type ( - Cond = sync.Cond - Locker = sync.Locker - Map = sync.Map - Mutex = sync.Mutex - Once = sync.Once - RWMutex = sync.RWMutex - WaitGroup = sync.WaitGroup -) - -// A Pool is a type-safe wrapper around [sync.Pool]. -type Pool[T any] struct { - New func() T - pool sync.Pool - once Once -} - -// Get is equivalent to [sync.Pool.Get]. -func (p *Pool[T]) Get() T { - p.once.Do(func() { // Do() guarantees at least once, not just only once - p.pool.New = func() any { return p.New() } - }) - return p.pool.Get().(T) //nolint:forcetypeassert -} - -// Put is equivalent to [sync.Pool.Put]. -func (p *Pool[T]) Put(t T) { - p.pool.Put(t) -} diff --git a/metrics/prometheus/prometheus.go b/metrics/prometheus/prometheus.go index cd478e9249..9db1495af8 100644 --- a/metrics/prometheus/prometheus.go +++ b/metrics/prometheus/prometheus.go @@ -57,7 +57,8 @@ func (g *Gatherer) Gather() (mfs []*dto.MetricFamily, err error) { } var ( - errMetricSkip = errors.New("metric skipped") + errMetricSkip = errors.New("metric skipped") + errMetricTypeNotSupported = errors.New("metric type is not supported") ) func ptrTo[T any](x T) *T { return &x } @@ -67,6 +68,12 @@ func metricFamily(registry Registry, name string) (mf *dto.MetricFamily, err err name = strings.ReplaceAll(name, "/", "_") switch m := metric.(type) { + case metrics.NilCounter, metrics.NilCounterFloat64, metrics.NilEWMA, + metrics.NilGauge, metrics.NilGaugeFloat64, metrics.NilGaugeInfo, + metrics.NilHealthcheck, metrics.NilHistogram, metrics.NilMeter, + metrics.NilResettingTimer, metrics.NilSample, metrics.NilTimer: + return nil, fmt.Errorf("%w: %q metric is nil", errMetricSkip, name) + case metrics.Counter: return &dto.MetricFamily{ Name: &name, @@ -191,7 +198,10 @@ func metricFamily(registry Registry, name string) (mf *dto.MetricFamily, err err }, }}, }, nil + case metrics.GaugeInfo: + // TODO(qdm12) handle this somehow maybe with dto.MetricType_UNTYPED + return nil, fmt.Errorf("%w: %q is a %T", errMetricSkip, name, metric) default: - return nil, fmt.Errorf("metric %q: type is not supported: %T", name, metric) + return nil, fmt.Errorf("%w: metric %q type %T", errMetricTypeNotSupported, name, metric) } } diff --git a/metrics/prometheus/prometheus_test.go b/metrics/prometheus/prometheus_test.go index 4263abed7d..71d506efa5 100644 --- a/metrics/prometheus/prometheus_test.go +++ b/metrics/prometheus/prometheus_test.go @@ -90,8 +90,8 @@ func TestGatherer_Gather(t *testing.T) { } assert.Equal(t, want, familyStrings) - register(t, "unsupported", metrics.NewGaugeInfo()) + register(t, "unsupported", metrics.NewHealthcheck(nil)) families, err = gatherer.Gather() - assert.EqualError(t, err, "metric \"unsupported\": type is not supported: *metrics.StandardGaugeInfo") + assert.ErrorIs(t, err, errMetricTypeNotSupported) assert.Empty(t, families) } diff --git a/miner/miner.go b/miner/miner.go index 512b99c1bb..487ea3bcf9 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -32,11 +32,11 @@ import ( "github.com/ava-labs/coreth/consensus" "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/precompile/precompileconfig" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/event" ) // Backend wraps all methods required for mining. diff --git a/miner/ordering.go b/miner/ordering.go index 07fa390e4b..364d3ee8c3 100644 --- a/miner/ordering.go +++ b/miner/ordering.go @@ -31,8 +31,8 @@ import ( "math/big" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" "github.com/holiman/uint256" ) diff --git a/miner/ordering_test.go b/miner/ordering_test.go index 27d6b96761..17af88d709 100644 --- a/miner/ordering_test.go +++ b/miner/ordering_test.go @@ -34,9 +34,9 @@ import ( "time" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" "github.com/holiman/uint256" ) diff --git a/miner/worker.go b/miner/worker.go index d311b684f1..ab36654927 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -43,15 +43,15 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/predicate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/event" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/event" + "github.com/ava-labs/libevm/log" "github.com/holiman/uint256" ) @@ -146,11 +146,12 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte timestamp = parent.Time } - gasLimit, err := customheader.GasLimit(w.chainConfig, parent, timestamp) + chainExtra := params.GetExtra(w.chainConfig) + gasLimit, err := customheader.GasLimit(chainExtra, parent, timestamp) if err != nil { return nil, fmt.Errorf("calculating new gas limit: %w", err) } - baseFee, err := customheader.BaseFee(w.chainConfig, parent, timestamp) + baseFee, err := customheader.BaseFee(chainExtra, parent, timestamp) if err != nil { return nil, fmt.Errorf("failed to calculate new base fee: %w", err) } @@ -202,7 +203,8 @@ func (w *worker) commitNewWork(predicateContext *precompileconfig.PredicateConte env.state.StopPrefetcher() }() // Configure any upgrades that should go into effect during this block. - err = core.ApplyUpgrades(w.chainConfig, &parent.Time, types.NewBlockWithHeader(header), env.state) + blockContext := core.NewBlockContext(header.Number, header.Time) + err = core.ApplyUpgrades(w.chainConfig, &parent.Time, blockContext, env.state) if err != nil { log.Error("failed to configure precompiles mining new block", "parent", parent.Hash(), "number", header.Number, "timestamp", header.Time, "err", err) return nil, err @@ -259,7 +261,9 @@ func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.Pre if err != nil { return nil, err } - capacity, err := customheader.GasCapacity(w.chainConfig, parent, header.Time) + + chainConfigExtra := params.GetExtra(w.chainConfig) + capacity, err := customheader.GasCapacity(chainConfigExtra, parent, header.Time) if err != nil { return nil, fmt.Errorf("calculating gas capacity: %w", err) } @@ -272,7 +276,7 @@ func (w *worker) createCurrentEnvironment(predicateContext *precompileconfig.Pre header: header, tcount: 0, gasPool: new(core.GasPool).AddGas(capacity), - rules: w.chainConfig.Rules(header.Number, header.Time), + rules: w.chainConfig.Rules(header.Number, params.IsMergeTODO, header.Time), predicateContext: predicateContext, predicateResults: predicate.NewResults(), start: tstart, @@ -325,7 +329,8 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction, coinb blockContext vm.BlockContext ) - if env.rules.IsDurango { + rulesExtra := params.GetRulesExtra(env.rules) + if rulesExtra.IsDurango { results, err := core.CheckPredicates(env.rules, env.predicateContext, tx) if err != nil { log.Debug("Transaction predicate failed verification in miner", "tx", tx.Hash(), "err", err) @@ -333,7 +338,11 @@ func (w *worker) applyTransaction(env *environment, tx *types.Transaction, coinb } env.predicateResults.SetTxResults(tx.Hash(), results) - blockContext = core.NewEVMBlockContextWithPredicateResults(env.header, w.chain, &coinbase, env.predicateResults) + predicateResultsBytes, err := env.predicateResults.Bytes() + if err != nil { + return nil, fmt.Errorf("failed to marshal predicate results: %w", err) + } + blockContext = core.NewEVMBlockContextWithPredicateResults(rulesExtra.AvalancheRules, env.header, w.chain, &coinbase, predicateResultsBytes) } else { blockContext = core.NewEVMBlockContext(env.header, w.chain, &coinbase) } @@ -455,7 +464,7 @@ func (w *worker) commitTransactions(env *environment, plainTxs, blobTxs *transac // commit runs any post-transaction state modifications, assembles the final block // and commits new work if consensus engine is running. func (w *worker) commit(env *environment) (*types.Block, error) { - if env.rules.IsDurango { + if params.GetRulesExtra(env.rules).IsDurango { predicateResultsBytes, err := env.predicateResults.Bytes() if err != nil { return nil, fmt.Errorf("failed to marshal predicate results: %w", err) diff --git a/core/vm/contracts_stateful_native_asset.go b/nativeasset/contract.go similarity index 51% rename from core/vm/contracts_stateful_native_asset.go rename to nativeasset/contract.go index 6791efe2e7..991c3dec44 100644 --- a/core/vm/contracts_stateful_native_asset.go +++ b/nativeasset/contract.go @@ -1,15 +1,16 @@ // (c) 2019-2020, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package vm +package nativeasset import ( "fmt" "math/big" "github.com/ava-labs/coreth/precompile/contract" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/log" "github.com/holiman/uint256" ) @@ -20,14 +21,14 @@ import ( // BLS12-381 Curve Operations added to the set of precompiled contracts var ( - genesisContractAddr = common.HexToAddress("0x0100000000000000000000000000000000000000") + GenesisContractAddr = common.HexToAddress("0x0100000000000000000000000000000000000000") NativeAssetBalanceAddr = common.HexToAddress("0x0100000000000000000000000000000000000001") NativeAssetCallAddr = common.HexToAddress("0x0100000000000000000000000000000000000002") ) -// nativeAssetBalance is a precompiled contract used to retrieve the native asset balance -type nativeAssetBalance struct { - gasCost uint64 +// NativeAssetBalance is a precompiled contract used to retrieve the native asset balance +type NativeAssetBalance struct { + GasCost uint64 } // PackNativeAssetBalanceInput packs the arguments into the required input data for a transaction to be passed into @@ -51,29 +52,30 @@ func UnpackNativeAssetBalanceInput(input []byte) (common.Address, common.Hash, e } // Run implements StatefulPrecompiledContract -func (b *nativeAssetBalance) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { +func (b *NativeAssetBalance) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { // input: encodePacked(address 20 bytes, assetID 32 bytes) - if suppliedGas < b.gasCost { - return nil, 0, vmerrs.ErrOutOfGas + if suppliedGas < b.GasCost { + return nil, 0, vm.ErrOutOfGas } - remainingGas = suppliedGas - b.gasCost + remainingGas = suppliedGas - b.GasCost address, assetID, err := UnpackNativeAssetBalanceInput(input) if err != nil { - return nil, remainingGas, vmerrs.ErrExecutionReverted + return nil, remainingGas, vm.ErrExecutionReverted } res, overflow := uint256.FromBig(accessibleState.GetStateDB().GetBalanceMultiCoin(address, assetID)) if overflow { - return nil, remainingGas, vmerrs.ErrExecutionReverted + return nil, remainingGas, vm.ErrExecutionReverted } return common.LeftPadBytes(res.Bytes(), 32), remainingGas, nil } -// nativeAssetCall atomically transfers a native asset to a recipient address as well as calling that +// NativeAssetCall atomically transfers a native asset to a recipient address as well as calling that // address -type nativeAssetCall struct { - gasCost uint64 +type NativeAssetCall struct { + GasCost uint64 + CallNewAccountGas uint64 } // PackNativeAssetCallInput packs the arguments into the required input data for a transaction to be passed into @@ -100,14 +102,69 @@ func UnpackNativeAssetCallInput(input []byte) (common.Address, common.Hash, *big return to, assetID, assetAmount, callData, nil } -// Run implements StatefulPrecompiledContract -func (c *nativeAssetCall) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { - // input: encodePacked(address 20 bytes, assetID 32 bytes, assetAmount 32 bytes, callData variable length bytes) - return accessibleState.NativeAssetCall(caller, input, suppliedGas, c.gasCost, readOnly) +// Run implements [contract.StatefulPrecompiledContract] +func (c *NativeAssetCall) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { + env := accessibleState.GetPrecompileEnv() + if !env.UseGas(c.GasCost) { + return nil, 0, vm.ErrOutOfGas + } + ret, err = c.run(env, accessibleState.GetStateDB(), caller, addr, input, readOnly) + // This precompile will be wrapped in a libevm `legacy.PrecompiledStatefulContract`, which + // allows for the deprecated pattern of returning remaining gas by calling + // env.UseGas() on the difference between gas in and gas out. Since we call + // UseGas() ourselves, we therefore return `suppliedGas` unchanged to stop + // the legacy wrapper from double-counting spends. + return ret, suppliedGas, err +} + +// run implements the contract logic, using `env.Gas()` and `env.UseGas()` in +// place of `suppliedGas` and returning `remainingGas`, respectively. This +// avoids mixing gas-accounting patterns when using `env.Call()`. +func (c *NativeAssetCall) run(env vm.PrecompileEnvironment, stateDB contract.StateDB, caller common.Address, addr common.Address, input []byte, readOnly bool) (ret []byte, err error) { + if readOnly { + return nil, vm.ErrExecutionReverted + } + + to, assetID, assetAmount, callData, err := UnpackNativeAssetCallInput(input) + if err != nil { + log.Debug("unpacking native asset call input failed", "err", err) + return nil, vm.ErrExecutionReverted + } + + // Note: it is not possible for a negative `assetAmount` to be passed in here due to the fact that decoding a + // byte slice into a [*big.Int] will always return a positive value, as documented on [big.Int.SetBytes]. + if assetAmount.Sign() != 0 && stateDB.GetBalanceMultiCoin(caller, assetID).Cmp(assetAmount) < 0 { + return nil, vm.ErrInsufficientBalance + } + + snapshot := stateDB.Snapshot() + + if !stateDB.Exist(to) { + if !env.UseGas(c.CallNewAccountGas) { + return nil, vm.ErrOutOfGas + } + stateDB.CreateAccount(to) + } + + // Send `assetAmount` of `assetID` to `to` address + stateDB.SubBalanceMultiCoin(caller, assetID, assetAmount) + stateDB.AddBalanceMultiCoin(to, assetID, assetAmount) + + ret, err = env.Call(to, callData, env.Gas(), new(uint256.Int), vm.WithUNSAFECallerAddressProxying()) + // When an error was returned by the EVM or when setting the creation code + // above we revert to the snapshot and consume any gas remaining. Additionally + // when we're in homestead this also counts for code storage gas errors. + if err != nil { + stateDB.RevertToSnapshot(snapshot) + if err != vm.ErrExecutionReverted { + env.UseGas(env.Gas()) + } + } + return ret, err } -type deprecatedContract struct{} +type DeprecatedContract struct{} -func (*deprecatedContract) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { - return nil, suppliedGas, vmerrs.ErrExecutionReverted +func (*DeprecatedContract) Run(accessibleState contract.AccessibleState, caller common.Address, addr common.Address, input []byte, suppliedGas uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) { + return nil, suppliedGas, vm.ErrExecutionReverted } diff --git a/core/vm/contracts_stateful_test.go b/nativeasset/contract_test.go similarity index 79% rename from core/vm/contracts_stateful_test.go rename to nativeasset/contract_test.go index 9ac7652108..cfa2b7e268 100644 --- a/core/vm/contracts_stateful_test.go +++ b/nativeasset/contract_test.go @@ -1,60 +1,44 @@ // (c) 2019-2020, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package vm +package nativeasset_test import ( "math/big" "testing" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" + . "github.com/ava-labs/coreth/nativeasset" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + ethtypes "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" "github.com/holiman/uint256" "github.com/stretchr/testify/assert" -) - -func TestPrecompiledContractSpendsGas(t *testing.T) { - unwrapped := &sha256hash{} - input := []byte{'J', 'E', 'T', 'S'} - requiredGas := unwrapped.RequiredGas(input) - _, remainingGas, err := RunPrecompiledContract(unwrapped, input, requiredGas) - if err != nil { - t.Fatalf("Unexpectedly failed to run precompiled contract: %s", err) - } + // Force import core to register the VM hooks. + // This allows testing the precompiles by exercising the EVM. + _ "github.com/ava-labs/coreth/core" +) - if remainingGas != 0 { - t.Fatalf("Found more remaining gas than expected: %d", remainingGas) - } +type stateDB interface { + vm.StateDB + GetBalanceMultiCoin(common.Address, common.Hash) *big.Int } // CanTransfer checks whether there are enough funds in the address' account to make a transfer. // This does not take the necessary gas in to account to make the transfer valid. -func CanTransfer(db StateDB, addr common.Address, amount *uint256.Int) bool { +func CanTransfer(db vm.StateDB, addr common.Address, amount *uint256.Int) bool { return db.GetBalance(addr).Cmp(amount) >= 0 } -func CanTransferMC(db StateDB, addr common.Address, to common.Address, coinID common.Hash, amount *big.Int) bool { - log.Info("CanTransferMC", "address", addr, "to", to, "coinID", coinID, "amount", amount) - return db.GetBalanceMultiCoin(addr, coinID).Cmp(amount) >= 0 -} - // Transfer subtracts amount from sender and adds amount to recipient using the given Db -func Transfer(db StateDB, sender, recipient common.Address, amount *uint256.Int) { +func Transfer(db vm.StateDB, sender, recipient common.Address, amount *uint256.Int) { db.SubBalance(sender, amount) db.AddBalance(recipient, amount) } -// Transfer subtracts amount from sender and adds amount to recipient using the given Db -func TransferMultiCoin(db StateDB, sender, recipient common.Address, coinID common.Hash, amount *big.Int) { - db.SubBalanceMultiCoin(sender, coinID, amount) - db.AddBalanceMultiCoin(recipient, coinID, amount) -} - func TestPackNativeAssetCallInput(t *testing.T) { addr := common.BytesToAddress([]byte("hello")) assetID := common.BytesToHash([]byte("ScoobyCoin")) @@ -72,17 +56,18 @@ func TestPackNativeAssetCallInput(t *testing.T) { } func TestStatefulPrecompile(t *testing.T) { - vmCtx := BlockContext{ - BlockNumber: big.NewInt(0), - Time: 0, - CanTransfer: CanTransfer, - CanTransferMC: CanTransferMC, - Transfer: Transfer, - TransferMultiCoin: TransferMultiCoin, + vmCtx := vm.BlockContext{ + BlockNumber: big.NewInt(0), + Time: 0, + CanTransfer: CanTransfer, + Transfer: Transfer, + Header: ðtypes.Header{ + Number: big.NewInt(0), + }, } type statefulContractTest struct { - setupStateDB func() StateDB + setupStateDB func() stateDB from common.Address precompileAddr common.Address input []byte @@ -92,14 +77,13 @@ func TestStatefulPrecompile(t *testing.T) { expectedErr error expectedResult []byte name string - stateDBCheck func(*testing.T, StateDB) + stateDBCheck func(*testing.T, stateDB) } userAddr1 := common.BytesToAddress([]byte("user1")) userAddr2 := common.BytesToAddress([]byte("user2")) assetID := common.BytesToHash([]byte("ScoobyCoin")) zeroBytes := make([]byte, 32) - big0.FillBytes(zeroBytes) big0 := uint256.NewInt(0) bigHundred := big.NewInt(100) u256Hundred := uint256.NewInt(100) @@ -111,7 +95,7 @@ func TestStatefulPrecompile(t *testing.T) { tests := []statefulContractTest{ { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) @@ -135,7 +119,7 @@ func TestStatefulPrecompile(t *testing.T) { name: "native asset balance: uninitialized multicoin balance returns 0", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) @@ -161,7 +145,7 @@ func TestStatefulPrecompile(t *testing.T) { name: "native asset balance: initialized multicoin balance returns 0", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) @@ -186,7 +170,7 @@ func TestStatefulPrecompile(t *testing.T) { name: "native asset balance: returns correct non-zero multicoin balance", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) @@ -199,12 +183,12 @@ func TestStatefulPrecompile(t *testing.T) { value: big0, gasInput: params.AssetBalanceApricot, expectedGasRemaining: 0, - expectedErr: vmerrs.ErrExecutionReverted, + expectedErr: vm.ErrExecutionReverted, expectedResult: nil, name: "native asset balance: invalid input data reverts", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) @@ -217,12 +201,12 @@ func TestStatefulPrecompile(t *testing.T) { value: big0, gasInput: params.AssetBalanceApricot - 1, expectedGasRemaining: 0, - expectedErr: vmerrs.ErrOutOfGas, + expectedErr: vm.ErrOutOfGas, expectedResult: nil, name: "native asset balance: insufficient gas errors", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) @@ -235,18 +219,18 @@ func TestStatefulPrecompile(t *testing.T) { value: u256Hundred, gasInput: params.AssetBalanceApricot, expectedGasRemaining: params.AssetBalanceApricot, - expectedErr: vmerrs.ErrInsufficientBalance, + expectedErr: vm.ErrInsufficientBalance, expectedResult: nil, name: "native asset balance: non-zero value with insufficient funds reverts before running pre-compile", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, u256Hundred) - statedb.SetBalanceMultiCoin(userAddr1, assetID, bigHundred) + statedb.AddBalanceMultiCoin(userAddr1, assetID, bigHundred) statedb.Finalise(true) return statedb }, @@ -254,12 +238,12 @@ func TestStatefulPrecompile(t *testing.T) { precompileAddr: NativeAssetCallAddr, input: PackNativeAssetCallInput(userAddr2, assetID, big.NewInt(50), nil), value: big0, - gasInput: params.AssetCallApricot + params.CallNewAccountGas, - expectedGasRemaining: 0, + gasInput: params.AssetCallApricot + params.CallNewAccountGas + 123, + expectedGasRemaining: 123, expectedErr: nil, expectedResult: nil, name: "native asset call: multicoin transfer", - stateDBCheck: func(t *testing.T, stateDB StateDB) { + stateDBCheck: func(t *testing.T, stateDB stateDB) { user1Balance := stateDB.GetBalance(userAddr1) user2Balance := stateDB.GetBalance(userAddr2) user1AssetBalance := stateDB.GetBalanceMultiCoin(userAddr1, assetID) @@ -273,13 +257,13 @@ func TestStatefulPrecompile(t *testing.T) { }, }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, u256Hundred) - statedb.SetBalanceMultiCoin(userAddr1, assetID, bigHundred) + statedb.AddBalanceMultiCoin(userAddr1, assetID, bigHundred) statedb.Finalise(true) return statedb }, @@ -292,7 +276,7 @@ func TestStatefulPrecompile(t *testing.T) { expectedErr: nil, expectedResult: nil, name: "native asset call: multicoin transfer with non-zero value", - stateDBCheck: func(t *testing.T, stateDB StateDB) { + stateDBCheck: func(t *testing.T, stateDB stateDB) { user1Balance := stateDB.GetBalance(userAddr1) user2Balance := stateDB.GetBalance(userAddr2) nativeAssetCallAddrBalance := stateDB.GetBalance(NativeAssetCallAddr) @@ -308,13 +292,13 @@ func TestStatefulPrecompile(t *testing.T) { }, }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, u256Hundred) - statedb.SetBalanceMultiCoin(userAddr1, assetID, big.NewInt(50)) + statedb.AddBalanceMultiCoin(userAddr1, assetID, big.NewInt(50)) statedb.Finalise(true) return statedb }, @@ -324,10 +308,10 @@ func TestStatefulPrecompile(t *testing.T) { value: uint256.NewInt(50), gasInput: params.AssetCallApricot, expectedGasRemaining: 0, - expectedErr: vmerrs.ErrInsufficientBalance, + expectedErr: vm.ErrInsufficientBalance, expectedResult: nil, name: "native asset call: insufficient multicoin funds", - stateDBCheck: func(t *testing.T, stateDB StateDB) { + stateDBCheck: func(t *testing.T, stateDB stateDB) { user1Balance := stateDB.GetBalance(userAddr1) user2Balance := stateDB.GetBalance(userAddr2) user1AssetBalance := stateDB.GetBalanceMultiCoin(userAddr1, assetID) @@ -340,13 +324,13 @@ func TestStatefulPrecompile(t *testing.T) { }, }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, uint256.NewInt(50)) - statedb.SetBalanceMultiCoin(userAddr1, assetID, big.NewInt(50)) + statedb.AddBalanceMultiCoin(userAddr1, assetID, big.NewInt(50)) statedb.Finalise(true) return statedb }, @@ -356,10 +340,10 @@ func TestStatefulPrecompile(t *testing.T) { value: uint256.NewInt(51), gasInput: params.AssetCallApricot, expectedGasRemaining: params.AssetCallApricot, - expectedErr: vmerrs.ErrInsufficientBalance, + expectedErr: vm.ErrInsufficientBalance, expectedResult: nil, name: "native asset call: insufficient funds", - stateDBCheck: func(t *testing.T, stateDB StateDB) { + stateDBCheck: func(t *testing.T, stateDB stateDB) { user1Balance := stateDB.GetBalance(userAddr1) user2Balance := stateDB.GetBalance(userAddr2) user1AssetBalance := stateDB.GetBalanceMultiCoin(userAddr1, assetID) @@ -372,13 +356,13 @@ func TestStatefulPrecompile(t *testing.T) { }, }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, u256Hundred) - statedb.SetBalanceMultiCoin(userAddr1, assetID, bigHundred) + statedb.AddBalanceMultiCoin(userAddr1, assetID, bigHundred) statedb.Finalise(true) return statedb }, @@ -388,18 +372,18 @@ func TestStatefulPrecompile(t *testing.T) { value: uint256.NewInt(50), gasInput: params.AssetCallApricot - 1, expectedGasRemaining: 0, - expectedErr: vmerrs.ErrOutOfGas, + expectedErr: vm.ErrOutOfGas, expectedResult: nil, name: "native asset call: insufficient gas for native asset call", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, u256Hundred) - statedb.SetBalanceMultiCoin(userAddr1, assetID, bigHundred) + statedb.AddBalanceMultiCoin(userAddr1, assetID, bigHundred) statedb.Finalise(true) return statedb }, @@ -409,10 +393,10 @@ func TestStatefulPrecompile(t *testing.T) { value: uint256.NewInt(50), gasInput: params.AssetCallApricot + params.CallNewAccountGas - 1, expectedGasRemaining: 0, - expectedErr: vmerrs.ErrOutOfGas, + expectedErr: vm.ErrOutOfGas, expectedResult: nil, name: "native asset call: insufficient gas to create new account", - stateDBCheck: func(t *testing.T, stateDB StateDB) { + stateDBCheck: func(t *testing.T, stateDB stateDB) { user1Balance := stateDB.GetBalance(userAddr1) user2Balance := stateDB.GetBalance(userAddr2) user1AssetBalance := stateDB.GetBalanceMultiCoin(userAddr1, assetID) @@ -425,13 +409,13 @@ func TestStatefulPrecompile(t *testing.T) { }, }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, u256Hundred) - statedb.SetBalanceMultiCoin(userAddr1, assetID, bigHundred) + statedb.AddBalanceMultiCoin(userAddr1, assetID, bigHundred) statedb.Finalise(true) return statedb }, @@ -441,28 +425,28 @@ func TestStatefulPrecompile(t *testing.T) { value: uint256.NewInt(50), gasInput: params.AssetCallApricot + params.CallNewAccountGas, expectedGasRemaining: params.CallNewAccountGas, - expectedErr: vmerrs.ErrExecutionReverted, + expectedErr: vm.ErrExecutionReverted, expectedResult: nil, name: "native asset call: invalid input", }, { - setupStateDB: func() StateDB { + setupStateDB: func() stateDB { statedb, err := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil) if err != nil { t.Fatal(err) } statedb.SetBalance(userAddr1, u256Hundred) - statedb.SetBalanceMultiCoin(userAddr1, assetID, bigHundred) + statedb.AddBalanceMultiCoin(userAddr1, assetID, bigHundred) statedb.Finalise(true) return statedb }, from: userAddr1, - precompileAddr: genesisContractAddr, + precompileAddr: GenesisContractAddr, input: PackNativeAssetCallInput(userAddr2, assetID, big.NewInt(50), nil), value: big0, gasInput: params.AssetCallApricot + params.CallNewAccountGas, expectedGasRemaining: params.AssetCallApricot + params.CallNewAccountGas, - expectedErr: vmerrs.ErrExecutionReverted, + expectedErr: vm.ErrExecutionReverted, expectedResult: nil, name: "deprecated contract", }, @@ -471,10 +455,10 @@ func TestStatefulPrecompile(t *testing.T) { t.Run(test.name, func(t *testing.T) { stateDB := test.setupStateDB() // Create EVM with BlockNumber and Time initialized to 0 to enable Apricot Rules. - evm := NewEVM(vmCtx, TxContext{}, stateDB, params.TestApricotPhase5Config, Config{}) // Use ApricotPhase5Config because these precompiles are deprecated in ApricotPhase6. - ret, gasRemaining, err := evm.Call(AccountRef(test.from), test.precompileAddr, test.input, test.gasInput, test.value) + evm := vm.NewEVM(vmCtx, vm.TxContext{}, stateDB, params.TestApricotPhase5Config, vm.Config{}) // Use ApricotPhase5Config because these precompiles are deprecated in ApricotPhase6. + ret, gasRemaining, err := evm.Call(vm.AccountRef(test.from), test.precompileAddr, test.input, test.gasInput, test.value) // Place gas remaining check before error check, so that it is not skipped when there is an error - assert.Equal(t, test.expectedGasRemaining, gasRemaining, "unexpected gas remaining") + assert.Equalf(t, test.expectedGasRemaining, gasRemaining, "unexpected gas remaining (%d of %d)", gasRemaining, test.gasInput) if test.expectedErr != nil { assert.Equal(t, test.expectedErr, err, "expected error to match") diff --git a/node/api.go b/node/api.go index f0be57313f..1a404b0d10 100644 --- a/node/api.go +++ b/node/api.go @@ -29,8 +29,8 @@ package node import ( "github.com/ava-labs/coreth/internal/debug" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/crypto" ) // apis returns the collection of built-in RPC APIs. diff --git a/node/config.go b/node/config.go index 58290afea7..c96004e110 100644 --- a/node/config.go +++ b/node/config.go @@ -31,10 +31,10 @@ import ( "os" "path/filepath" - "github.com/ava-labs/coreth/accounts" - "github.com/ava-labs/coreth/accounts/external" - "github.com/ava-labs/coreth/accounts/keystore" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/accounts" + "github.com/ava-labs/libevm/accounts/external" + "github.com/ava-labs/libevm/accounts/keystore" + "github.com/ava-labs/libevm/log" ) // Config represents a small collection of configuration values to fine tune the diff --git a/node/node.go b/node/node.go index 2cc4551c29..64ddfe4d8c 100644 --- a/node/node.go +++ b/node/node.go @@ -27,8 +27,8 @@ package node import ( - "github.com/ava-labs/coreth/accounts" "github.com/ava-labs/coreth/rpc" + "github.com/ava-labs/libevm/accounts" ) // Node is a container on which services can be registered. diff --git a/params/config.go b/params/config.go index b10cc516ab..0e6c927ec5 100644 --- a/params/config.go +++ b/params/config.go @@ -27,14 +27,13 @@ package params import ( - "encoding/json" - "fmt" "math/big" - "github.com/ava-labs/coreth/precompile/modules" - "github.com/ava-labs/coreth/precompile/precompileconfig" + "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + ethparams "github.com/ava-labs/libevm/params" ) // Avalanche ChainIDs @@ -47,503 +46,313 @@ var ( AvalancheLocalChainID = big.NewInt(43112) ) +// Guarantees extras initialisation before a call to [params.ChainConfig.Rules]. +var _ = libevmInit() + var ( - TestChainConfig = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: utils.NewUint64(0), - FortunaTimestamp: utils.NewUint64(0), + TestChainConfig = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ShanghaiTime: utils.TimeToNewUint64(upgrade.GetConfig(constants.UnitTestID).DurangoTime), + CancunTime: utils.TimeToNewUint64(upgrade.GetConfig(constants.UnitTestID).EtnaTime), }, - } + extras.TestChainConfig, + ) - TestLaunchConfig = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: nil, - ApricotPhase2BlockTimestamp: nil, - ApricotPhase3BlockTimestamp: nil, - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestLaunchConfig = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), }, - } + extras.TestLaunchConfig, + ) - TestApricotPhase1Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: nil, - ApricotPhase3BlockTimestamp: nil, - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhase1Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), }, - } + extras.TestApricotPhase1Config, + ) - TestApricotPhase2Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: nil, - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhase2Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), }, - } + extras.TestApricotPhase2Config, + ) - TestApricotPhase3Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: nil, - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhase3Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestApricotPhase3Config, + ) - TestApricotPhase4Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: nil, - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhase4Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestApricotPhase4Config, + ) - TestApricotPhase5Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: nil, - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhase5Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestApricotPhase5Config, + ) - TestApricotPhasePre6Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: nil, - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhasePre6Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestApricotPhasePre6Config, + ) - TestApricotPhase6Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: nil, - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhase6Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestApricotPhase6Config, + ) - TestApricotPhasePost6Config = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: nil, - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestApricotPhasePost6Config = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestApricotPhasePost6Config, + ) - TestBanffChainConfig = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: nil, - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestBanffChainConfig = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestBanffChainConfig, + ) - TestCortinaChainConfig = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: nil, - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestCortinaChainConfig = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - } + extras.TestCortinaChainConfig, + ) - TestDurangoChainConfig = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ShanghaiTime: utils.NewUint64(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: nil, - FortunaTimestamp: nil, + TestDurangoChainConfig = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ShanghaiTime: utils.NewUint64(0), }, - } + extras.TestDurangoChainConfig, + ) - TestEtnaChainConfig = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ShanghaiTime: utils.NewUint64(0), - CancunTime: utils.NewUint64(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: utils.NewUint64(0), - FortunaTimestamp: nil, + TestEtnaChainConfig = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ShanghaiTime: utils.NewUint64(0), + CancunTime: utils.NewUint64(0), }, - } + extras.TestEtnaChainConfig, + ) - TestFortunaChainConfig = &ChainConfig{ - AvalancheContext: AvalancheContext{utils.TestSnowContext()}, - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ShanghaiTime: utils.NewUint64(0), - CancunTime: utils.NewUint64(0), - NetworkUpgrades: NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), - ApricotPhase6BlockTimestamp: utils.NewUint64(0), - ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), - EtnaTimestamp: utils.NewUint64(0), - FortunaTimestamp: utils.NewUint64(0), + TestFortunaChainConfig = WithExtra( + &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ShanghaiTime: utils.NewUint64(0), + CancunTime: utils.NewUint64(0), }, - } + extras.TestFortunaChainConfig, + ) - TestRules = TestChainConfig.Rules(new(big.Int), 0) + TestRules = TestChainConfig.Rules(new(big.Int), IsMergeTODO, 0) ) // ChainConfig is the core config which determines the blockchain settings. @@ -551,542 +360,11 @@ var ( // ChainConfig is stored in the database on a per block basis. This means // that any network, identified by its genesis block, can have its own // set of configuration options. -type ChainConfig struct { - ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection - - HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead) - - DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork) - DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork - - // EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) - EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork) - EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block - EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block - - ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium) - ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated) - PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople) - IstanbulBlock *big.Int `json:"istanbulBlock,omitempty"` // Istanbul switch block (nil = no fork, 0 = already on istanbul) - MuirGlacierBlock *big.Int `json:"muirGlacierBlock,omitempty"` // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated) - BerlinBlock *big.Int `json:"berlinBlock,omitempty"` // Berlin switch block (nil = no fork, 0 = already on berlin) - LondonBlock *big.Int `json:"londonBlock,omitempty"` // London switch block (nil = no fork, 0 = already on london) - - // Fork scheduling was switched from blocks to timestamps here - - ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) - CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already activated) - VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) - - NetworkUpgrades // Config for timestamps that enable network upgrades. Skip encoding/decoding directly into ChainConfig. - - AvalancheContext `json:"-"` // Avalanche specific context set during VM initialization. Not serialized. - - UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Skip encoding/decoding directly into ChainConfig. -} - -// Description returns a human-readable description of ChainConfig. -func (c *ChainConfig) Description() string { - var banner string - - banner += fmt.Sprintf("Chain ID: %v\n", c.ChainID) - banner += "Consensus: Dummy Consensus Engine\n\n" - - // Create a list of forks with a short description of them. Forks that only - // makes sense for mainnet should be optional at printing to avoid bloating - // the output for testnets and private networks. - banner += "Hard Forks (block based):\n" - banner += fmt.Sprintf(" - Homestead: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock) - if c.DAOForkBlock != nil { - banner += fmt.Sprintf(" - DAO Fork: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock) - } - banner += fmt.Sprintf(" - Tangerine Whistle (EIP 150): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)\n", c.EIP150Block) - banner += fmt.Sprintf(" - Spurious Dragon/1 (EIP 155): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.EIP155Block) - banner += fmt.Sprintf(" - Spurious Dragon/2 (EIP 158): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.EIP155Block) - banner += fmt.Sprintf(" - Byzantium: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock) - banner += fmt.Sprintf(" - Constantinople: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock) - banner += fmt.Sprintf(" - Petersburg: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock) - banner += fmt.Sprintf(" - Istanbul: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock) - if c.MuirGlacierBlock != nil { - banner += fmt.Sprintf(" - Muir Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock) - } - - banner += "Hard forks (timestamp based):\n" - banner += fmt.Sprintf(" - Cancun Timestamp: @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md)\n", ptrToString(c.CancunTime)) - banner += fmt.Sprintf(" - Verkle Timestamp: @%-10v", ptrToString(c.VerkleTime)) - banner += "\n" - - banner += "Avalanche Upgrades (timestamp based):\n" - banner += c.NetworkUpgrades.Description() - banner += "\n" - - upgradeConfigBytes, err := json.Marshal(c.UpgradeConfig) - if err != nil { - upgradeConfigBytes = []byte("cannot marshal UpgradeConfig") - } - banner += fmt.Sprintf("Upgrade Config: %s", string(upgradeConfigBytes)) - banner += "\n" - return banner -} - -// IsHomestead returns whether num is either equal to the homestead block or greater. -func (c *ChainConfig) IsHomestead(num *big.Int) bool { - return isBlockForked(c.HomesteadBlock, num) -} - -// IsDAOFork returns whether num is either equal to the DAO fork block or greater. -func (c *ChainConfig) IsDAOFork(num *big.Int) bool { - return isBlockForked(c.DAOForkBlock, num) -} - -// IsEIP150 returns whether num is either equal to the EIP150 fork block or greater. -func (c *ChainConfig) IsEIP150(num *big.Int) bool { - return isBlockForked(c.EIP150Block, num) -} - -// IsEIP155 returns whether num is either equal to the EIP155 fork block or greater. -func (c *ChainConfig) IsEIP155(num *big.Int) bool { - return isBlockForked(c.EIP155Block, num) -} - -// IsEIP158 returns whether num is either equal to the EIP158 fork block or greater. -func (c *ChainConfig) IsEIP158(num *big.Int) bool { - return isBlockForked(c.EIP158Block, num) -} - -// IsByzantium returns whether num is either equal to the Byzantium fork block or greater. -func (c *ChainConfig) IsByzantium(num *big.Int) bool { - return isBlockForked(c.ByzantiumBlock, num) -} - -// IsConstantinople returns whether num is either equal to the Constantinople fork block or greater. -func (c *ChainConfig) IsConstantinople(num *big.Int) bool { - return isBlockForked(c.ConstantinopleBlock, num) -} - -// IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. -func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { - return isBlockForked(c.MuirGlacierBlock, num) -} - -// IsPetersburg returns whether num is either -// - equal to or greater than the PetersburgBlock fork block, -// - OR is nil, and Constantinople is active -func (c *ChainConfig) IsPetersburg(num *big.Int) bool { - return isBlockForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isBlockForked(c.ConstantinopleBlock, num) -} - -// IsIstanbul returns whether num is either equal to the Istanbul fork block or greater. -func (c *ChainConfig) IsIstanbul(num *big.Int) bool { - return isBlockForked(c.IstanbulBlock, num) -} - -// IsBerlin returns whether num is either equal to the Berlin fork block or greater. -func (c *ChainConfig) IsBerlin(num *big.Int) bool { - return isBlockForked(c.BerlinBlock, num) -} - -// IsLondon returns whether num is either equal to the London fork block or greater. -func (c *ChainConfig) IsLondon(num *big.Int) bool { - return isBlockForked(c.LondonBlock, num) -} - -// IsShanghai returns whether time is either equal to the Shanghai fork time or greater. -func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool { - return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time) -} - -// IsCancun returns whether num is either equal to the Cancun fork time or greater. -func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool { - return c.IsLondon(num) && isTimestampForked(c.CancunTime, time) -} - -// IsVerkle returns whether num is either equal to the Verkle fork time or greater. -func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { - return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) -} - -// CheckCompatible checks whether scheduled fork transitions have been imported -// with a mismatching chain configuration. -func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { - var ( - bhead = new(big.Int).SetUint64(height) - btime = time - ) - // Iterate checkCompatible to find the lowest conflict. - var lasterr *ConfigCompatError - for { - err := c.checkCompatible(newcfg, bhead, btime) - if err == nil || (lasterr != nil && err.RewindToBlock == lasterr.RewindToBlock && err.RewindToTime == lasterr.RewindToTime) { - break - } - lasterr = err - - if err.RewindToTime > 0 { - btime = err.RewindToTime - } else { - bhead.SetUint64(err.RewindToBlock) - } - } - return lasterr -} - -type fork struct { - name string - block *big.Int // some go-ethereum forks use block numbers - timestamp *uint64 // Avalanche forks use timestamps - optional bool // if true, the fork may be nil and next fork is still allowed -} - -// CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough -// to guarantee that forks can be implemented in a different order than on official networks -func (c *ChainConfig) CheckConfigForkOrder() error { - ethForks := []fork{ - {name: "homesteadBlock", block: c.HomesteadBlock}, - {name: "daoForkBlock", block: c.DAOForkBlock, optional: true}, - {name: "eip150Block", block: c.EIP150Block}, - {name: "eip155Block", block: c.EIP155Block}, - {name: "eip158Block", block: c.EIP158Block}, - {name: "byzantiumBlock", block: c.ByzantiumBlock}, - {name: "constantinopleBlock", block: c.ConstantinopleBlock}, - {name: "petersburgBlock", block: c.PetersburgBlock}, - {name: "istanbulBlock", block: c.IstanbulBlock}, - {name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true}, - {name: "berlinBlock", block: c.BerlinBlock}, - {name: "londonBlock", block: c.LondonBlock}, - {name: "shanghaiTime", timestamp: c.ShanghaiTime}, - {name: "cancunTime", timestamp: c.CancunTime, optional: true}, - {name: "verkleTime", timestamp: c.VerkleTime, optional: true}, - } - - // Check that forks are enabled in order - if err := checkForks(ethForks, true); err != nil { - return err - } - - // Note: In Avalanche, hard forks must take place via block timestamps instead - // of block numbers since blocks are produced asynchronously. Therefore, we do not - // check that the block timestamps in the same way as for - // the block number forks since it would not be a meaningful comparison. - // Instead, we check only that Phases are enabled in order. - // Note: we do not add the optional stateful precompile configs in here because they are optional - // and independent, such that the ordering they are enabled does not impact the correctness of the - // chain config. - if err := checkForks(c.forkOrder(), false); err != nil { - return err - } - - return nil -} - -// checkForks checks that forks are enabled in order and returns an error if not -// [blockFork] is true if the fork is a block number fork, false if it is a timestamp fork -func checkForks(forks []fork, blockFork bool) error { - lastFork := fork{} - for _, cur := range forks { - if lastFork.name != "" { - switch { - // Non-optional forks must all be present in the chain config up to the last defined fork - case lastFork.block == nil && lastFork.timestamp == nil && (cur.block != nil || cur.timestamp != nil): - if cur.block != nil { - return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at block %v", - lastFork.name, cur.name, cur.block) - } else { - return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at timestamp %v", - lastFork.name, cur.name, cur.timestamp) - } - - // Fork (whether defined by block or timestamp) must follow the fork definition sequence - case (lastFork.block != nil && cur.block != nil) || (lastFork.timestamp != nil && cur.timestamp != nil): - if lastFork.block != nil && lastFork.block.Cmp(cur.block) > 0 { - return fmt.Errorf("unsupported fork ordering: %v enabled at block %v, but %v enabled at block %v", - lastFork.name, lastFork.block, cur.name, cur.block) - } else if lastFork.timestamp != nil && *lastFork.timestamp > *cur.timestamp { - return fmt.Errorf("unsupported fork ordering: %v enabled at timestamp %v, but %v enabled at timestamp %v", - lastFork.name, lastFork.timestamp, cur.name, cur.timestamp) - } - - // Timestamp based forks can follow block based ones, but not the other way around - if lastFork.timestamp != nil && cur.block != nil { - return fmt.Errorf("unsupported fork ordering: %v used timestamp ordering, but %v reverted to block ordering", - lastFork.name, cur.name) - } - } - } - // If it was optional and not set, then ignore it - if !cur.optional || (cur.block != nil || cur.timestamp != nil) { - lastFork = cur - } - } - return nil -} - -// checkCompatible confirms that [newcfg] is backwards compatible with [c] to upgrade with the given head block height and timestamp. -// This confirms that all Ethereum and Avalanche upgrades are backwards compatible as well as that the precompile config is backwards -// compatible. -func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, headTimestamp uint64) *ConfigCompatError { - if isForkBlockIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, headNumber) { - return newBlockCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) - } - if isForkBlockIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, headNumber) { - return newBlockCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) - } - if c.IsDAOFork(headNumber) && c.DAOForkSupport != newcfg.DAOForkSupport { - return newBlockCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) - } - if isForkBlockIncompatible(c.EIP150Block, newcfg.EIP150Block, headNumber) { - return newBlockCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) - } - if isForkBlockIncompatible(c.EIP155Block, newcfg.EIP155Block, headNumber) { - return newBlockCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) - } - if isForkBlockIncompatible(c.EIP158Block, newcfg.EIP158Block, headNumber) { - return newBlockCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) - } - if c.IsEIP158(headNumber) && !configBlockEqual(c.ChainID, newcfg.ChainID) { - return newBlockCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) - } - if isForkBlockIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, headNumber) { - return newBlockCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) - } - if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, headNumber) { - return newBlockCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) - } - if isForkBlockIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, headNumber) { - // the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople - // mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set - if isForkBlockIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, headNumber) { - return newBlockCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock) - } - } - if isForkBlockIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, headNumber) { - return newBlockCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock) - } - if isForkBlockIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, headNumber) { - return newBlockCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock) - } - if isForkBlockIncompatible(c.BerlinBlock, newcfg.BerlinBlock, headNumber) { - return newBlockCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock) - } - if isForkBlockIncompatible(c.LondonBlock, newcfg.LondonBlock, headNumber) { - return newBlockCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock) - } - if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) { - return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime) - } - if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) { - return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime) - } - if isForkTimestampIncompatible(c.VerkleTime, newcfg.VerkleTime, headTimestamp) { - return newTimestampCompatError("Verkle fork timestamp", c.VerkleTime, newcfg.VerkleTime) - } - - // Check avalanche network upgrades - if err := c.CheckNetworkUpgradesCompatible(&newcfg.NetworkUpgrades, headTimestamp); err != nil { - return err - } - return nil -} - -// isForkBlockIncompatible returns true if a fork scheduled at block s1 cannot be -// rescheduled to block s2 because head is already past the fork. -func isForkBlockIncompatible(s1, s2, head *big.Int) bool { - return (isBlockForked(s1, head) || isBlockForked(s2, head)) && !configBlockEqual(s1, s2) -} - -// isBlockForked returns whether a fork scheduled at block s is active at the -// given head block. Whilst this method is the same as isTimestampForked, they -// are explicitly separate for clearer reading. -func isBlockForked(s, head *big.Int) bool { - if s == nil || head == nil { - return false - } - return s.Cmp(head) <= 0 -} - -func configBlockEqual(x, y *big.Int) bool { - if x == nil { - return y == nil - } - if y == nil { - return x == nil - } - return x.Cmp(y) == 0 -} - -// isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1 -// cannot be rescheduled to timestamp s2 because head is already past the fork. -func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool { - return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) -} - -// isTimestampForked returns whether a fork scheduled at timestamp s is active -// at the given head timestamp. Whilst this method is the same as isBlockForked, -// they are explicitly separate for clearer reading. -func isTimestampForked(s *uint64, head uint64) bool { - if s == nil { - return false - } - return *s <= head -} - -func configTimestampEqual(x, y *uint64) bool { - if x == nil { - return y == nil - } - if y == nil { - return x == nil - } - return *x == *y -} - -// ConfigCompatError is raised if the locally-stored blockchain is initialised with a -// ChainConfig that would alter the past. -type ConfigCompatError struct { - What string - - // block numbers of the stored and new configurations if block based forking - StoredBlock, NewBlock *big.Int - - // timestamps of the stored and new configurations if time based forking - StoredTime, NewTime *uint64 - - // the block number to which the local chain must be rewound to correct the error - RewindToBlock uint64 - - // the timestamp to which the local chain must be rewound to correct the error - RewindToTime uint64 -} - -func newBlockCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError { - var rew *big.Int - switch { - case storedblock == nil: - rew = newblock - case newblock == nil || storedblock.Cmp(newblock) < 0: - rew = storedblock - default: - rew = newblock - } - err := &ConfigCompatError{ - What: what, - StoredBlock: storedblock, - NewBlock: newblock, - RewindToBlock: 0, - } - if rew != nil && rew.Sign() > 0 { - err.RewindToBlock = rew.Uint64() - 1 - } - return err -} - -func newTimestampCompatError(what string, storedtime, newtime *uint64) *ConfigCompatError { - var rew *uint64 - switch { - case storedtime == nil: - rew = newtime - case newtime == nil || *storedtime < *newtime: - rew = storedtime - default: - rew = newtime - } - err := &ConfigCompatError{ - What: what, - StoredTime: storedtime, - NewTime: newtime, - RewindToTime: 0, - } - if rew != nil && *rew > 0 { - err.RewindToTime = *rew - 1 - } - return err -} - -func (err *ConfigCompatError) Error() string { - if err.StoredBlock != nil { - return fmt.Sprintf("mismatching %s in database (have block %d, want block %d, rewindto block %d)", err.What, err.StoredBlock, err.NewBlock, err.RewindToBlock) - } - return fmt.Sprintf("mismatching %s in database (have timestamp %s, want timestamp %s, rewindto timestamp %d)", err.What, ptrToString(err.StoredTime), ptrToString(err.NewTime), err.RewindToTime) -} - -type EthRules struct { - IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool - IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool - IsCancun bool - IsVerkle bool -} +type ChainConfig = ethparams.ChainConfig // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions // that do not have or require information about the block. // // Rules is a one time interface meaning that it shouldn't be used in between transition // phases. -type Rules struct { - ChainID *big.Int - - // Rules for Ethereum releases - EthRules - - // Rules for Avalanche releases - AvalancheRules - - // ActivePrecompiles maps addresses to stateful precompiled contracts that are enabled - // for this rule set. - // Note: none of these addresses should conflict with the address space used by - // any existing precompiles. - ActivePrecompiles map[common.Address]precompileconfig.Config - // Predicaters maps addresses to stateful precompile Predicaters - // that are enabled for this rule set. - Predicaters map[common.Address]precompileconfig.Predicater - // AccepterPrecompiles map addresses to stateful precompile accepter functions - // that are enabled for this rule set. - AccepterPrecompiles map[common.Address]precompileconfig.Accepter -} - -// Rules ensures c's ChainID is not nil. -func (c *ChainConfig) rules(num *big.Int, timestamp uint64) Rules { - chainID := c.ChainID - if chainID == nil { - chainID = new(big.Int) - } - return Rules{ - ChainID: new(big.Int).Set(chainID), - EthRules: EthRules{ - IsHomestead: c.IsHomestead(num), - IsEIP150: c.IsEIP150(num), - IsEIP155: c.IsEIP155(num), - IsEIP158: c.IsEIP158(num), - IsByzantium: c.IsByzantium(num), - IsConstantinople: c.IsConstantinople(num), - IsPetersburg: c.IsPetersburg(num), - IsIstanbul: c.IsIstanbul(num), - IsCancun: c.IsCancun(num, timestamp), - }, - } -} - -// Rules returns the Avalanche modified rules to support Avalanche -// network upgrades -func (c *ChainConfig) Rules(blockNum *big.Int, timestamp uint64) Rules { - rules := c.rules(blockNum, timestamp) - - rules.AvalancheRules = c.GetAvalancheRules(timestamp) - - // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. - rules.ActivePrecompiles = make(map[common.Address]precompileconfig.Config) - rules.Predicaters = make(map[common.Address]precompileconfig.Predicater) - rules.AccepterPrecompiles = make(map[common.Address]precompileconfig.Accepter) - for _, module := range modules.RegisteredModules() { - if config := c.getActivePrecompileConfig(module.Address, timestamp); config != nil && !config.IsDisabled() { - rules.ActivePrecompiles[module.Address] = config - if predicater, ok := config.(precompileconfig.Predicater); ok { - rules.Predicaters[module.Address] = predicater - } - if precompileAccepter, ok := config.(precompileconfig.Accepter); ok { - rules.AccepterPrecompiles[module.Address] = precompileAccepter - } - } - } - - return rules -} +type Rules = ethparams.Rules diff --git a/params/config_extra.go b/params/config_extra.go index 9d5be4bfa9..ab8f7cc89c 100644 --- a/params/config_extra.go +++ b/params/config_extra.go @@ -6,36 +6,24 @@ package params import ( "encoding/json" "errors" - "fmt" "math/big" - "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/upgrade" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" ) const ( maxJSONLen = 64 * 1024 * 1024 // 64MB + // TODO: Value to pass to geth's Rules by default where the appropriate + // context is not available in the avalanche code. (similar to context.TODO()) + IsMergeTODO = true ) -// UpgradeConfig includes the following configs that may be specified in upgradeBytes: -// - Timestamps that enable avalanche network upgrades, -// - Enabling or disabling precompiles as network upgrades. -type UpgradeConfig struct { - // Config for enabling and disabling precompiles as network upgrades. - PrecompileUpgrades []PrecompileUpgrade `json:"precompileUpgrades,omitempty"` -} - -// AvalancheContext provides Avalanche specific context directly into the EVM. -type AvalancheContext struct { - SnowCtx *snow.Context -} - // SetEthUpgrades enables Etheruem network upgrades using the same time as // the Avalanche network upgrade that enables them. -func (c *ChainConfig) SetEthUpgrades() { +func SetEthUpgrades(c *ChainConfig) { // Set Ethereum block upgrades to initially activated as they were already activated on launch. c.HomesteadBlock = big.NewInt(0) c.DAOForkBlock = big.NewInt(0) @@ -60,51 +48,47 @@ func (c *ChainConfig) SetEthUpgrades() { // to the initially active time. This is likely to correspond to an intended block // number of 0 as well. initiallyActive := uint64(upgrade.InitiallyActiveTime.Unix()) - if c.ApricotPhase2BlockTimestamp != nil && *c.ApricotPhase2BlockTimestamp <= initiallyActive && c.BerlinBlock == nil { + extra := GetExtra(c) + if extra.ApricotPhase2BlockTimestamp != nil && *extra.ApricotPhase2BlockTimestamp <= initiallyActive && c.BerlinBlock == nil { c.BerlinBlock = big.NewInt(0) } - if c.ApricotPhase3BlockTimestamp != nil && *c.ApricotPhase3BlockTimestamp <= initiallyActive && c.LondonBlock == nil { + if extra.ApricotPhase3BlockTimestamp != nil && *extra.ApricotPhase3BlockTimestamp <= initiallyActive && c.LondonBlock == nil { c.LondonBlock = big.NewInt(0) } } - if c.DurangoBlockTimestamp != nil { - c.ShanghaiTime = utils.NewUint64(*c.DurangoBlockTimestamp) + extra := GetExtra(c) + if extra.DurangoBlockTimestamp != nil { + c.ShanghaiTime = utils.NewUint64(*extra.DurangoBlockTimestamp) } - if c.EtnaTimestamp != nil { - c.CancunTime = utils.NewUint64(*c.EtnaTimestamp) + if extra.EtnaTimestamp != nil { + c.CancunTime = utils.NewUint64(*extra.EtnaTimestamp) } } -// UnmarshalJSON parses the JSON-encoded data and stores the result in the -// object pointed to by c. -// This is a custom unmarshaler to handle the Precompiles field. -// Precompiles was presented as an inline object in the JSON. -// This custom unmarshaler ensures backwards compatibility with the old format. -func (c *ChainConfig) UnmarshalJSON(data []byte) error { - // Alias ChainConfig to avoid recursion - type _ChainConfig ChainConfig - tmp := _ChainConfig{} - if err := json.Unmarshal(data, &tmp); err != nil { - return err +func GetExtra(c *ChainConfig) *extras.ChainConfig { + ex := payloads.ChainConfig.Get(c) + if ex == nil { + ex = &extras.ChainConfig{} + payloads.ChainConfig.Set(c, ex) } + return ex +} - // At this point we have populated all fields except PrecompileUpgrade - *c = ChainConfig(tmp) - - return nil +func Copy(c *ChainConfig) ChainConfig { + cpy := *c + extraCpy := *GetExtra(c) + return *WithExtra(&cpy, &extraCpy) } -// MarshalJSON returns the JSON encoding of c. -// This is a custom marshaler to handle the Precompiles field. -func (c ChainConfig) MarshalJSON() ([]byte, error) { - // Alias ChainConfig to avoid recursion - type _ChainConfig ChainConfig - return json.Marshal(_ChainConfig(c)) +// WithExtra sets the extra payload on `c` and returns the modified argument. +func WithExtra(c *ChainConfig, extra *extras.ChainConfig) *ChainConfig { + payloads.ChainConfig.Set(c, extra) + return c } type ChainConfigWithUpgradesJSON struct { ChainConfig - UpgradeConfig UpgradeConfig `json:"upgrades,omitempty"` + UpgradeConfig extras.UpgradeConfig `json:"upgrades,omitempty"` } // MarshalJSON implements json.Marshaler. This is a workaround for the fact that @@ -114,7 +98,7 @@ type ChainConfigWithUpgradesJSON struct { // ChainConfig struct. func (cu ChainConfigWithUpgradesJSON) MarshalJSON() ([]byte, error) { // embed the ChainConfig struct into the response - chainConfigJSON, err := json.Marshal(cu.ChainConfig) + chainConfigJSON, err := json.Marshal(&cu.ChainConfig) if err != nil { return nil, err } @@ -123,7 +107,7 @@ func (cu ChainConfigWithUpgradesJSON) MarshalJSON() ([]byte, error) { } type upgrades struct { - UpgradeConfig UpgradeConfig `json:"upgrades"` + UpgradeConfig extras.UpgradeConfig `json:"upgrades"` } upgradeJSON, err := json.Marshal(upgrades{cu.UpgradeConfig}) @@ -149,7 +133,7 @@ func (cu *ChainConfigWithUpgradesJSON) UnmarshalJSON(input []byte) error { } type upgrades struct { - UpgradeConfig UpgradeConfig `json:"upgrades"` + UpgradeConfig extras.UpgradeConfig `json:"upgrades"` } var u upgrades @@ -161,64 +145,12 @@ func (cu *ChainConfigWithUpgradesJSON) UnmarshalJSON(input []byte) error { return nil } -// Verify verifies chain config and returns error -func (c *ChainConfig) Verify() error { - // Verify the precompile upgrades are internally consistent given the existing chainConfig. - if err := c.verifyPrecompileUpgrades(); err != nil { - return fmt.Errorf("invalid precompile upgrades: %w", err) - } - - return nil -} - -// IsPrecompileEnabled returns whether precompile with [address] is enabled at [timestamp]. -func (c *ChainConfig) IsPrecompileEnabled(address common.Address, timestamp uint64) bool { - config := c.getActivePrecompileConfig(address, timestamp) - return config != nil && !config.IsDisabled() -} - // ToWithUpgradesJSON converts the ChainConfig to ChainConfigWithUpgradesJSON with upgrades explicitly displayed. // ChainConfig does not include upgrades in its JSON output. // This is a workaround for showing upgrades in the JSON output. -func (c *ChainConfig) ToWithUpgradesJSON() *ChainConfigWithUpgradesJSON { +func ToWithUpgradesJSON(c *ChainConfig) *ChainConfigWithUpgradesJSON { return &ChainConfigWithUpgradesJSON{ ChainConfig: *c, - UpgradeConfig: c.UpgradeConfig, - } -} - -func (r *Rules) PredicatersExist() bool { - return len(r.Predicaters) > 0 -} - -func (r *Rules) PredicaterExists(addr common.Address) bool { - _, PredicaterExists := r.Predicaters[addr] - return PredicaterExists -} - -// IsPrecompileEnabled returns true if the precompile at [addr] is enabled for this rule set. -func (r *Rules) IsPrecompileEnabled(addr common.Address) bool { - _, ok := r.ActivePrecompiles[addr] - return ok -} - -func ptrToString(val *uint64) string { - if val == nil { - return "nil" - } - return fmt.Sprintf("%d", *val) -} - -// IsForkTransition returns true if [fork] activates during the transition from -// [parent] to [current]. -// Taking [parent] as a pointer allows for us to pass nil when checking forks -// that activate during genesis. -// Note: this works for both block number and timestamp activated forks. -func IsForkTransition(fork *uint64, parent *uint64, current uint64) bool { - var parentForked bool - if parent != nil { - parentForked = isTimestampForked(fork, *parent) + UpgradeConfig: GetExtra(c).UpgradeConfig, } - currentForked := isTimestampForked(fork, current) - return !parentForked && currentForked } diff --git a/params/config_libevm.go b/params/config_libevm.go new file mode 100644 index 0000000000..4cb663e6f4 --- /dev/null +++ b/params/config_libevm.go @@ -0,0 +1,55 @@ +// (c) 2024-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package params + +import ( + "math/big" + + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/precompile/modules" + "github.com/ava-labs/coreth/precompile/precompileconfig" + "github.com/ava-labs/libevm/common" + ethparams "github.com/ava-labs/libevm/params" +) + +// libevmInit would ideally be a regular init() function, but it MUST be run +// before any calls to [params.ChainConfig.Rules]. See `config.go` for its call site. +func libevmInit() any { + payloads = ethparams.RegisterExtras(ethparams.Extras[*extras.ChainConfig, RulesExtra]{ + ReuseJSONRoot: true, // Reuse the root JSON input when unmarshalling the extra payload. + NewRules: constructRulesExtra, + }) + return nil +} + +var payloads ethparams.ExtraPayloads[*extras.ChainConfig, RulesExtra] + +// constructRulesExtra acts as an adjunct to the [params.ChainConfig.Rules] +// method. Its primary purpose is to construct the extra payload for the +// [params.Rules] but it MAY also modify the [params.Rules]. +func constructRulesExtra(c *ethparams.ChainConfig, r *ethparams.Rules, cEx *extras.ChainConfig, blockNum *big.Int, isMerge bool, timestamp uint64) RulesExtra { + var rules RulesExtra + if cEx == nil { + return rules + } + rules.AvalancheRules = cEx.GetAvalancheRules(timestamp) + + // Initialize the stateful precompiles that should be enabled at [blockTimestamp]. + rules.Precompiles = make(map[common.Address]precompileconfig.Config) + rules.Predicaters = make(map[common.Address]precompileconfig.Predicater) + rules.AccepterPrecompiles = make(map[common.Address]precompileconfig.Accepter) + for _, module := range modules.RegisteredModules() { + if config := cEx.GetActivePrecompileConfig(module.Address, timestamp); config != nil && !config.IsDisabled() { + rules.Precompiles[module.Address] = config + if predicater, ok := config.(precompileconfig.Predicater); ok { + rules.Predicaters[module.Address] = predicater + } + if precompileAccepter, ok := config.(precompileconfig.Accepter); ok { + rules.AccepterPrecompiles[module.Address] = precompileAccepter + } + } + } + + return rules +} diff --git a/params/config_test.go b/params/config_test.go index 6123ac5525..4b665503f2 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -33,7 +33,9 @@ import ( "testing" "time" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/utils" + ethparams "github.com/ava-labs/libevm/params" ) func TestCheckCompatible(t *testing.T) { @@ -41,7 +43,7 @@ func TestCheckCompatible(t *testing.T) { stored, new *ChainConfig headBlock uint64 headTimestamp uint64 - wantErr *ConfigCompatError + wantErr *ethparams.ConfigCompatError } tests := []test{ {stored: TestChainConfig, new: TestChainConfig, headBlock: 0, headTimestamp: 0, wantErr: nil}, @@ -59,7 +61,7 @@ func TestCheckCompatible(t *testing.T) { new: &ChainConfig{HomesteadBlock: nil}, headBlock: 3, headTimestamp: 30, - wantErr: &ConfigCompatError{ + wantErr: ðparams.ConfigCompatError{ What: "Homestead fork block", StoredBlock: big.NewInt(0), NewBlock: nil, @@ -71,7 +73,7 @@ func TestCheckCompatible(t *testing.T) { new: &ChainConfig{HomesteadBlock: big.NewInt(1)}, headBlock: 3, headTimestamp: 30, - wantErr: &ConfigCompatError{ + wantErr: ðparams.ConfigCompatError{ What: "Homestead fork block", StoredBlock: big.NewInt(0), NewBlock: big.NewInt(1), @@ -83,7 +85,7 @@ func TestCheckCompatible(t *testing.T) { new: &ChainConfig{HomesteadBlock: big.NewInt(25), EIP150Block: big.NewInt(20)}, headBlock: 25, headTimestamp: 250, - wantErr: &ConfigCompatError{ + wantErr: ðparams.ConfigCompatError{ What: "EIP150 fork block", StoredBlock: big.NewInt(10), NewBlock: big.NewInt(20), @@ -102,7 +104,7 @@ func TestCheckCompatible(t *testing.T) { new: &ChainConfig{ConstantinopleBlock: big.NewInt(30), PetersburgBlock: big.NewInt(31)}, headBlock: 40, headTimestamp: 400, - wantErr: &ConfigCompatError{ + wantErr: ðparams.ConfigCompatError{ What: "Petersburg fork block", StoredBlock: nil, NewBlock: big.NewInt(31), @@ -114,7 +116,7 @@ func TestCheckCompatible(t *testing.T) { new: TestApricotPhase4Config, headBlock: 0, headTimestamp: 0, - wantErr: &ConfigCompatError{ + wantErr: ðparams.ConfigCompatError{ What: "ApricotPhase5 fork block timestamp", StoredTime: utils.NewUint64(0), NewTime: nil, @@ -126,7 +128,7 @@ func TestCheckCompatible(t *testing.T) { new: TestApricotPhase4Config, headBlock: 10, headTimestamp: 100, - wantErr: &ConfigCompatError{ + wantErr: ðparams.ConfigCompatError{ What: "ApricotPhase5 fork block timestamp", StoredTime: utils.NewUint64(0), NewTime: nil, @@ -144,21 +146,24 @@ func TestCheckCompatible(t *testing.T) { } func TestConfigRules(t *testing.T) { - c := &ChainConfig{ - NetworkUpgrades: NetworkUpgrades{ - CortinaBlockTimestamp: utils.NewUint64(500), + c := WithExtra( + &ChainConfig{}, + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + CortinaBlockTimestamp: utils.NewUint64(500), + }, }, - } + ) var stamp uint64 - if r := c.Rules(big.NewInt(0), stamp); r.IsCortina { + if r := c.Rules(big.NewInt(0), IsMergeTODO, stamp); GetRulesExtra(r).IsCortina { t.Errorf("expected %v to not be cortina", stamp) } stamp = 500 - if r := c.Rules(big.NewInt(0), stamp); !r.IsCortina { + if r := c.Rules(big.NewInt(0), IsMergeTODO, stamp); !GetRulesExtra(r).IsCortina { t.Errorf("expected %v to be cortina", stamp) } stamp = math.MaxInt64 - if r := c.Rules(big.NewInt(0), stamp); !r.IsCortina { + if r := c.Rules(big.NewInt(0), IsMergeTODO, stamp); !GetRulesExtra(r).IsCortina { t.Errorf("expected %v to be cortina", stamp) } } diff --git a/params/extras/config.go b/params/extras/config.go new file mode 100644 index 0000000000..0816bcd6a0 --- /dev/null +++ b/params/extras/config.go @@ -0,0 +1,308 @@ +// (c) 2024 Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package extras + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/common" + ethparams "github.com/ava-labs/libevm/params" +) + +var ( + TestChainConfig = &ChainConfig{ + AvalancheContext: AvalancheContext{SnowCtx: utils.TestSnowContext()}, + NetworkUpgrades: NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + ApricotPhase5BlockTimestamp: utils.NewUint64(0), + ApricotPhasePre6BlockTimestamp: utils.NewUint64(0), + ApricotPhase6BlockTimestamp: utils.NewUint64(0), + ApricotPhasePost6BlockTimestamp: utils.NewUint64(0), + BanffBlockTimestamp: utils.NewUint64(0), + CortinaBlockTimestamp: utils.NewUint64(0), + DurangoBlockTimestamp: utils.NewUint64(0), + EtnaTimestamp: utils.NewUint64(0), + FortunaTimestamp: utils.NewUint64(0), + }, + } + + TestLaunchConfig = &ChainConfig{ + AvalancheContext: AvalancheContext{SnowCtx: utils.TestSnowContext()}, + } + + TestApricotPhase1Config = copyAndSet(TestLaunchConfig, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase1BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase2Config = copyAndSet(TestApricotPhase1Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase2BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase3Config = copyAndSet(TestApricotPhase2Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase3BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase4Config = copyAndSet(TestApricotPhase3Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase4BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase5Config = copyAndSet(TestApricotPhase4Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase5BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhasePre6Config = copyAndSet(TestApricotPhase5Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhasePre6BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhase6Config = copyAndSet(TestApricotPhasePre6Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhase6BlockTimestamp = utils.NewUint64(0) + }) + + TestApricotPhasePost6Config = copyAndSet(TestApricotPhase6Config, func(c *ChainConfig) { + c.NetworkUpgrades.ApricotPhasePost6BlockTimestamp = utils.NewUint64(0) + }) + + TestBanffChainConfig = copyAndSet(TestApricotPhasePost6Config, func(c *ChainConfig) { + c.NetworkUpgrades.BanffBlockTimestamp = utils.NewUint64(0) + }) + + TestCortinaChainConfig = copyAndSet(TestBanffChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.CortinaBlockTimestamp = utils.NewUint64(0) + }) + + TestDurangoChainConfig = copyAndSet(TestCortinaChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.DurangoBlockTimestamp = utils.NewUint64(0) + }) + + TestEtnaChainConfig = copyAndSet(TestDurangoChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.EtnaTimestamp = utils.NewUint64(0) + }) + + TestFortunaChainConfig = copyAndSet(TestEtnaChainConfig, func(c *ChainConfig) { + c.NetworkUpgrades.FortunaTimestamp = utils.NewUint64(0) + }) +) + +func copyAndSet(c *ChainConfig, set func(*ChainConfig)) *ChainConfig { + newConfig := *c + set(&newConfig) + return &newConfig +} + +// UpgradeConfig includes the following configs that may be specified in upgradeBytes: +// - Timestamps that enable avalanche network upgrades, +// - Enabling or disabling precompiles as network upgrades. +type UpgradeConfig struct { + // Config for enabling and disabling precompiles as network upgrades. + PrecompileUpgrades []PrecompileUpgrade `json:"precompileUpgrades,omitempty"` +} + +// AvalancheContext provides Avalanche specific context directly into the EVM. +type AvalancheContext struct { + SnowCtx *snow.Context +} + +type ChainConfig struct { + NetworkUpgrades // Config for timestamps that enable network upgrades. + + AvalancheContext `json:"-"` // Avalanche specific context set during VM initialization. Not serialized. + + UpgradeConfig `json:"-"` // Config specified in upgradeBytes (avalanche network upgrades or enable/disabling precompiles). Not serialized. +} + +func (c *ChainConfig) CheckConfigCompatible(newcfg_ *ethparams.ChainConfig, headNumber *big.Int, headTimestamp uint64) *ethparams.ConfigCompatError { + if c == nil { + return nil + } + newcfg, ok := newcfg_.Hooks().(*ChainConfig) + if !ok { + // Proper registration of the extras on the libevm side should prevent this from happening. + // Return an error to prevent the chain from starting, just in case. + return ethparams.NewTimestampCompatError( + fmt.Sprintf("ChainConfig.Hooks() is not of the expected type *extras.ChainConfig, got %T", newcfg_.Hooks()), + utils.NewUint64(0), + nil, + ) + } + + if err := c.checkNetworkUpgradesCompatible(&newcfg.NetworkUpgrades, headTimestamp); err != nil { + return err + } + + return nil +} + +func (c *ChainConfig) Description() string { + if c == nil { + return "" + } + var banner string + + banner += "Avalanche Upgrades (timestamp based):\n" + banner += c.NetworkUpgrades.Description() + banner += "\n" + + upgradeConfigBytes, err := json.Marshal(c.UpgradeConfig) + if err != nil { + upgradeConfigBytes = []byte("cannot marshal UpgradeConfig") + } + banner += fmt.Sprintf("Upgrade Config: %s", string(upgradeConfigBytes)) + banner += "\n" + return banner +} + +// isForkTimestampIncompatible returns true if a fork scheduled at timestamp s1 +// cannot be rescheduled to timestamp s2 because head is already past the fork. +func isForkTimestampIncompatible(s1, s2 *uint64, head uint64) bool { + return (isTimestampForked(s1, head) || isTimestampForked(s2, head)) && !configTimestampEqual(s1, s2) +} + +// isTimestampForked returns whether a fork scheduled at timestamp s is active +// at the given head timestamp. +func isTimestampForked(s *uint64, head uint64) bool { + if s == nil { + return false + } + return *s <= head +} + +func configTimestampEqual(x, y *uint64) bool { + if x == nil { + return y == nil + } + if y == nil { + return x == nil + } + return *x == *y +} + +// UnmarshalJSON parses the JSON-encoded data and stores the result in the +// object pointed to by c. +// This is a custom unmarshaler to handle the Precompiles field. +// Precompiles was presented as an inline object in the JSON. +// This custom unmarshaler ensures backwards compatibility with the old format. +func (c *ChainConfig) UnmarshalJSON(data []byte) error { + // Alias ChainConfigExtra to avoid recursion + type _ChainConfigExtra ChainConfig + tmp := _ChainConfigExtra{} + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + + // At this point we have populated all fields except PrecompileUpgrade + *c = ChainConfig(tmp) + + return nil +} + +// MarshalJSON returns the JSON encoding of c. +// This is a custom marshaler to handle the Precompiles field. +func (c *ChainConfig) MarshalJSON() ([]byte, error) { + // Alias ChainConfigExtra to avoid recursion + type _ChainConfigExtra ChainConfig + return json.Marshal(_ChainConfigExtra(*c)) +} + +type fork struct { + name string + block *big.Int // some go-ethereum forks use block numbers + timestamp *uint64 // Avalanche forks use timestamps + optional bool // if true, the fork may be nil and next fork is still allowed +} + +func (c *ChainConfig) CheckConfigForkOrder() error { + if c == nil { + return nil + } + // Note: In Avalanche, upgrades must take place via block timestamps instead + // of block numbers since blocks are produced asynchronously. Therefore, we do + // not check block timestamp forks in the same way as block number forks since + // it would not be a meaningful comparison. Instead, we only check that the + // Avalanche upgrades are enabled in order. + // Note: we do not add the precompile configs here because they are optional + // and independent, i.e. the order in which they are enabled does not impact + // the correctness of the chain config. + return checkForks(c.forkOrder(), false) +} + +// checkForks checks that forks are enabled in order and returns an error if not. +// `blockFork` is true if the fork is a block number fork, false if it is a timestamp fork +func checkForks(forks []fork, blockFork bool) error { + lastFork := fork{} + for _, cur := range forks { + if lastFork.name != "" { + switch { + // Non-optional forks must all be present in the chain config up to the last defined fork + case lastFork.block == nil && lastFork.timestamp == nil && (cur.block != nil || cur.timestamp != nil): + if cur.block != nil { + return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at block %v", + lastFork.name, cur.name, cur.block) + } else { + return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at timestamp %v", + lastFork.name, cur.name, cur.timestamp) + } + + // Fork (whether defined by block or timestamp) must follow the fork definition sequence + case (lastFork.block != nil && cur.block != nil) || (lastFork.timestamp != nil && cur.timestamp != nil): + if lastFork.block != nil && lastFork.block.Cmp(cur.block) > 0 { + return fmt.Errorf("unsupported fork ordering: %v enabled at block %v, but %v enabled at block %v", + lastFork.name, lastFork.block, cur.name, cur.block) + } else if lastFork.timestamp != nil && *lastFork.timestamp > *cur.timestamp { + return fmt.Errorf("unsupported fork ordering: %v enabled at timestamp %v, but %v enabled at timestamp %v", + lastFork.name, lastFork.timestamp, cur.name, cur.timestamp) + } + + // Timestamp based forks can follow block based ones, but not the other way around + if lastFork.timestamp != nil && cur.block != nil { + return fmt.Errorf("unsupported fork ordering: %v used timestamp ordering, but %v reverted to block ordering", + lastFork.name, cur.name) + } + } + } + // If it was optional and not set, then ignore it + if !cur.optional || (cur.block != nil || cur.timestamp != nil) { + lastFork = cur + } + } + return nil +} + +// Verify verifies chain config. +func (c *ChainConfig) Verify() error { + // Verify the precompile upgrades are internally consistent given the existing chainConfig. + if err := c.verifyPrecompileUpgrades(); err != nil { + return fmt.Errorf("invalid precompile upgrades: %w", err) + } + + return nil +} + +// IsPrecompileEnabled returns whether precompile with `address` is enabled at `timestamp`. +func (c *ChainConfig) IsPrecompileEnabled(address common.Address, timestamp uint64) bool { + config := c.GetActivePrecompileConfig(address, timestamp) + return config != nil && !config.IsDisabled() +} + +// IsForkTransition returns true if `fork` activates during the transition from +// `parent` to `current`. +// Taking `parent` as a pointer allows for us to pass nil when checking forks +// that activate during genesis. +// Note: `parent` and `current` can be either both timestamp values, or both +// block number values, since this function works for both block number and +// timestamp activated forks. +func IsForkTransition(fork *uint64, parent *uint64, current uint64) bool { + var parentForked bool + if parent != nil { + parentForked = isTimestampForked(fork, *parent) + } + currentForked := isTimestampForked(fork, current) + return !parentForked && currentForked +} diff --git a/params/config_extra_test.go b/params/extras/config_extra_test.go similarity index 99% rename from params/config_extra_test.go rename to params/extras/config_extra_test.go index 64438b7f07..a94264cf31 100644 --- a/params/config_extra_test.go +++ b/params/extras/config_extra_test.go @@ -1,7 +1,7 @@ // (c) 2024 Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package params +package extras import ( "testing" diff --git a/params/network_upgrades.go b/params/extras/network_upgrades.go similarity index 82% rename from params/network_upgrades.go rename to params/extras/network_upgrades.go index 33453dfd58..066109bb35 100644 --- a/params/network_upgrades.go +++ b/params/extras/network_upgrades.go @@ -1,7 +1,7 @@ // (c) 2022, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package params +package extras import ( "fmt" @@ -9,6 +9,7 @@ import ( "github.com/ava-labs/avalanchego/upgrade" "github.com/ava-labs/coreth/utils" + ethparams "github.com/ava-labs/libevm/params" ) type NetworkUpgrades struct { @@ -50,45 +51,45 @@ func (n *NetworkUpgrades) Equal(other *NetworkUpgrades) bool { return reflect.DeepEqual(n, other) } -func (n *NetworkUpgrades) CheckNetworkUpgradesCompatible(newcfg *NetworkUpgrades, time uint64) *ConfigCompatError { +func (n *NetworkUpgrades) checkNetworkUpgradesCompatible(newcfg *NetworkUpgrades, time uint64) *ethparams.ConfigCompatError { if isForkTimestampIncompatible(n.ApricotPhase1BlockTimestamp, newcfg.ApricotPhase1BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhase1 fork block timestamp", n.ApricotPhase1BlockTimestamp, newcfg.ApricotPhase1BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhase1 fork block timestamp", n.ApricotPhase1BlockTimestamp, newcfg.ApricotPhase1BlockTimestamp) } if isForkTimestampIncompatible(n.ApricotPhase2BlockTimestamp, newcfg.ApricotPhase2BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhase2 fork block timestamp", n.ApricotPhase2BlockTimestamp, newcfg.ApricotPhase2BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhase2 fork block timestamp", n.ApricotPhase2BlockTimestamp, newcfg.ApricotPhase2BlockTimestamp) } if isForkTimestampIncompatible(n.ApricotPhase3BlockTimestamp, newcfg.ApricotPhase3BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhase3 fork block timestamp", n.ApricotPhase3BlockTimestamp, newcfg.ApricotPhase3BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhase3 fork block timestamp", n.ApricotPhase3BlockTimestamp, newcfg.ApricotPhase3BlockTimestamp) } if isForkTimestampIncompatible(n.ApricotPhase4BlockTimestamp, newcfg.ApricotPhase4BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhase4 fork block timestamp", n.ApricotPhase4BlockTimestamp, newcfg.ApricotPhase4BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhase4 fork block timestamp", n.ApricotPhase4BlockTimestamp, newcfg.ApricotPhase4BlockTimestamp) } if isForkTimestampIncompatible(n.ApricotPhase5BlockTimestamp, newcfg.ApricotPhase5BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhase5 fork block timestamp", n.ApricotPhase5BlockTimestamp, newcfg.ApricotPhase5BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhase5 fork block timestamp", n.ApricotPhase5BlockTimestamp, newcfg.ApricotPhase5BlockTimestamp) } if isForkTimestampIncompatible(n.ApricotPhasePre6BlockTimestamp, newcfg.ApricotPhasePre6BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhasePre6 fork block timestamp", n.ApricotPhasePre6BlockTimestamp, newcfg.ApricotPhasePre6BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhasePre6 fork block timestamp", n.ApricotPhasePre6BlockTimestamp, newcfg.ApricotPhasePre6BlockTimestamp) } if isForkTimestampIncompatible(n.ApricotPhase6BlockTimestamp, newcfg.ApricotPhase6BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhase6 fork block timestamp", n.ApricotPhase6BlockTimestamp, newcfg.ApricotPhase6BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhase6 fork block timestamp", n.ApricotPhase6BlockTimestamp, newcfg.ApricotPhase6BlockTimestamp) } if isForkTimestampIncompatible(n.ApricotPhasePost6BlockTimestamp, newcfg.ApricotPhasePost6BlockTimestamp, time) { - return newTimestampCompatError("ApricotPhasePost6 fork block timestamp", n.ApricotPhasePost6BlockTimestamp, newcfg.ApricotPhasePost6BlockTimestamp) + return ethparams.NewTimestampCompatError("ApricotPhasePost6 fork block timestamp", n.ApricotPhasePost6BlockTimestamp, newcfg.ApricotPhasePost6BlockTimestamp) } if isForkTimestampIncompatible(n.BanffBlockTimestamp, newcfg.BanffBlockTimestamp, time) { - return newTimestampCompatError("Banff fork block timestamp", n.BanffBlockTimestamp, newcfg.BanffBlockTimestamp) + return ethparams.NewTimestampCompatError("Banff fork block timestamp", n.BanffBlockTimestamp, newcfg.BanffBlockTimestamp) } if isForkTimestampIncompatible(n.CortinaBlockTimestamp, newcfg.CortinaBlockTimestamp, time) { - return newTimestampCompatError("Cortina fork block timestamp", n.CortinaBlockTimestamp, newcfg.CortinaBlockTimestamp) + return ethparams.NewTimestampCompatError("Cortina fork block timestamp", n.CortinaBlockTimestamp, newcfg.CortinaBlockTimestamp) } if isForkTimestampIncompatible(n.DurangoBlockTimestamp, newcfg.DurangoBlockTimestamp, time) { - return newTimestampCompatError("Durango fork block timestamp", n.DurangoBlockTimestamp, newcfg.DurangoBlockTimestamp) + return ethparams.NewTimestampCompatError("Durango fork block timestamp", n.DurangoBlockTimestamp, newcfg.DurangoBlockTimestamp) } if isForkTimestampIncompatible(n.EtnaTimestamp, newcfg.EtnaTimestamp, time) { - return newTimestampCompatError("Etna fork block timestamp", n.EtnaTimestamp, newcfg.EtnaTimestamp) + return ethparams.NewTimestampCompatError("Etna fork block timestamp", n.EtnaTimestamp, newcfg.EtnaTimestamp) } if isForkTimestampIncompatible(n.FortunaTimestamp, newcfg.FortunaTimestamp, time) { - return newTimestampCompatError("Fortuna fork block timestamp", n.FortunaTimestamp, newcfg.FortunaTimestamp) + return ethparams.NewTimestampCompatError("Fortuna fork block timestamp", n.FortunaTimestamp, newcfg.FortunaTimestamp) } return nil @@ -114,13 +115,13 @@ func (n *NetworkUpgrades) forkOrder() []fork { // IsApricotPhase1 returns whether [time] represents a block // with a timestamp after the Apricot Phase 1 upgrade time. -func (n *NetworkUpgrades) IsApricotPhase1(time uint64) bool { +func (n NetworkUpgrades) IsApricotPhase1(time uint64) bool { return isTimestampForked(n.ApricotPhase1BlockTimestamp, time) } // IsApricotPhase2 returns whether [time] represents a block // with a timestamp after the Apricot Phase 2 upgrade time. -func (n *NetworkUpgrades) IsApricotPhase2(time uint64) bool { +func (n NetworkUpgrades) IsApricotPhase2(time uint64) bool { return isTimestampForked(n.ApricotPhase2BlockTimestamp, time) } @@ -132,55 +133,55 @@ func (n *NetworkUpgrades) IsApricotPhase3(time uint64) bool { // IsApricotPhase4 returns whether [time] represents a block // with a timestamp after the Apricot Phase 4 upgrade time. -func (n *NetworkUpgrades) IsApricotPhase4(time uint64) bool { +func (n NetworkUpgrades) IsApricotPhase4(time uint64) bool { return isTimestampForked(n.ApricotPhase4BlockTimestamp, time) } // IsApricotPhase5 returns whether [time] represents a block // with a timestamp after the Apricot Phase 5 upgrade time. -func (n *NetworkUpgrades) IsApricotPhase5(time uint64) bool { +func (n NetworkUpgrades) IsApricotPhase5(time uint64) bool { return isTimestampForked(n.ApricotPhase5BlockTimestamp, time) } // IsApricotPhasePre6 returns whether [time] represents a block // with a timestamp after the Apricot Phase Pre 6 upgrade time. -func (n *NetworkUpgrades) IsApricotPhasePre6(time uint64) bool { +func (n NetworkUpgrades) IsApricotPhasePre6(time uint64) bool { return isTimestampForked(n.ApricotPhasePre6BlockTimestamp, time) } // IsApricotPhase6 returns whether [time] represents a block // with a timestamp after the Apricot Phase 6 upgrade time. -func (n *NetworkUpgrades) IsApricotPhase6(time uint64) bool { +func (n NetworkUpgrades) IsApricotPhase6(time uint64) bool { return isTimestampForked(n.ApricotPhase6BlockTimestamp, time) } // IsApricotPhasePost6 returns whether [time] represents a block // with a timestamp after the Apricot Phase 6 Post upgrade time. -func (n *NetworkUpgrades) IsApricotPhasePost6(time uint64) bool { +func (n NetworkUpgrades) IsApricotPhasePost6(time uint64) bool { return isTimestampForked(n.ApricotPhasePost6BlockTimestamp, time) } // IsBanff returns whether [time] represents a block // with a timestamp after the Banff upgrade time. -func (n *NetworkUpgrades) IsBanff(time uint64) bool { +func (n NetworkUpgrades) IsBanff(time uint64) bool { return isTimestampForked(n.BanffBlockTimestamp, time) } // IsCortina returns whether [time] represents a block // with a timestamp after the Cortina upgrade time. -func (n *NetworkUpgrades) IsCortina(time uint64) bool { +func (n NetworkUpgrades) IsCortina(time uint64) bool { return isTimestampForked(n.CortinaBlockTimestamp, time) } // IsDurango returns whether [time] represents a block // with a timestamp after the Durango upgrade time. -func (n *NetworkUpgrades) IsDurango(time uint64) bool { +func (n NetworkUpgrades) IsDurango(time uint64) bool { return isTimestampForked(n.DurangoBlockTimestamp, time) } // IsEtna returns whether [time] represents a block // with a timestamp after the Etna upgrade time. -func (n *NetworkUpgrades) IsEtna(time uint64) bool { +func (n NetworkUpgrades) IsEtna(time uint64) bool { return isTimestampForked(n.EtnaTimestamp, time) } @@ -190,7 +191,7 @@ func (n *NetworkUpgrades) IsFortuna(time uint64) bool { return isTimestampForked(n.FortunaTimestamp, time) } -func (n *NetworkUpgrades) Description() string { +func (n NetworkUpgrades) Description() string { var banner string banner += fmt.Sprintf(" - Apricot Phase 1 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.3.0)\n", ptrToString(n.ApricotPhase1BlockTimestamp)) banner += fmt.Sprintf(" - Apricot Phase 2 Timestamp: @%-10v (https://github.com/ava-labs/avalanchego/releases/tag/v1.4.0)\n", ptrToString(n.ApricotPhase2BlockTimestamp)) @@ -253,3 +254,10 @@ func (n *NetworkUpgrades) GetAvalancheRules(timestamp uint64) AvalancheRules { IsFortuna: n.IsFortuna(timestamp), } } + +func ptrToString(val *uint64) string { + if val == nil { + return "nil" + } + return fmt.Sprintf("%d", *val) +} diff --git a/params/precompile_upgrade.go b/params/extras/precompile_upgrade.go similarity index 91% rename from params/precompile_upgrade.go rename to params/extras/precompile_upgrade.go index 4ae5377145..7e216530bf 100644 --- a/params/precompile_upgrade.go +++ b/params/extras/precompile_upgrade.go @@ -1,7 +1,7 @@ // (c) 2023 Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package params +package extras import ( "encoding/json" @@ -11,7 +11,8 @@ import ( "github.com/ava-labs/coreth/precompile/modules" "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + ethparams "github.com/ava-labs/libevm/params" ) var errNoKey = errors.New("PrecompileUpgrade cannot be empty") @@ -131,9 +132,9 @@ func (c *ChainConfig) verifyPrecompileUpgrades() error { return nil } -// getActivePrecompileConfig returns the most recent precompile config corresponding to [address]. +// GetActivePrecompileConfig returns the most recent precompile config corresponding to [address]. // If none have occurred, returns nil. -func (c *ChainConfig) getActivePrecompileConfig(address common.Address, timestamp uint64) precompileconfig.Config { +func (c *ChainConfig) GetActivePrecompileConfig(address common.Address, timestamp uint64) precompileconfig.Config { configs := c.GetActivatingPrecompileConfigs(address, nil, timestamp, c.PrecompileUpgrades) if len(configs) == 0 { return nil @@ -163,14 +164,16 @@ func (c *ChainConfig) GetActivatingPrecompileConfigs(address common.Address, fro return configs } -// CheckPrecompilesCompatible checks if [precompileUpgrades] are compatible with [c] at [headTimestamp]. +// checkPrecompilesCompatible checks if [precompileUpgrades] are compatible with [c] at [headTimestamp]. // Returns a ConfigCompatError if upgrades already activated at [headTimestamp] are missing from // [precompileUpgrades]. Upgrades not already activated may be modified or absent from [precompileUpgrades]. // Returns nil if [precompileUpgrades] is compatible with [c]. // Assumes given timestamp is the last accepted block timestamp. // This ensures that as long as the node has not accepted a block with a different rule set it will allow a // new upgrade to be applied as long as it activates after the last accepted block. -func (c *ChainConfig) CheckPrecompilesCompatible(precompileUpgrades []PrecompileUpgrade, time uint64) *ConfigCompatError { +// +//nolint:unused +func (c *ChainConfig) checkPrecompilesCompatible(precompileUpgrades []PrecompileUpgrade, time uint64) *ethparams.ConfigCompatError { for _, module := range modules.RegisteredModules() { if err := c.checkPrecompileCompatible(module.Address, precompileUpgrades, time); err != nil { return err @@ -184,7 +187,9 @@ func (c *ChainConfig) CheckPrecompilesCompatible(precompileUpgrades []Precompile // and [precompileUpgrades] at [headTimestamp]. // Returns an error if upgrades already activated at [headTimestamp] are missing from [precompileUpgrades]. // Upgrades that have already gone into effect cannot be modified or absent from [precompileUpgrades]. -func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompileUpgrades []PrecompileUpgrade, time uint64) *ConfigCompatError { +// +//nolint:unused +func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompileUpgrades []PrecompileUpgrade, time uint64) *ethparams.ConfigCompatError { // All active upgrades (from nil to [lastTimestamp]) must match. activeUpgrades := c.GetActivatingPrecompileConfigs(address, nil, time, c.PrecompileUpgrades) newUpgrades := c.GetActivatingPrecompileConfigs(address, nil, time, precompileUpgrades) @@ -193,7 +198,7 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi for i, upgrade := range activeUpgrades { if len(newUpgrades) <= i { // missing upgrade - return newTimestampCompatError( + return ethparams.NewTimestampCompatError( fmt.Sprintf("missing PrecompileUpgrade[%d]", i), upgrade.Timestamp(), nil, @@ -201,7 +206,7 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi } // All upgrades that have activated must be identical. if !upgrade.Equal(newUpgrades[i]) { - return newTimestampCompatError( + return ethparams.NewTimestampCompatError( fmt.Sprintf("PrecompileUpgrade[%d]", i), upgrade.Timestamp(), newUpgrades[i].Timestamp(), @@ -211,7 +216,7 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi // then, make sure newUpgrades does not have additional upgrades // that are already activated. (cannot perform retroactive upgrade) if len(newUpgrades) > len(activeUpgrades) { - return newTimestampCompatError( + return ethparams.NewTimestampCompatError( fmt.Sprintf("cannot retroactively enable PrecompileUpgrade[%d]", len(activeUpgrades)), nil, newUpgrades[len(activeUpgrades)].Timestamp(), // this indexes to the first element in newUpgrades after the end of activeUpgrades @@ -225,7 +230,7 @@ func (c *ChainConfig) checkPrecompileCompatible(address common.Address, precompi func (c *ChainConfig) EnabledStatefulPrecompiles(blockTimestamp uint64) Precompiles { statefulPrecompileConfigs := make(Precompiles) for _, module := range modules.RegisteredModules() { - if config := c.getActivePrecompileConfig(module.Address, blockTimestamp); config != nil && !config.IsDisabled() { + if config := c.GetActivePrecompileConfig(module.Address, blockTimestamp); config != nil && !config.IsDisabled() { statefulPrecompileConfigs[module.ConfigKey] = config } } diff --git a/params/precompiles.go b/params/extras/precompiles.go similarity index 98% rename from params/precompiles.go rename to params/extras/precompiles.go index 9b47b219fd..10bbd1161a 100644 --- a/params/precompiles.go +++ b/params/extras/precompiles.go @@ -1,7 +1,7 @@ // (c) 2023 Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package params +package extras import ( "encoding/json" diff --git a/params/extras/rules.go b/params/extras/rules.go new file mode 100644 index 0000000000..237cc791a7 --- /dev/null +++ b/params/extras/rules.go @@ -0,0 +1,41 @@ +// (c) 2024 Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package extras + +import ( + "github.com/ava-labs/coreth/precompile/precompileconfig" + "github.com/ava-labs/libevm/common" +) + +type Rules struct { + // Rules for Avalanche releases + AvalancheRules + + // Precompiles maps addresses to stateful precompiled contracts that are enabled + // for this rule set. + // Note: none of these addresses should conflict with the address space used by + // any existing precompiles. + Precompiles map[common.Address]precompileconfig.Config + // Predicaters maps addresses to stateful precompile Predicaters + // that are enabled for this rule set. + Predicaters map[common.Address]precompileconfig.Predicater + // AccepterPrecompiles map addresses to stateful precompile accepter functions + // that are enabled for this rule set. + AccepterPrecompiles map[common.Address]precompileconfig.Accepter +} + +func (r *Rules) PredicatersExist() bool { + return len(r.Predicaters) > 0 +} + +func (r *Rules) PredicaterExists(addr common.Address) bool { + _, ok := r.Predicaters[addr] + return ok +} + +// IsPrecompileEnabled returns true if the precompile at `addr` is enabled for this rule set. +func (r *Rules) IsPrecompileEnabled(addr common.Address) bool { + _, ok := r.Precompiles[addr] + return ok +} diff --git a/params/hooks_libevm.go b/params/hooks_libevm.go new file mode 100644 index 0000000000..af7e24a25f --- /dev/null +++ b/params/hooks_libevm.go @@ -0,0 +1,201 @@ +// (c) 2024-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package params + +import ( + "maps" + "math/big" + "slices" + + "github.com/ava-labs/avalanchego/snow" + "github.com/ava-labs/coreth/nativeasset" + "github.com/ava-labs/coreth/params/extras" + customheader "github.com/ava-labs/coreth/plugin/evm/header" + "github.com/ava-labs/coreth/precompile/contract" + "github.com/ava-labs/coreth/precompile/modules" + "github.com/ava-labs/coreth/precompile/precompileconfig" + "github.com/ava-labs/coreth/predicate" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/libevm" + "github.com/ava-labs/libevm/libevm/legacy" +) + +type RulesExtra extras.Rules + +func GetRulesExtra(r Rules) *extras.Rules { + rules := payloads.Rules.GetPointer(&r) + return (*extras.Rules)(rules) +} + +func (r RulesExtra) CanCreateContract(ac *libevm.AddressContext, gas uint64, state libevm.StateReader) (uint64, error) { + return gas, nil +} + +func (r RulesExtra) CanExecuteTransaction(_ common.Address, _ *common.Address, _ libevm.StateReader) error { + return nil +} + +var PrecompiledContractsApricotPhase2 = map[common.Address]contract.StatefulPrecompiledContract{ + nativeasset.GenesisContractAddr: &nativeasset.DeprecatedContract{}, + nativeasset.NativeAssetBalanceAddr: &nativeasset.NativeAssetBalance{GasCost: AssetBalanceApricot}, + nativeasset.NativeAssetCallAddr: &nativeasset.NativeAssetCall{GasCost: AssetCallApricot, CallNewAccountGas: CallNewAccountGas}, +} + +var PrecompiledContractsApricotPhasePre6 = map[common.Address]contract.StatefulPrecompiledContract{ + nativeasset.GenesisContractAddr: &nativeasset.DeprecatedContract{}, + nativeasset.NativeAssetBalanceAddr: &nativeasset.DeprecatedContract{}, + nativeasset.NativeAssetCallAddr: &nativeasset.DeprecatedContract{}, +} + +var PrecompiledContractsApricotPhase6 = map[common.Address]contract.StatefulPrecompiledContract{ + nativeasset.GenesisContractAddr: &nativeasset.DeprecatedContract{}, + nativeasset.NativeAssetBalanceAddr: &nativeasset.NativeAssetBalance{GasCost: AssetBalanceApricot}, + nativeasset.NativeAssetCallAddr: &nativeasset.NativeAssetCall{GasCost: AssetCallApricot, CallNewAccountGas: CallNewAccountGas}, +} + +var PrecompiledContractsBanff = map[common.Address]contract.StatefulPrecompiledContract{ + nativeasset.GenesisContractAddr: &nativeasset.DeprecatedContract{}, + nativeasset.NativeAssetBalanceAddr: &nativeasset.DeprecatedContract{}, + nativeasset.NativeAssetCallAddr: &nativeasset.DeprecatedContract{}, +} + +func (r RulesExtra) ActivePrecompiles(existing []common.Address) []common.Address { + var precompiles map[common.Address]contract.StatefulPrecompiledContract + switch { + case r.IsBanff: + precompiles = PrecompiledContractsBanff + case r.IsApricotPhase6: + precompiles = PrecompiledContractsApricotPhase6 + case r.IsApricotPhasePre6: + precompiles = PrecompiledContractsApricotPhasePre6 + case r.IsApricotPhase2: + precompiles = PrecompiledContractsApricotPhase2 + } + + var addresses []common.Address + addresses = slices.AppendSeq(addresses, maps.Keys(precompiles)) + addresses = append(addresses, existing...) + return addresses +} + +// precompileOverrideBuiltin specifies precompiles that were activated prior to the +// dynamic precompile activation registry. +// These were only active historically and are not active in the current network. +func (r RulesExtra) precompileOverrideBuiltin(addr common.Address) (libevm.PrecompiledContract, bool) { + var precompiles map[common.Address]contract.StatefulPrecompiledContract + switch { + case r.IsBanff: + precompiles = PrecompiledContractsBanff + case r.IsApricotPhase6: + precompiles = PrecompiledContractsApricotPhase6 + case r.IsApricotPhasePre6: + precompiles = PrecompiledContractsApricotPhasePre6 + case r.IsApricotPhase2: + precompiles = PrecompiledContractsApricotPhase2 + } + + precompile, ok := precompiles[addr] + if !ok { + return nil, false + } + + return makePrecompile(precompile), true +} + +func makePrecompile(contract contract.StatefulPrecompiledContract) libevm.PrecompiledContract { + run := func(env vm.PrecompileEnvironment, input []byte, suppliedGas uint64) ([]byte, uint64, error) { + header, err := env.BlockHeader() + if err != nil { + panic(err) // Should never happen + } + var predicateResults *predicate.Results + rules := GetRulesExtra(env.Rules()).AvalancheRules + if predicateResultsBytes := customheader.PredicateBytesFromExtra(rules, header.Extra); len(predicateResultsBytes) > 0 { + predicateResults, err = predicate.ParseResults(predicateResultsBytes) + if err != nil { + panic(err) // Should never happen, as results are already validated in block validation + } + } + accessibleState := accessibleState{ + env: env, + blockContext: &precompileBlockContext{ + number: env.BlockNumber(), + time: env.BlockTime(), + predicateResults: predicateResults, + }, + } + return contract.Run(accessibleState, env.Addresses().Caller, env.Addresses().Self, input, suppliedGas, env.ReadOnly()) + } + return vm.NewStatefulPrecompile(legacy.PrecompiledStatefulContract(run).Upgrade()) +} + +func (r RulesExtra) PrecompileOverride(addr common.Address) (libevm.PrecompiledContract, bool) { + if p, ok := r.precompileOverrideBuiltin(addr); ok { + return p, true + } + if _, ok := r.Precompiles[addr]; !ok { + return nil, false + } + module, ok := modules.GetPrecompileModuleByAddress(addr) + if !ok { + return nil, false + } + + return makePrecompile(module.Contract), true +} + +type accessibleState struct { + env vm.PrecompileEnvironment + blockContext *precompileBlockContext +} + +func (a accessibleState) GetStateDB() contract.StateDB { + // TODO the contracts should be refactored to call `env.ReadOnlyState` + // or `env.StateDB` based on the env.ReadOnly() flag + var state libevm.StateReader + if a.env.ReadOnly() { + state = a.env.ReadOnlyState() + } else { + state = a.env.StateDB() + } + return state.(contract.StateDB) +} + +func (a accessibleState) GetBlockContext() contract.BlockContext { + return a.blockContext +} + +func (a accessibleState) GetChainConfig() precompileconfig.ChainConfig { + return GetExtra(a.env.ChainConfig()) +} + +func (a accessibleState) GetSnowContext() *snow.Context { + return GetExtra(a.env.ChainConfig()).SnowCtx +} + +func (a accessibleState) GetPrecompileEnv() vm.PrecompileEnvironment { + return a.env +} + +type precompileBlockContext struct { + number *big.Int + time uint64 + predicateResults *predicate.Results +} + +func (p *precompileBlockContext) Number() *big.Int { + return p.number +} + +func (p *precompileBlockContext) Timestamp() uint64 { + return p.time +} + +func (p *precompileBlockContext) GetPredicateResults(txHash common.Hash, precompileAddress common.Address) []byte { + if p.predicateResults == nil { + return nil + } + return p.predicateResults.GetPredicateResults(txHash, precompileAddress) +} diff --git a/params/protocol_params.go b/params/protocol_params.go index a09de7025c..1d8ed7f9e1 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -29,18 +29,12 @@ package params import ( "math/big" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) const ( - GasLimitBoundDivisor uint64 = 1024 // The bound divisor of the gas limit, used in update calculations. - MinGasLimit uint64 = 5000 // Minimum the gas limit may ever be. - MaxGasLimit uint64 = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). - GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. - - // Note: MaximumExtraDataSize has been reduced to 32 in Geth, but is kept the same in Coreth for - // backwards compatibility. - MaximumExtraDataSize uint64 = 64 // Maximum size extra data may be after Genesis. + GenesisGasLimit uint64 = 4712388 // Gas limit of the Genesis block. + ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero. diff --git a/peer/network.go b/peer/network.go index a4dfd015f6..7ce1203b45 100644 --- a/peer/network.go +++ b/peer/network.go @@ -12,7 +12,7 @@ import ( "golang.org/x/sync/semaphore" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" diff --git a/peer/peer_tracker.go b/peer/peer_tracker.go index 30f73d854d..c529dc1e32 100644 --- a/peer/peer_tracker.go +++ b/peer/peer_tracker.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/version" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" ) diff --git a/plugin/evm/admin.go b/plugin/evm/admin.go index 34595a0b0e..bd3308e7ee 100644 --- a/plugin/evm/admin.go +++ b/plugin/evm/admin.go @@ -10,7 +10,7 @@ import ( "github.com/ava-labs/avalanchego/api" "github.com/ava-labs/avalanchego/utils/profiler" "github.com/ava-labs/coreth/plugin/evm/client" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) // Admin is the API service for admin API calls diff --git a/plugin/evm/api.go b/plugin/evm/api.go index bfeed5619d..079699cfb9 100644 --- a/plugin/evm/api.go +++ b/plugin/evm/api.go @@ -18,8 +18,8 @@ import ( "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/plugin/evm/client" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) // test constants diff --git a/plugin/evm/atomic/export_tx.go b/plugin/evm/atomic/export_tx.go index 34a4594841..d10979152a 100644 --- a/plugin/evm/atomic/export_tx.go +++ b/plugin/evm/atomic/export_tx.go @@ -9,7 +9,7 @@ import ( "fmt" "math/big" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/holiman/uint256" @@ -26,8 +26,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) var ( @@ -75,7 +75,7 @@ func (utx *UnsignedExportTx) InputUTXOs() set.Set[ids.ID] { // Verify this transaction is well-formed func (utx *UnsignedExportTx) Verify( ctx *snow.Context, - rules params.Rules, + rules extras.Rules, ) error { switch { case utx == nil: @@ -287,7 +287,7 @@ func (utx *UnsignedExportTx) AtomicOps() (ids.ID, *atomic.Requests, error) { // NewExportTx returns a new ExportTx func NewExportTx( ctx *snow.Context, - rules params.Rules, + rules extras.Rules, state StateDB, assetID ids.ID, // AssetID of the tokens to export amount uint64, // Amount of tokens to export diff --git a/plugin/evm/atomic/import_tx.go b/plugin/evm/atomic/import_tx.go index 03f7655c3b..a2b97a406b 100644 --- a/plugin/evm/atomic/import_tx.go +++ b/plugin/evm/atomic/import_tx.go @@ -10,7 +10,7 @@ import ( "math/big" "slices" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/holiman/uint256" @@ -25,8 +25,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/components/verify" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) var ( @@ -74,7 +74,7 @@ func (utx *UnsignedImportTx) InputUTXOs() set.Set[ids.ID] { // Verify this transaction is well-formed func (utx *UnsignedImportTx) Verify( ctx *snow.Context, - rules params.Rules, + rules extras.Rules, ) error { switch { case utx == nil: @@ -291,7 +291,7 @@ func (utx *UnsignedImportTx) AtomicOps() (ids.ID, *atomic.Requests, error) { // NewImportTx returns a new ImportTx func NewImportTx( ctx *snow.Context, - rules params.Rules, + rules extras.Rules, time uint64, chainID ids.ID, // chain to import from to common.Address, // Address of recipient diff --git a/plugin/evm/atomic/mempool.go b/plugin/evm/atomic/mempool.go index 83e668077b..4754b070c9 100644 --- a/plugin/evm/atomic/mempool.go +++ b/plugin/evm/atomic/mempool.go @@ -15,8 +15,8 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/coreth/plugin/evm/config" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/log" ) const ( diff --git a/plugin/evm/atomic/params.go b/plugin/evm/atomic/params.go new file mode 100644 index 0000000000..b154d0bfc0 --- /dev/null +++ b/plugin/evm/atomic/params.go @@ -0,0 +1,13 @@ +// (c) 2025 Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package atomic + +import "github.com/ava-labs/avalanchego/utils/units" + +const ( + AvalancheAtomicTxFee = units.MilliAvax + + // The base cost to charge per atomic transaction. Added in Apricot Phase 5. + AtomicTxBaseCost uint64 = 10_000 +) diff --git a/plugin/evm/atomic/test_tx.go b/plugin/evm/atomic/test_tx.go index 71437ea41e..de23a8b09e 100644 --- a/plugin/evm/atomic/test_tx.go +++ b/plugin/evm/atomic/test_tx.go @@ -16,7 +16,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" ) var TestTxCodec codec.Manager @@ -56,7 +56,7 @@ var _ UnsignedAtomicTx = &TestUnsignedTx{} func (t *TestUnsignedTx) GasUsed(fixedFee bool) (uint64, error) { return t.GasUsedV, nil } // Verify implements the UnsignedAtomicTx interface -func (t *TestUnsignedTx) Verify(ctx *snow.Context, rules params.Rules) error { return t.VerifyV } +func (t *TestUnsignedTx) Verify(ctx *snow.Context, rules extras.Rules) error { return t.VerifyV } // AtomicOps implements the UnsignedAtomicTx interface func (t *TestUnsignedTx) AtomicOps() (ids.ID, *avalancheatomic.Requests, error) { diff --git a/plugin/evm/atomic/tx.go b/plugin/evm/atomic/tx.go index e3258ef18f..30791e4000 100644 --- a/plugin/evm/atomic/tx.go +++ b/plugin/evm/atomic/tx.go @@ -11,10 +11,10 @@ import ( "math/big" "sort" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/holiman/uint256" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/avalanchego/chains/atomic" "github.com/ava-labs/avalanchego/codec" @@ -130,7 +130,7 @@ type UnsignedTx interface { type Backend struct { Ctx *snow.Context Fx fx.Fx - Rules params.Rules + Rules extras.Rules Bootstrapped bool BlockFetcher BlockFetcher SecpCache *secp256k1.RecoverCache @@ -167,7 +167,7 @@ type UnsignedAtomicTx interface { // InputUTXOs returns the UTXOs this tx consumes InputUTXOs() set.Set[ids.ID] // Verify attempts to verify that the transaction is well formed - Verify(ctx *snow.Context, rules params.Rules) error + Verify(ctx *snow.Context, rules extras.Rules) error // Attempts to verify this transaction with the provided state. // SemanticVerify this transaction is valid. SemanticVerify(backend *Backend, stx *Tx, parent AtomicBlockContext, baseFee *big.Int) error diff --git a/plugin/evm/atomic_backend.go b/plugin/evm/atomic_backend.go index 45afa707f2..35388b0689 100644 --- a/plugin/evm/atomic_backend.go +++ b/plugin/evm/atomic_backend.go @@ -17,8 +17,8 @@ import ( "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/coreth/plugin/evm/atomic" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) var _ AtomicBackend = &atomicBackend{} diff --git a/plugin/evm/atomic_state.go b/plugin/evm/atomic_state.go index 911f1afb3a..7647a4cbab 100644 --- a/plugin/evm/atomic_state.go +++ b/plugin/evm/atomic_state.go @@ -10,8 +10,8 @@ import ( "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/coreth/plugin/evm/atomic" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) var _ AtomicState = &atomicState{} diff --git a/plugin/evm/atomic_syncer.go b/plugin/evm/atomic_syncer.go index 8c435690c0..7c25da5539 100644 --- a/plugin/evm/atomic_syncer.go +++ b/plugin/evm/atomic_syncer.go @@ -12,11 +12,11 @@ import ( "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/ava-labs/coreth/plugin/evm/message" syncclient "github.com/ava-labs/coreth/sync/client" - "github.com/ava-labs/coreth/trie" + "github.com/ava-labs/libevm/trie" ) var ( diff --git a/plugin/evm/atomic_syncer_test.go b/plugin/evm/atomic_syncer_test.go index 3feffe444c..584a5feecc 100644 --- a/plugin/evm/atomic_syncer_test.go +++ b/plugin/evm/atomic_syncer_test.go @@ -16,16 +16,16 @@ import ( "github.com/ava-labs/avalanchego/database/memdb" "github.com/ava-labs/avalanchego/database/versiondb" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/plugin/evm/config" "github.com/ava-labs/coreth/plugin/evm/message" syncclient "github.com/ava-labs/coreth/sync/client" "github.com/ava-labs/coreth/sync/handlers" handlerstats "github.com/ava-labs/coreth/sync/handlers/stats" "github.com/ava-labs/coreth/sync/syncutils" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" ) const commitInterval = 1024 diff --git a/plugin/evm/atomic_trie.go b/plugin/evm/atomic_trie.go index 2ef09a7f32..9fa4a81a46 100644 --- a/plugin/evm/atomic_trie.go +++ b/plugin/evm/atomic_trie.go @@ -14,17 +14,17 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/plugin/evm/database" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/triedb/hashdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/triedb" ) const ( @@ -153,9 +153,9 @@ func newAtomicTrie( trieDB := triedb.NewDatabase( rawdb.NewDatabase(database.WrapDatabase(atomicTrieDB)), &triedb.Config{ - HashDB: &hashdb.Config{ + DBOverride: hashdb.Config{ CleanCacheSize: 64 * units.MiB, // Allocate 64MB of memory for clean cache - }, + }.BackendConstructor, }, ) diff --git a/plugin/evm/atomic_trie_iterator.go b/plugin/evm/atomic_trie_iterator.go index 2bdf90b581..6fd636d744 100644 --- a/plugin/evm/atomic_trie_iterator.go +++ b/plugin/evm/atomic_trie_iterator.go @@ -12,8 +12,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/trie" ) const atomicTrieKeyLen = wrappers.LongLen + common.HashLength diff --git a/plugin/evm/atomic_trie_iterator_test.go b/plugin/evm/atomic_trie_iterator_test.go index 21ec9913f9..8da2e03127 100644 --- a/plugin/evm/atomic_trie_iterator_test.go +++ b/plugin/evm/atomic_trie_iterator_test.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/coreth/plugin/evm/atomic" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/plugin/evm/atomic_trie_test.go b/plugin/evm/atomic_trie_test.go index 1a065d4530..03c2c20d2f 100644 --- a/plugin/evm/atomic_trie_test.go +++ b/plugin/evm/atomic_trie_test.go @@ -22,12 +22,12 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/atomic" - "github.com/ava-labs/coreth/trie/trienode" + "github.com/ava-labs/libevm/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie/trienode" ) const testCommitInterval = 100 diff --git a/plugin/evm/atomic_tx_repository.go b/plugin/evm/atomic_tx_repository.go index d1074f60f2..08c4c4d5c4 100644 --- a/plugin/evm/atomic_tx_repository.go +++ b/plugin/evm/atomic_tx_repository.go @@ -8,8 +8,8 @@ import ( "fmt" "time" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/database" diff --git a/plugin/evm/atomic_tx_repository_test.go b/plugin/evm/atomic_tx_repository_test.go index 224f8fa726..9c5616004b 100644 --- a/plugin/evm/atomic_tx_repository_test.go +++ b/plugin/evm/atomic_tx_repository_test.go @@ -13,7 +13,7 @@ import ( "github.com/ava-labs/avalanchego/database/versiondb" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/coreth/plugin/evm/atomic" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/utils/set" diff --git a/plugin/evm/block.go b/plugin/evm/block.go index 042ff22703..d9ed019cf0 100644 --- a/plugin/evm/block.go +++ b/plugin/evm/block.go @@ -10,18 +10,20 @@ import ( "fmt" "time" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/atomic" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/predicate" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/consensus/snowman" @@ -119,8 +121,8 @@ type Block struct { // newBlock returns a new Block wrapping the ethBlock type and implementing the snowman.Block interface func (vm *VM) newBlock(ethBlock *types.Block) (*Block, error) { - isApricotPhase5 := vm.chainConfig.IsApricotPhase5(ethBlock.Time()) - atomicTxs, err := atomic.ExtractAtomicTxs(ethBlock.ExtData(), isApricotPhase5, atomic.Codec) + isApricotPhase5 := vm.chainConfigExtra().IsApricotPhase5(ethBlock.Time()) + atomicTxs, err := atomic.ExtractAtomicTxs(customtypes.BlockExtData(ethBlock), isApricotPhase5, atomic.Codec) if err != nil { return nil, err } @@ -151,7 +153,7 @@ func (b *Block) Accept(context.Context) error { // Call Accept for relevant precompile logs. Note we do this prior to // calling Accept on the blockChain so any side effects (eg warp signatures) // take place before the accepted log is emitted to subscribers. - rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), b.ethBlock.Timestamp()) + rules := b.vm.rules(b.ethBlock.Number(), b.ethBlock.Time()) if err := b.handlePrecompileAccept(rules); err != nil { return err } @@ -189,7 +191,7 @@ func (b *Block) Accept(context.Context) error { // handlePrecompileAccept calls Accept on any logs generated with an active precompile address that implements // contract.Accepter -func (b *Block) handlePrecompileAccept(rules params.Rules) error { +func (b *Block) handlePrecompileAccept(rules extras.Rules) error { // Short circuit early if there are no precompile accepters to execute if len(rules.AccepterPrecompiles) == 0 { return nil @@ -265,7 +267,7 @@ func (b *Block) syntacticVerify() error { } header := b.ethBlock.Header() - rules := b.vm.chainConfig.Rules(header.Number, header.Time) + rules := b.vm.chainConfig.Rules(header.Number, params.IsMergeTODO, header.Time) return b.vm.syntacticBlockValidator.SyntacticVerify(b, rules) } @@ -279,7 +281,8 @@ func (b *Block) Verify(context.Context) error { // ShouldVerifyWithContext implements the block.WithVerifyContext interface func (b *Block) ShouldVerifyWithContext(context.Context) (bool, error) { - predicates := b.vm.chainConfig.Rules(b.ethBlock.Number(), b.ethBlock.Timestamp()).Predicaters + rules := b.vm.rules(b.ethBlock.Number(), b.ethBlock.Time()) + predicates := rules.Predicaters // Short circuit early if there are no predicates to verify if len(predicates) == 0 { return false, nil @@ -359,12 +362,13 @@ func (b *Block) verify(predicateContext *precompileconfig.PredicateContext, writ // verifyPredicates verifies the predicates in the block are valid according to predicateContext. func (b *Block) verifyPredicates(predicateContext *precompileconfig.PredicateContext) error { - rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), b.ethBlock.Timestamp()) + rules := b.vm.chainConfig.Rules(b.ethBlock.Number(), params.IsMergeTODO, b.ethBlock.Time()) + rulesExtra := params.GetRulesExtra(rules) switch { - case !rules.IsDurango && rules.PredicatersExist(): + case !rulesExtra.IsDurango && rulesExtra.PredicatersExist(): return errors.New("cannot enable predicates before Durango activation") - case !rules.IsDurango: + case !rulesExtra.IsDurango: return nil } @@ -382,7 +386,8 @@ func (b *Block) verifyPredicates(predicateContext *precompileconfig.PredicateCon return fmt.Errorf("failed to marshal predicate results: %w", err) } extraData := b.ethBlock.Extra() - headerPredicateResultsBytes := header.PredicateBytesFromExtra(rules.AvalancheRules, extraData) + avalancheRules := rulesExtra.AvalancheRules + headerPredicateResultsBytes := header.PredicateBytesFromExtra(avalancheRules, extraData) if !bytes.Equal(headerPredicateResultsBytes, predicateResultsBytes) { return fmt.Errorf("%w (remote: %x local: %x)", errInvalidHeaderPredicateResults, headerPredicateResultsBytes, predicateResultsBytes) } diff --git a/plugin/evm/block_builder.go b/plugin/evm/block_builder.go index 721561ff40..c621c7ff1b 100644 --- a/plugin/evm/block_builder.go +++ b/plugin/evm/block_builder.go @@ -16,7 +16,7 @@ import ( "github.com/ava-labs/avalanchego/snow" commonEng "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) const ( diff --git a/plugin/evm/block_verification.go b/plugin/evm/block_verification.go index 3bc08fd8f9..6014f4fbad 100644 --- a/plugin/evm/block_verification.go +++ b/plugin/evm/block_verification.go @@ -8,19 +8,20 @@ import ( "fmt" "math/big" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/trie" safemath "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/coreth/constants" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" - "github.com/ava-labs/coreth/trie" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/core/types" ) var ( @@ -43,6 +44,7 @@ func NewBlockValidator(extDataHashes map[common.Hash]common.Hash) BlockValidator } func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { + rulesExtra := params.GetRulesExtra(rules) if b == nil || b.ethBlock == nil { return errInvalidBlock } @@ -50,10 +52,10 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { ethHeader := b.ethBlock.Header() blockHash := b.ethBlock.Hash() - if !rules.IsApricotPhase1 { + if !rulesExtra.IsApricotPhase1 { if v.extDataHashes != nil { - extData := b.ethBlock.ExtData() - extDataHash := types.CalcExtDataHash(extData) + extData := customtypes.BlockExtData(b.ethBlock) + extDataHash := customtypes.CalcExtDataHash(extData) // If there is no extra data, check that there is no extra data in the hash map either to ensure we do not // have a block that is unexpectedly missing extra data. expectedExtDataHash, ok := v.extDataHashes[blockHash] @@ -77,15 +79,18 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { } // Verify the ExtDataHash field - if rules.IsApricotPhase1 { - if hash := types.CalcExtDataHash(b.ethBlock.ExtData()); ethHeader.ExtDataHash != hash { - return fmt.Errorf("extra data hash mismatch: have %x, want %x", ethHeader.ExtDataHash, hash) + headerExtra := customtypes.GetHeaderExtra(ethHeader) + if rulesExtra.IsApricotPhase1 { + extraData := customtypes.BlockExtData(b.ethBlock) + hash := customtypes.CalcExtDataHash(extraData) + if headerExtra.ExtDataHash != hash { + return fmt.Errorf("extra data hash mismatch: have %x, want %x", headerExtra.ExtDataHash, hash) } } else { - if ethHeader.ExtDataHash != (common.Hash{}) { + if headerExtra.ExtDataHash != (common.Hash{}) { return fmt.Errorf( "expected ExtDataHash to be empty but got %x", - ethHeader.ExtDataHash, + headerExtra.ExtDataHash, ) } } @@ -109,12 +114,12 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { } // Verify the extra data is well-formed. - if err := header.VerifyExtra(rules.AvalancheRules, ethHeader.Extra); err != nil { + if err := header.VerifyExtra(rulesExtra.AvalancheRules, ethHeader.Extra); err != nil { return err } - if b.ethBlock.Version() != 0 { - return fmt.Errorf("invalid version: %d", b.ethBlock.Version()) + if version := customtypes.BlockVersion(b.ethBlock); version != 0 { + return fmt.Errorf("invalid version: %d", version) } // Check that the tx hash in the header matches the body @@ -144,14 +149,14 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { // Enforce minimum gas prices here prior to dynamic fees going into effect. switch { - case !rules.IsApricotPhase1: + case !rulesExtra.IsApricotPhase1: // If we are in ApricotPhase0, enforce each transaction has a minimum gas price of at least the LaunchMinGasPrice for _, tx := range b.ethBlock.Transactions() { if tx.GasPrice().Cmp(ap0MinGasPrice) < 0 { return fmt.Errorf("block contains tx %s with gas price too low (%d < %d)", tx.Hash(), tx.GasPrice(), ap0.MinGasPrice) } } - case !rules.IsApricotPhase3: + case !rulesExtra.IsApricotPhase3: // If we are prior to ApricotPhase3, enforce each transaction has a minimum gas price of at least the ApricotPhase1MinGasPrice for _, tx := range b.ethBlock.Transactions() { if tx.GasPrice().Cmp(ap1MinGasPrice) < 0 { @@ -168,7 +173,7 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { } // Ensure BaseFee is non-nil as of ApricotPhase3. - if rules.IsApricotPhase3 { + if rulesExtra.IsApricotPhase3 { if ethHeader.BaseFee == nil { return errNilBaseFeeApricotPhase3 } @@ -179,19 +184,19 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { } // If we are in ApricotPhase4, ensure that ExtDataGasUsed is populated correctly. - if rules.IsApricotPhase4 { + if rulesExtra.IsApricotPhase4 { // After the F upgrade, the extDataGasUsed field is validated by // [header.VerifyGasUsed]. - if !rules.IsFortuna && rules.IsApricotPhase5 { - if !utils.BigLessOrEqualUint64(ethHeader.ExtDataGasUsed, ap5.AtomicGasLimit) { - return fmt.Errorf("too large extDataGasUsed: %d", ethHeader.ExtDataGasUsed) + if !rulesExtra.IsFortuna && rulesExtra.IsApricotPhase5 { + if !utils.BigLessOrEqualUint64(headerExtra.ExtDataGasUsed, ap5.AtomicGasLimit) { + return fmt.Errorf("too large extDataGasUsed: %d", headerExtra.ExtDataGasUsed) } } var totalGasUsed uint64 for _, atomicTx := range b.atomicTxs { // We perform this check manually here to avoid the overhead of having to // reparse the atomicTx in `CalcExtDataGasUsed`. - fixedFee := rules.IsApricotPhase5 // Charge the atomic tx fixed fee as of ApricotPhase5 + fixedFee := rulesExtra.IsApricotPhase5 // Charge the atomic tx fixed fee as of ApricotPhase5 gasUsed, err := atomicTx.GasUsed(fixedFee) if err != nil { return err @@ -203,15 +208,15 @@ func (v blockValidator) SyntacticVerify(b *Block, rules params.Rules) error { } switch { - case !utils.BigEqualUint64(ethHeader.ExtDataGasUsed, totalGasUsed): - return fmt.Errorf("invalid extDataGasUsed: have %d, want %d", ethHeader.ExtDataGasUsed, totalGasUsed) + case !utils.BigEqualUint64(headerExtra.ExtDataGasUsed, totalGasUsed): + return fmt.Errorf("invalid extDataGasUsed: have %d, want %d", headerExtra.ExtDataGasUsed, totalGasUsed) // Make sure BlockGasCost is not nil // NOTE: ethHeader.BlockGasCost correctness is checked in header verification - case ethHeader.BlockGasCost == nil: + case headerExtra.BlockGasCost == nil: return errNilBlockGasCostApricotPhase4 - case !ethHeader.BlockGasCost.IsUint64(): - return fmt.Errorf("too large blockGasCost: %d", ethHeader.BlockGasCost) + case !headerExtra.BlockGasCost.IsUint64(): + return fmt.Errorf("too large blockGasCost: %d", headerExtra.BlockGasCost) } } diff --git a/plugin/evm/client/utils.go b/plugin/evm/client/utils.go index 5ea43f4a20..7d1e35e4ae 100644 --- a/plugin/evm/client/utils.go +++ b/plugin/evm/client/utils.go @@ -3,7 +3,7 @@ package client -import "github.com/ethereum/go-ethereum/common" +import "github.com/ava-labs/libevm/common" func ParseEthAddress(addrStr string) (common.Address, error) { if !common.IsHexAddress(addrStr) { diff --git a/plugin/evm/config/config.go b/plugin/evm/config/config.go index ba89d7ddee..b34ce838aa 100644 --- a/plugin/evm/config/config.go +++ b/plugin/evm/config/config.go @@ -12,8 +12,8 @@ import ( "github.com/ava-labs/avalanchego/vms/components/gas" "github.com/ava-labs/coreth/plugin/evm/upgrade/etna" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" "github.com/spf13/cast" ) diff --git a/plugin/evm/config/config_test.go b/plugin/evm/config/config_test.go index ad13ebdfed..7b96a11742 100644 --- a/plugin/evm/config/config_test.go +++ b/plugin/evm/config/config_test.go @@ -9,7 +9,7 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/assert" ) diff --git a/plugin/evm/customrawdb/accessors_metadata_ext.go b/plugin/evm/customrawdb/accessors_metadata_ext.go new file mode 100644 index 0000000000..d0b97b0157 --- /dev/null +++ b/plugin/evm/customrawdb/accessors_metadata_ext.go @@ -0,0 +1,114 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customrawdb + +import ( + "fmt" + "time" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/rlp" +) + +// writeCurrentTimeMarker writes a marker of the current time in the db at `key`. +func writeCurrentTimeMarker(db ethdb.KeyValueStore, key []byte) error { + data, err := rlp.EncodeToBytes(uint64(time.Now().Unix())) + if err != nil { + return err + } + return db.Put(key, data) +} + +// readTimeMarker reads the timestamp stored at `key` +func readTimeMarker(db ethdb.KeyValueStore, key []byte) (time.Time, error) { + data, err := db.Get(key) + if err != nil { + return time.Time{}, err + } + + var unix uint64 + if err := rlp.DecodeBytes(data, &unix); err != nil { + return time.Time{}, err + } + + return time.Unix(int64(unix), 0), nil +} + +// WriteOfflinePruning writes a time marker of the last attempt to run offline pruning. +// The marker is written when offline pruning completes and is deleted when the node +// is started successfully with offline pruning disabled. This ensures users must +// disable offline pruning and start their node successfully between runs of offline +// pruning. +func WriteOfflinePruning(db ethdb.KeyValueStore) error { + return writeCurrentTimeMarker(db, offlinePruningKey) +} + +// ReadOfflinePruning reads the most recent timestamp of an attempt to run offline +// pruning if present. +func ReadOfflinePruning(db ethdb.KeyValueStore) (time.Time, error) { + return readTimeMarker(db, offlinePruningKey) +} + +// DeleteOfflinePruning deletes any marker of the last attempt to run offline pruning. +func DeleteOfflinePruning(db ethdb.KeyValueStore) error { + return db.Delete(offlinePruningKey) +} + +// WritePopulateMissingTries writes a marker for the current attempt to populate +// missing tries. +func WritePopulateMissingTries(db ethdb.KeyValueStore) error { + return writeCurrentTimeMarker(db, populateMissingTriesKey) +} + +// ReadPopulateMissingTries reads the most recent timestamp of an attempt to +// re-populate missing trie nodes. +func ReadPopulateMissingTries(db ethdb.KeyValueStore) (time.Time, error) { + return readTimeMarker(db, populateMissingTriesKey) +} + +// DeletePopulateMissingTries deletes any marker of the last attempt to +// re-populate missing trie nodes. +func DeletePopulateMissingTries(db ethdb.KeyValueStore) error { + return db.Delete(populateMissingTriesKey) +} + +// WritePruningDisabled writes a marker to track whether the node has ever run +// with pruning disabled. +func WritePruningDisabled(db ethdb.KeyValueStore) error { + return db.Put(pruningDisabledKey, nil) +} + +// HasPruningDisabled returns true if there is a marker present indicating that +// the node has run with pruning disabled at some pooint. +func HasPruningDisabled(db ethdb.KeyValueStore) (bool, error) { + return db.Has(pruningDisabledKey) +} + +// WriteAcceptorTip writes `hash` as the last accepted block that has been fully processed. +func WriteAcceptorTip(db ethdb.KeyValueWriter, hash common.Hash) error { + return db.Put(acceptorTipKey, hash[:]) +} + +// ReadAcceptorTip reads the hash of the last accepted block that was fully processed. +// If there is no value present (the index is being initialized for the first time), then the +// empty hash is returned. +func ReadAcceptorTip(db ethdb.KeyValueReader) (common.Hash, error) { + has, err := db.Has(acceptorTipKey) + if err != nil { + return common.Hash{}, err + } + if !has { + // If the index is not present on disk, the [acceptorTipKey] index has not been initialized yet. + return common.Hash{}, nil + } + h, err := db.Get(acceptorTipKey) + if err != nil { + return common.Hash{}, err + } + if len(h) != common.HashLength { + return common.Hash{}, fmt.Errorf("value has incorrect length %d", len(h)) + } + return common.BytesToHash(h), nil +} diff --git a/plugin/evm/customrawdb/accessors_snapshot_ext.go b/plugin/evm/customrawdb/accessors_snapshot_ext.go new file mode 100644 index 0000000000..a551dc7b4e --- /dev/null +++ b/plugin/evm/customrawdb/accessors_snapshot_ext.go @@ -0,0 +1,46 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customrawdb + +import ( + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" +) + +// ReadSnapshotBlockHash retrieves the hash of the block whose state is contained in +// the persisted snapshot. +func ReadSnapshotBlockHash(db ethdb.KeyValueReader) common.Hash { + data, _ := db.Get(snapshotBlockHashKey) + if len(data) != common.HashLength { + return common.Hash{} + } + return common.BytesToHash(data) +} + +// WriteSnapshotBlockHash stores the root of the block whose state is contained in +// the persisted snapshot. +func WriteSnapshotBlockHash(db ethdb.KeyValueWriter, blockHash common.Hash) { + if err := db.Put(snapshotBlockHashKey, blockHash[:]); err != nil { + log.Crit("Failed to store snapshot block hash", "err", err) + } +} + +// DeleteSnapshotBlockHash deletes the hash of the block whose state is contained in +// the persisted snapshot. Since snapshots are not immutable, this method can +// be used during updates, so a crash or failure will mark the entire snapshot +// invalid. +func DeleteSnapshotBlockHash(db ethdb.KeyValueWriter) { + if err := db.Delete(snapshotBlockHashKey); err != nil { + log.Crit("Failed to remove snapshot block hash", "err", err) + } +} + +// IterateAccountSnapshots returns an iterator for walking all of the accounts in the snapshot +func IterateAccountSnapshots(db ethdb.Iteratee) ethdb.Iterator { + it := db.NewIterator(rawdb.SnapshotAccountPrefix, nil) + keyLen := len(rawdb.SnapshotAccountPrefix) + common.HashLength + return rawdb.NewKeyLengthIterator(it, keyLen) +} diff --git a/core/rawdb/accessors_state_sync.go b/plugin/evm/customrawdb/accessors_state_sync.go similarity index 79% rename from core/rawdb/accessors_state_sync.go rename to plugin/evm/customrawdb/accessors_state_sync.go index 36ba9ef1bd..a54a016a12 100644 --- a/core/rawdb/accessors_state_sync.go +++ b/plugin/evm/customrawdb/accessors_state_sync.go @@ -1,15 +1,16 @@ // (c) 2022, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package rawdb +package customrawdb import ( "encoding/binary" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" ) // ReadSyncRoot reads the root corresponding to the main trie of an in-progress @@ -31,14 +32,14 @@ func WriteSyncRoot(db ethdb.KeyValueWriter, root common.Hash) error { return db.Put(syncRootKey, root[:]) } -// AddCodeToFetch adds a marker that we need to fetch the code for [hash]. +// AddCodeToFetch adds a marker that we need to fetch the code for `hash`. func AddCodeToFetch(db ethdb.KeyValueWriter, hash common.Hash) { if err := db.Put(codeToFetchKey(hash), nil); err != nil { log.Crit("Failed to put code to fetch", "codeHash", hash, "err", err) } } -// DeleteCodeToFetch removes the marker that the code corresponding to [hash] needs to be fetched. +// DeleteCodeToFetch removes the marker that the code corresponding to `hash` needs to be fetched. func DeleteCodeToFetch(db ethdb.KeyValueWriter, hash common.Hash) { if err := db.Delete(codeToFetchKey(hash)); err != nil { log.Crit("Failed to delete code to fetch", "codeHash", hash, "err", err) @@ -49,7 +50,7 @@ func DeleteCodeToFetch(db ethdb.KeyValueWriter, hash common.Hash) { // hashes that are pending syncing. It is the caller's responsibility to // unpack the key and call Release on the returned iterator. func NewCodeToFetchIterator(db ethdb.Iteratee) ethdb.Iterator { - return NewKeyLengthIterator( + return rawdb.NewKeyLengthIterator( db.NewIterator(CodeToFetchPrefix, nil), codeToFetchKeyLength, ) @@ -70,14 +71,14 @@ func NewSyncSegmentsIterator(db ethdb.Iteratee, root common.Hash) ethdb.Iterator copy(segmentsPrefix, syncSegmentsPrefix) copy(segmentsPrefix[len(syncSegmentsPrefix):], root[:]) - return NewKeyLengthIterator( + return rawdb.NewKeyLengthIterator( db.NewIterator(segmentsPrefix, nil), syncSegmentsKeyLength, ) } // WriteSyncSegment adds a trie segment for root at the given start position. -func WriteSyncSegment(db ethdb.KeyValueWriter, root common.Hash, start []byte) error { +func WriteSyncSegment(db ethdb.KeyValueWriter, root common.Hash, start common.Hash) error { return db.Put(packSyncSegmentKey(root, start), []byte{0x01}) } @@ -86,12 +87,12 @@ func ClearSyncSegments(db ethdb.KeyValueStore, root common.Hash) error { segmentsPrefix := make([]byte, len(syncSegmentsPrefix)+common.HashLength) copy(segmentsPrefix, syncSegmentsPrefix) copy(segmentsPrefix[len(syncSegmentsPrefix):], root[:]) - return ClearPrefix(db, segmentsPrefix, syncSegmentsKeyLength) + return clearPrefix(db, segmentsPrefix, syncSegmentsKeyLength) } // ClearAllSyncSegments removes all segment markers from db func ClearAllSyncSegments(db ethdb.KeyValueStore) error { - return ClearPrefix(db, syncSegmentsPrefix, syncSegmentsKeyLength) + return clearPrefix(db, syncSegmentsPrefix, syncSegmentsKeyLength) } // UnpackSyncSegmentKey returns the root and start position for a trie segment @@ -104,11 +105,11 @@ func UnpackSyncSegmentKey(keyBytes []byte) (common.Hash, []byte) { } // packSyncSegmentKey packs root and account into a key for storage in db. -func packSyncSegmentKey(root common.Hash, start []byte) []byte { - bytes := make([]byte, len(syncSegmentsPrefix)+common.HashLength+len(start)) +func packSyncSegmentKey(root common.Hash, start common.Hash) []byte { + bytes := make([]byte, syncSegmentsKeyLength) copy(bytes, syncSegmentsPrefix) copy(bytes[len(syncSegmentsPrefix):], root[:]) - copy(bytes[len(syncSegmentsPrefix)+common.HashLength:], start) + copy(bytes[len(syncSegmentsPrefix)+common.HashLength:], start.Bytes()) return bytes } @@ -116,7 +117,7 @@ func packSyncSegmentKey(root common.Hash, start []byte) []byte { // added for syncing (beginning at seek). It is the caller's responsibility to unpack // the key and call Release on the returned iterator. func NewSyncStorageTriesIterator(db ethdb.Iteratee, seek []byte) ethdb.Iterator { - return NewKeyLengthIterator(db.NewIterator(syncStorageTriesPrefix, seek), syncStorageTriesKeyLength) + return rawdb.NewKeyLengthIterator(db.NewIterator(syncStorageTriesPrefix, seek), syncStorageTriesKeyLength) } // WriteSyncStorageTrie adds a storage trie for account (with the given root) to be synced. @@ -130,12 +131,12 @@ func ClearSyncStorageTrie(db ethdb.KeyValueStore, root common.Hash) error { accountsPrefix := make([]byte, len(syncStorageTriesPrefix)+common.HashLength) copy(accountsPrefix, syncStorageTriesPrefix) copy(accountsPrefix[len(syncStorageTriesPrefix):], root[:]) - return ClearPrefix(db, accountsPrefix, syncStorageTriesKeyLength) + return clearPrefix(db, accountsPrefix, syncStorageTriesKeyLength) } // ClearAllSyncStorageTries removes all storage tries added for syncing from db func ClearAllSyncStorageTries(db ethdb.KeyValueStore) error { - return ClearPrefix(db, syncStorageTriesPrefix, syncStorageTriesKeyLength) + return clearPrefix(db, syncStorageTriesPrefix, syncStorageTriesKeyLength) } // UnpackSyncStorageTrieKey returns the root and account for a storage trie @@ -156,7 +157,7 @@ func packSyncStorageTrieKey(root common.Hash, account common.Hash) []byte { return bytes } -// WriteSyncPerformed logs an entry in [db] indicating the VM state synced to [blockNumber]. +// WriteSyncPerformed logs an entry in `db` indicating the VM state synced to `blockNumber`. func WriteSyncPerformed(db ethdb.KeyValueWriter, blockNumber uint64) error { syncPerformedPrefixLen := len(syncPerformedPrefix) bytes := make([]byte, syncPerformedPrefixLen+wrappers.LongLen) @@ -168,7 +169,7 @@ func WriteSyncPerformed(db ethdb.KeyValueWriter, blockNumber uint64) error { // NewSyncPerformedIterator returns an iterator over all block numbers the VM // has state synced to. func NewSyncPerformedIterator(db ethdb.Iteratee) ethdb.Iterator { - return NewKeyLengthIterator(db.NewIterator(syncPerformedPrefix, nil), syncPerformedKeyLength) + return rawdb.NewKeyLengthIterator(db.NewIterator(syncPerformedPrefix, nil), syncPerformedKeyLength) } // UnpackSyncPerformedKey returns the block number from keys the iterator returned @@ -191,3 +192,31 @@ func GetLatestSyncPerformed(db ethdb.Iteratee) uint64 { } return latestSyncPerformed } + +// clearPrefix removes all keys in db that begin with prefix and match an +// expected key length. `keyLen` must include the length of the prefix. +func clearPrefix(db ethdb.KeyValueStore, prefix []byte, keyLen int) error { + it := db.NewIterator(prefix, nil) + defer it.Release() + + batch := db.NewBatch() + for it.Next() { + key := common.CopyBytes(it.Key()) + if len(key) != keyLen { + continue + } + if err := batch.Delete(key); err != nil { + return err + } + if batch.ValueSize() > ethdb.IdealBatchSize { + if err := batch.Write(); err != nil { + return err + } + batch.Reset() + } + } + if err := it.Error(); err != nil { + return err + } + return batch.Write() +} diff --git a/core/rawdb/accessors_state_sync_test.go b/plugin/evm/customrawdb/accessors_state_sync_test.go similarity index 83% rename from core/rawdb/accessors_state_sync_test.go rename to plugin/evm/customrawdb/accessors_state_sync_test.go index 5c51eb7bf3..f864d37909 100644 --- a/core/rawdb/accessors_state_sync_test.go +++ b/plugin/evm/customrawdb/accessors_state_sync_test.go @@ -1,20 +1,21 @@ // (c) 2023, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. -package rawdb +package customrawdb import ( "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" "github.com/stretchr/testify/require" ) func TestClearPrefix(t *testing.T) { require := require.New(t) - db := NewMemoryDatabase() + db := rawdb.NewMemoryDatabase() // add a key that should be cleared - require.NoError(WriteSyncSegment(db, common.Hash{1}, common.Hash{}.Bytes())) + require.NoError(WriteSyncSegment(db, common.Hash{1}, common.Hash{})) // add a key that should not be cleared key := append(syncSegmentsPrefix, []byte("foo")...) diff --git a/plugin/evm/customrawdb/database_ext.go b/plugin/evm/customrawdb/database_ext.go new file mode 100644 index 0000000000..c9a6c83f26 --- /dev/null +++ b/plugin/evm/customrawdb/database_ext.go @@ -0,0 +1,63 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customrawdb + +import ( + "bytes" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" +) + +// InspectDatabase traverses the entire database and checks the size +// of all different categories of data. +func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { + type stat = rawdb.DatabaseStat + stats := []struct { + name string + keyLen int + keyPrefix []byte + stat *stat + }{ + {"Trie segments", syncSegmentsKeyLength, syncSegmentsPrefix, &stat{}}, + {"Storage tries to fetch", syncStorageTriesKeyLength, syncStorageTriesPrefix, &stat{}}, + {"Code to fetch", codeToFetchKeyLength, CodeToFetchPrefix, &stat{}}, + {"Block numbers synced to", syncPerformedKeyLength, syncPerformedPrefix, &stat{}}, + } + + options := []rawdb.InspectDatabaseOption{ + rawdb.WithDatabaseMetadataKeys(func(key []byte) bool { + return bytes.Equal(key, snapshotBlockHashKey) || + bytes.Equal(key, syncRootKey) + }), + rawdb.WithDatabaseStatRecorder(func(key []byte, size common.StorageSize) bool { + for _, s := range stats { + if len(key) == s.keyLen && bytes.HasPrefix(key, s.keyPrefix) { + s.stat.Add(size) + return true + } + } + return false + }), + rawdb.WithDatabaseStatsTransformer(func(rows [][]string) [][]string { + newRows := make([][]string, 0, len(rows)) + for _, row := range rows { + switch db, cat := row[0], row[1]; { + // Discard rows specific to libevm (geth) but irrelevant to coreth. + case db == "Key-Value store" && (cat == "Difficulties" || cat == "Beacon sync headers"): + case db == "Ancient store (Chain)": + default: + newRows = append(newRows, row) + } + } + for _, s := range stats { + newRows = append(newRows, []string{"State sync", s.name, s.stat.Size(), s.stat.Count()}) + } + return newRows + }), + } + + return rawdb.InspectDatabase(db, keyPrefix, keyStart, options...) +} diff --git a/plugin/evm/customrawdb/database_ext_test.go b/plugin/evm/customrawdb/database_ext_test.go new file mode 100644 index 0000000000..1f10e5e6de --- /dev/null +++ b/plugin/evm/customrawdb/database_ext_test.go @@ -0,0 +1,135 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customrawdb + +import ( + "fmt" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" +) + +func ExampleInspectDatabase() { + db := &stubDatabase{ + iterator: &stubIterator{}, + } + + // Extra metadata keys: (17 + 32) + (12 + 32) = 93 bytes + WriteSnapshotBlockHash(db, common.Hash{}) + rawdb.WriteSnapshotRoot(db, common.Hash{}) + // Trie segments: (77 + 2) + 1 = 80 bytes + _ = WriteSyncSegment(db, common.Hash{}, common.Hash{}) + // Storage tries to fetch: 76 + 1 = 77 bytes + _ = WriteSyncStorageTrie(db, common.Hash{}, common.Hash{}) + // Code to fetch: 34 + 0 = 34 bytes + AddCodeToFetch(db, common.Hash{}) + // Block numbers synced to: 22 + 1 = 23 bytes + _ = WriteSyncPerformed(db, 0) + + keyPrefix := []byte(nil) + keyStart := []byte(nil) + + err := InspectDatabase(db, keyPrefix, keyStart) + if err != nil { + fmt.Println(err) + } + // Output: + // +-----------------+-------------------------+----------+-------+ + // | DATABASE | CATEGORY | SIZE | ITEMS | + // +-----------------+-------------------------+----------+-------+ + // | Key-Value store | Headers | 0.00 B | 0 | + // | Key-Value store | Bodies | 0.00 B | 0 | + // | Key-Value store | Receipt lists | 0.00 B | 0 | + // | Key-Value store | Block number->hash | 0.00 B | 0 | + // | Key-Value store | Block hash->number | 0.00 B | 0 | + // | Key-Value store | Transaction index | 0.00 B | 0 | + // | Key-Value store | Bloombit index | 0.00 B | 0 | + // | Key-Value store | Contract codes | 0.00 B | 0 | + // | Key-Value store | Hash trie nodes | 0.00 B | 0 | + // | Key-Value store | Path trie state lookups | 0.00 B | 0 | + // | Key-Value store | Path trie account nodes | 0.00 B | 0 | + // | Key-Value store | Path trie storage nodes | 0.00 B | 0 | + // | Key-Value store | Trie preimages | 0.00 B | 0 | + // | Key-Value store | Account snapshot | 0.00 B | 0 | + // | Key-Value store | Storage snapshot | 0.00 B | 0 | + // | Key-Value store | Clique snapshots | 0.00 B | 0 | + // | Key-Value store | Singleton metadata | 93.00 B | 2 | + // | Light client | CHT trie nodes | 0.00 B | 0 | + // | Light client | Bloom trie nodes | 0.00 B | 0 | + // | State sync | Trie segments | 78.00 B | 1 | + // | State sync | Storage tries to fetch | 77.00 B | 1 | + // | State sync | Code to fetch | 34.00 B | 1 | + // | State sync | Block numbers synced to | 23.00 B | 1 | + // +-----------------+-------------------------+----------+-------+ + // | TOTAL | 305.00 B | | + // +-----------------+-------------------------+----------+-------+ +} + +type stubDatabase struct { + ethdb.Database + iterator *stubIterator +} + +func (s *stubDatabase) NewIterator(keyPrefix, keyStart []byte) ethdb.Iterator { + return s.iterator +} + +// AncientSize is used in [InspectDatabase] to determine the ancient sizes. +func (s *stubDatabase) AncientSize(kind string) (uint64, error) { + return 0, nil +} + +func (s *stubDatabase) Ancients() (uint64, error) { + return 0, nil +} + +func (s *stubDatabase) Tail() (uint64, error) { + return 0, nil +} + +func (s *stubDatabase) Put(key, value []byte) error { + s.iterator.kvs = append(s.iterator.kvs, keyValue{key: key, value: value}) + return nil +} + +func (s *stubDatabase) Get(key []byte) ([]byte, error) { + return nil, nil +} + +func (s *stubDatabase) ReadAncients(fn func(ethdb.AncientReaderOp) error) error { + return nil +} + +type stubIterator struct { + ethdb.Iterator + i int // see [stubIterator.pos] + kvs []keyValue +} + +type keyValue struct { + key []byte + value []byte +} + +// pos returns the true iterator position, which is otherwise off by one because +// Next() is called _before_ usage. +func (s *stubIterator) pos() int { + return s.i - 1 +} + +func (s *stubIterator) Next() bool { + s.i++ + return s.pos() < len(s.kvs) +} + +func (s *stubIterator) Release() {} + +func (s *stubIterator) Key() []byte { + return s.kvs[s.pos()].key +} + +func (s *stubIterator) Value() []byte { + return s.kvs[s.pos()].value +} diff --git a/plugin/evm/customrawdb/schema_ext.go b/plugin/evm/customrawdb/schema_ext.go new file mode 100644 index 0000000000..3b597e034e --- /dev/null +++ b/plugin/evm/customrawdb/schema_ext.go @@ -0,0 +1,53 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customrawdb + +import ( + "github.com/ava-labs/avalanchego/utils/wrappers" + "github.com/ava-labs/libevm/common" +) + +var ( + // snapshotBlockHashKey tracks the block hash of the last snapshot. + snapshotBlockHashKey = []byte("SnapshotBlockHash") + // offlinePruningKey tracks runs of offline pruning + offlinePruningKey = []byte("OfflinePruning") + // populateMissingTriesKey tracks runs of trie backfills + populateMissingTriesKey = []byte("PopulateMissingTries") + // pruningDisabledKey tracks whether the node has ever run in archival mode + // to ensure that a user does not accidentally corrupt an archival node. + pruningDisabledKey = []byte("PruningDisabled") + // acceptorTipKey tracks the tip of the last accepted block that has been fully processed. + acceptorTipKey = []byte("AcceptorTipKey") +) + +// State sync progress keys and prefixes +var ( + // syncRootKey indicates the root of the main account trie currently being synced + syncRootKey = []byte("sync_root") + // syncStorageTriesPrefix is the prefix for storage tries that need to be fetched. + // syncStorageTriesPrefix + trie root + account hash: indicates a storage trie must be fetched for the account + syncStorageTriesPrefix = []byte("sync_storage") + // syncSegmentsPrefix is the prefix for segments. + // syncSegmentsPrefix + trie root + 32-byte start key: indicates the trie at root has a segment starting at the specified key + syncSegmentsPrefix = []byte("sync_segments") + // CodeToFetchPrefix is the prefix for code hashes that need to be fetched. + // CodeToFetchPrefix + code hash -> empty value tracks the outstanding code hashes we need to fetch. + CodeToFetchPrefix = []byte("CP") +) + +// State sync progress key lengths +var ( + syncStorageTriesKeyLength = len(syncStorageTriesPrefix) + 2*common.HashLength + syncSegmentsKeyLength = len(syncSegmentsPrefix) + 2*common.HashLength + codeToFetchKeyLength = len(CodeToFetchPrefix) + common.HashLength +) + +// State sync metadata +var ( + syncPerformedPrefix = []byte("sync_performed") + // syncPerformedKeyLength is the length of the key for the sync performed metadata key, + // and is equal to [syncPerformedPrefix] + block number as uint64. + syncPerformedKeyLength = len(syncPerformedPrefix) + wrappers.LongLen +) diff --git a/plugin/evm/customtypes/block_ext.go b/plugin/evm/customtypes/block_ext.go new file mode 100644 index 0000000000..8ec41a1537 --- /dev/null +++ b/plugin/evm/customtypes/block_ext.go @@ -0,0 +1,154 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customtypes + +import ( + "math/big" + "slices" + + "github.com/ava-labs/libevm/common" + ethtypes "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" +) + +// SetBlockExtra sets the [BlockBodyExtra] `extra` in the [Block] `b`. +func SetBlockExtra(b *ethtypes.Block, extra *BlockBodyExtra) { + extras.Block.Set(b, extra) +} + +// BlockBodyExtra is a struct containing extra fields used by Avalanche +// in the [Block] and [Body]. +type BlockBodyExtra struct { + Version uint32 + ExtData *[]byte +} + +// Copy deep copies the [BlockBodyExtra] `b` and returns it. +// It is notably used in the following functions: +// - [ethtypes.Block.Body] +// - [ethtypes.Block.WithSeal] +// - [ethtypes.Block.WithBody] +// - [ethtypes.Block.WithWithdrawals] +func (b *BlockBodyExtra) Copy() *BlockBodyExtra { + cpy := *b + if b.ExtData != nil { + data := slices.Clone(*b.ExtData) + cpy.ExtData = &data + } + return &cpy +} + +// BodyRLPFieldPointersForEncoding returns the fields that should be encoded +// for the [Body] and [BlockBodyExtra]. +// Note the following fields are added (+) and removed (-) compared to geth: +// - (-) [ethtypes.Body] `Withdrawals` field +// - (+) [BlockBodyExtra] `Version` field +// - (+) [BlockBodyExtra] `ExtData` field +func (b *BlockBodyExtra) BodyRLPFieldsForEncoding(body *ethtypes.Body) *rlp.Fields { + return &rlp.Fields{ + Required: []any{ + body.Transactions, + body.Uncles, + b.Version, + b.ExtData, + }, + } +} + +// BodyRLPFieldPointersForDecoding returns the fields that should be decoded to +// for the [Body] and [BlockBodyExtra]. +func (b *BlockBodyExtra) BodyRLPFieldPointersForDecoding(body *ethtypes.Body) *rlp.Fields { + return &rlp.Fields{ + Required: []any{ + &body.Transactions, + &body.Uncles, + &b.Version, + &b.ExtData, + }, + } +} + +// BlockRLPFieldPointersForEncoding returns the fields that should be encoded +// for the [Block] and [BlockBodyExtra]. +// Note the following fields are added (+) and removed (-) compared to geth: +// - (-) [ethtypes.Block] `Withdrawals` field +// - (+) [BlockBodyExtra] `Version` field +// - (+) [BlockBodyExtra] `ExtData` field +func (b *BlockBodyExtra) BlockRLPFieldsForEncoding(block *ethtypes.BlockRLPProxy) *rlp.Fields { + return &rlp.Fields{ + Required: []any{ + block.Header, + block.Txs, + block.Uncles, + b.Version, + b.ExtData, + }, + } +} + +// BlockRLPFieldPointersForDecoding returns the fields that should be decoded to +// for the [Block] and [BlockBodyExtra]. +func (b *BlockBodyExtra) BlockRLPFieldPointersForDecoding(block *ethtypes.BlockRLPProxy) *rlp.Fields { + return &rlp.Fields{ + Required: []any{ + &block.Header, + &block.Txs, + &block.Uncles, + &b.Version, + &b.ExtData, + }, + } +} + +func BlockExtData(b *ethtypes.Block) []byte { + if data := extras.Block.Get(b).ExtData; data != nil { + return *data + } + return nil +} + +func BlockVersion(b *ethtypes.Block) uint32 { + return extras.Block.Get(b).Version +} + +func BlockExtDataGasUsed(b *ethtypes.Block) *big.Int { + used := GetHeaderExtra(b.Header()).ExtDataGasUsed + if used == nil { + return nil + } + return new(big.Int).Set(used) +} + +func BlockGasCost(b *ethtypes.Block) *big.Int { + cost := GetHeaderExtra(b.Header()).BlockGasCost + if cost == nil { + return nil + } + return new(big.Int).Set(cost) +} + +func CalcExtDataHash(extdata []byte) common.Hash { + if len(extdata) == 0 { + return EmptyExtDataHash + } + return rlpHash(extdata) +} + +func NewBlockWithExtData( + header *ethtypes.Header, txs []*ethtypes.Transaction, uncles []*ethtypes.Header, receipts []*ethtypes.Receipt, + hasher ethtypes.TrieHasher, extdata []byte, recalc bool, +) *ethtypes.Block { + if recalc { + headerExtra := GetHeaderExtra(header) + headerExtra.ExtDataHash = CalcExtDataHash(extdata) + } + block := ethtypes.NewBlock(header, txs, uncles, receipts, hasher) + extdataCopy := make([]byte, len(extdata)) + copy(extdataCopy, extdata) + extra := &BlockBodyExtra{ + ExtData: &extdataCopy, + } + extras.Block.Set(block, extra) + return block +} diff --git a/plugin/evm/customtypes/block_ext_test.go b/plugin/evm/customtypes/block_ext_test.go new file mode 100644 index 0000000000..d4d490448e --- /dev/null +++ b/plugin/evm/customtypes/block_ext_test.go @@ -0,0 +1,495 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customtypes + +import ( + "encoding/hex" + "math/big" + "reflect" + "testing" + "unsafe" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/rlp" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + // TODO(arr4n) These tests were originally part of the `coreth/core/types` + // package so assume the presence of identifiers. A dot-import reduces PR + // noise during the refactoring. + . "github.com/ava-labs/libevm/core/types" +) + +func TestCopyHeader(t *testing.T) { + t.Parallel() + + t.Run("empty_header", func(t *testing.T) { + t.Parallel() + + empty := &Header{} + + headerExtra := &HeaderExtra{} + extras.Header.Set(empty, headerExtra) + + cpy := CopyHeader(empty) + + want := &Header{ + Difficulty: new(big.Int), + Number: new(big.Int), + } + + headerExtra = &HeaderExtra{} + extras.Header.Set(want, headerExtra) + + assert.Equal(t, want, cpy) + }) + + t.Run("filled_header", func(t *testing.T) { + t.Parallel() + + header, _ := headerWithNonZeroFields() // the header carries the [HeaderExtra] so we can ignore it + + gotHeader := CopyHeader(header) + gotExtra := GetHeaderExtra(gotHeader) + + wantHeader, wantExtra := headerWithNonZeroFields() + assert.Equal(t, wantHeader, gotHeader) + assert.Equal(t, wantExtra, gotExtra) + + exportedFieldsPointToDifferentMemory(t, header, gotHeader) + exportedFieldsPointToDifferentMemory(t, GetHeaderExtra(header), gotExtra) + }) +} + +func exportedFieldsPointToDifferentMemory[T interface { + Header | HeaderExtra | BlockBodyExtra +}](t *testing.T, original, cpy *T) { + t.Helper() + + v := reflect.ValueOf(*original) + typ := v.Type() + cp := reflect.ValueOf(*cpy) + for i := range v.NumField() { + field := typ.Field(i) + if !field.IsExported() { + continue + } + switch field.Type.Kind() { + case reflect.Array, reflect.Uint64, reflect.Uint32: + // Not pointers, but using explicit Kinds for safety + continue + } + + t.Run(field.Name, func(t *testing.T) { + fieldCp := cp.Field(i).Interface() + switch f := v.Field(i).Interface().(type) { + case *big.Int: + assertDifferentPointers(t, f, fieldCp) + case *common.Hash: + assertDifferentPointers(t, f, fieldCp) + case *uint64: + assertDifferentPointers(t, f, fieldCp) + case *[]uint8: + assertDifferentPointers(t, f, fieldCp) + case []uint8: + assertDifferentPointers(t, unsafe.SliceData(f), unsafe.SliceData(fieldCp.([]uint8))) + default: + t.Errorf("field %q type %T needs to be added to switch cases of exportedFieldsDeepCopied", field.Name, f) + } + }) + } +} + +// assertDifferentPointers asserts that `a` and `b` are both non-nil +// pointers pointing to different memory locations. +func assertDifferentPointers[T any](t *testing.T, a *T, b any) { + t.Helper() + switch { + case a == nil: + t.Errorf("a (%T) cannot be nil", a) + case b == nil: + t.Errorf("b (%T) cannot be nil", b) + case a == b: + t.Errorf("pointers to same memory") + } + // Note: no need to check `b` is of the same type as `a`, otherwise + // the memory address would be different as well. +} + +// blockWithNonZeroFields returns a [Block] and a [BlockBodyExtra], +// each with all fields set to non-zero values. +// The [BlockBodyExtra] extra payload is set in the [Block] via `extras.Block.Set`. +// +// NOTE: They can be used to demonstrate that RLP round-trip encoding +// can recover all fields, but not that the encoded format is correct. This is +// very important as the RLP encoding of a [Block] defines its hash. +func blockWithNonZeroFields() (*Block, *BlockBodyExtra) { + header := WithHeaderExtra( + &Header{ + ParentHash: common.Hash{1}, + }, + &HeaderExtra{ + ExtDataHash: common.Hash{2}, + }, + ) + + tx := NewTransaction(1, common.Address{2}, big.NewInt(3), 4, big.NewInt(5), []byte{6}) + txs := []*Transaction{tx} + + uncle := WithHeaderExtra( + &Header{ + Difficulty: big.NewInt(7), + Number: big.NewInt(8), + ParentHash: common.Hash{9}, + }, + &HeaderExtra{ + ExtDataHash: common.Hash{10}, + }, + ) + uncles := []*Header{uncle} + + receipts := []*Receipt{{PostState: []byte{11}}} + + block := NewBlock(header, txs, uncles, receipts, stubHasher{}) + withdrawals := []*Withdrawal{{Index: 12}} + block = block.WithWithdrawals(withdrawals) + extra := &BlockBodyExtra{ + Version: 13, + ExtData: &[]byte{14}, + } + SetBlockExtra(block, extra) + return block, extra +} + +func TestBlockWithNonZeroFields(t *testing.T) { + t.Parallel() + + block, extra := blockWithNonZeroFields() + t.Run("Block", func(t *testing.T) { + ignoreFields := []string{"extra", "hash", "size", "ReceivedAt", "ReceivedFrom"} + allFieldsSet(t, block, ignoreFields...) + }) + t.Run("BlockExtra", func(t *testing.T) { allFieldsSet(t, extra) }) +} + +// bodyWithNonZeroFields returns a [Body] and a [BlockBodyExtra], +// each with all fields set to non-zero values. +// The [BlockBodyExtra] extra payload is set in the [Body] via `extras.Block.Set` +// and the extra copying done in `Block.Body()`. +// +// NOTE: They can be used to demonstrate that RLP round-trip encoding +// can recover all fields, but not that the encoded format is correct. This is +// very important as the RLP encoding of a [Body] defines its hash. +func bodyWithNonZeroFields() (*Body, *BlockBodyExtra) { + block, extra := blockWithNonZeroFields() + return block.Body(), extra +} + +func TestBodyWithNonZeroFields(t *testing.T) { + t.Parallel() + + body, extra := bodyWithNonZeroFields() + t.Run("Body", func(t *testing.T) { + ignoredFields := []string{"extra"} + allFieldsSet(t, body, ignoredFields...) + }) + t.Run("BodyExtra", func(t *testing.T) { allFieldsSet(t, extra) }) +} + +func txHashComparer() cmp.Option { + return cmp.Comparer(func(a, b *Transaction) bool { + return a.Hash() == b.Hash() + }) +} + +func headerHashComparer() cmp.Option { + return cmp.Comparer(func(a, b *Header) bool { + return a.Hash() == b.Hash() + }) +} + +func TestBodyExtraRLP(t *testing.T) { + t.Parallel() + + body, _ := bodyWithNonZeroFields() // the body carries the [BlockBodyExtra] so we can ignore it + + encoded, err := rlp.EncodeToBytes(body) + require.NoError(t, err) + + gotBody := new(Body) + err = rlp.DecodeBytes(encoded, gotBody) + require.NoError(t, err) + + wantBody, wantExtra := bodyWithNonZeroFields() + wantBody.Withdrawals = nil + + opts := cmp.Options{ + txHashComparer(), + headerHashComparer(), + cmpopts.IgnoreUnexported(Body{}), + } + if diff := cmp.Diff(wantBody, gotBody, opts); diff != "" { + t.Errorf("%T diff after RLP round-trip (-want +got):\n%s", wantBody, diff) + } + + gotExtra := extras.Body.Get(gotBody) + if diff := cmp.Diff(wantExtra, gotExtra); diff != "" { + t.Errorf("%T diff after RLP round-trip of %T (-want +got):\n%s", wantExtra, wantBody, diff) + } + + // Golden data from original coreth implementation, before integration of + // libevm. WARNING: changing these values can break backwards compatibility + // with extreme consequences. + const wantHex = "f90235dedd0105049402000000000000000000000000000000000000000306808080f90211f9020ea00900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070880808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a00a000000000000000000000000000000000000000000000000000000000000000d0e" + + assert.Equal(t, wantHex, hex.EncodeToString(encoded), "golden data") +} + +func TestBlockExtraRLP(t *testing.T) { + t.Parallel() + + block, _ := blockWithNonZeroFields() // the block carries the [BlockBodyExtra] so we can ignore it + + encoded, err := rlp.EncodeToBytes(block) + require.NoError(t, err) + + gotBlock := new(Block) + err = rlp.DecodeBytes(encoded, gotBlock) + require.NoError(t, err) + + wantBlock, wantExtra := blockWithNonZeroFields() + wantBlock = wantBlock.WithWithdrawals(nil) // withdrawals are not encoded + + opts := cmp.Options{ + txHashComparer(), + headerHashComparer(), + cmpopts.IgnoreUnexported(Block{}), + } + if diff := cmp.Diff(wantBlock, gotBlock, opts); diff != "" { + t.Errorf("%T diff after RLP round-trip (-want +got):\n%s", gotBlock, diff) + } + + gotExtra := extras.Block.Get(gotBlock) + if diff := cmp.Diff(wantExtra, gotExtra); diff != "" { + t.Errorf("%T diff after RLP round-trip of %T (-want +got):\n%s", wantExtra, wantBlock, diff) + } + + // Golden data from original coreth implementation, before integration of + // libevm. WARNING: changing these values can break backwards compatibility + // with extreme consequences. + const wantHex = "f90446f9020ea00100000000000000000000000000000000000000000000000000000000000000a008539331084089cedbaf7771d0f5f69847f246e0676e4d96091a49c53c89360b940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000808080808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a00200000000000000000000000000000000000000000000000000000000000000dedd0105049402000000000000000000000000000000000000000306808080f90211f9020ea00900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000940000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000070880808080a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a00a000000000000000000000000000000000000000000000000000000000000000d0e" + + assert.Equal(t, wantHex, hex.EncodeToString(encoded), "golden data") +} + +// TestBlockBody tests the [BlockBodyExtra.Copy] method is implemented correctly. +func TestBlockBody(t *testing.T) { + t.Parallel() + + const version = 1 + extData := &[]byte{2} + + blockExtras := &BlockBodyExtra{ + Version: version, + ExtData: extData, + } + allFieldsSet(t, blockExtras) // make sure each field is checked + block := NewBlock(&Header{}, nil, nil, nil, stubHasher{}) + extras.Block.Set(block, blockExtras) + + wantExtra := &BlockBodyExtra{ + Version: version, + ExtData: extData, + } + gotExtra := extras.Body.Get(block.Body()) // [types.Block.Body] invokes [BlockBodyExtra.Copy] + assert.Equal(t, wantExtra, gotExtra) + + exportedFieldsPointToDifferentMemory(t, blockExtras, gotExtra) +} + +func TestBlockGetters(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + headerExtra *HeaderExtra + blockExtra *BlockBodyExtra + wantExtDataGasUsed *big.Int + wantBlockGasCost *big.Int + wantVersion uint32 + wantExtData []byte + }{ + { + name: "empty", + headerExtra: &HeaderExtra{}, + blockExtra: &BlockBodyExtra{}, + }, + { + name: "fields_set", + headerExtra: &HeaderExtra{ + ExtDataGasUsed: big.NewInt(1), + BlockGasCost: big.NewInt(2), + }, + blockExtra: &BlockBodyExtra{ + Version: 3, + ExtData: &[]byte{4}, + }, + wantExtDataGasUsed: big.NewInt(1), + wantBlockGasCost: big.NewInt(2), + wantVersion: 3, + wantExtData: []byte{4}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + header := WithHeaderExtra(&Header{}, test.headerExtra) + + block := NewBlock(header, nil, nil, nil, stubHasher{}) + extras.Block.Set(block, test.blockExtra) + + extData := BlockExtData(block) + assert.Equal(t, test.wantExtData, extData, "BlockExtData()") + + version := BlockVersion(block) + assert.Equal(t, test.wantVersion, version, "BlockVersion()") + + extDataGasUsed := BlockExtDataGasUsed(block) + assert.Equal(t, test.wantExtDataGasUsed, extDataGasUsed, "BlockExtDataGasUsed()") + + blockGasCost := BlockGasCost(block) + assert.Equal(t, test.wantBlockGasCost, blockGasCost, "BlockGasCost()") + }) + } +} + +func TestNewBlockWithExtData(t *testing.T) { + t.Parallel() + + // This transaction is generated beforehand because of its unexported time field being set + // on creation. + testTx := NewTransaction(0, common.Address{1}, big.NewInt(2), 3, big.NewInt(4), []byte{5}) + + tests := []struct { + name string + header *Header + txs []*Transaction + uncles []*Header + receipts []*Receipt + extdata []byte + recalc bool + wantBlock func() *Block + }{ + { + name: "empty", + header: WithHeaderExtra(&Header{}, &HeaderExtra{}), + wantBlock: func() *Block { + header := WithHeaderExtra(&Header{}, &HeaderExtra{}) + block := NewBlock(header, nil, nil, nil, stubHasher{}) + blockExtra := &BlockBodyExtra{ExtData: &[]byte{}} + extras.Block.Set(block, blockExtra) + return block + }, + }, + { + name: "header_nil_extra", + header: &Header{}, + wantBlock: func() *Block { + header := WithHeaderExtra(&Header{}, &HeaderExtra{}) + block := NewBlock(header, nil, nil, nil, stubHasher{}) + blockExtra := &BlockBodyExtra{ExtData: &[]byte{}} + extras.Block.Set(block, blockExtra) + return block + }, + }, + { + name: "with_recalc", + header: WithHeaderExtra( + &Header{}, + &HeaderExtra{ + ExtDataHash: common.Hash{1}, // should be overwritten + }, + ), + extdata: []byte{2}, + recalc: true, + wantBlock: func() *Block { + header := WithHeaderExtra( + &Header{}, + &HeaderExtra{ExtDataHash: CalcExtDataHash([]byte{2})}, + ) + block := NewBlock(header, nil, nil, nil, stubHasher{}) + blockExtra := &BlockBodyExtra{ExtData: &[]byte{2}} + extras.Block.Set(block, blockExtra) + return block + }, + }, + { + name: "filled_no_recalc", + header: WithHeaderExtra( + &Header{GasLimit: 1}, + &HeaderExtra{ + ExtDataHash: common.Hash{2}, + ExtDataGasUsed: big.NewInt(3), + BlockGasCost: big.NewInt(4), + }, + ), + txs: []*Transaction{testTx}, + uncles: []*Header{ + WithHeaderExtra( + &Header{GasLimit: 5}, + &HeaderExtra{BlockGasCost: big.NewInt(6)}, + ), + }, + receipts: []*Receipt{{PostState: []byte{7}}}, + extdata: []byte{8}, + wantBlock: func() *Block { + header := WithHeaderExtra( + &Header{GasLimit: 1}, + &HeaderExtra{ + ExtDataHash: common.Hash{2}, + ExtDataGasUsed: big.NewInt(3), + BlockGasCost: big.NewInt(4), + }, + ) + uncle := WithHeaderExtra( + &Header{GasLimit: 5}, + &HeaderExtra{BlockGasCost: big.NewInt(6)}, + ) + uncles := []*Header{uncle} + block := NewBlock(header, []*Transaction{testTx}, uncles, []*Receipt{{PostState: []byte{7}}}, stubHasher{}) + blockExtra := &BlockBodyExtra{ExtData: &[]byte{8}} + extras.Block.Set(block, blockExtra) + return block + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + + block := NewBlockWithExtData( + test.header, + test.txs, + test.uncles, + test.receipts, + stubHasher{}, + test.extdata, + test.recalc, + ) + + assert.Equal(t, test.wantBlock(), block) + }) + } +} + +type stubHasher struct{} + +func (h stubHasher) Reset() {} +func (h stubHasher) Update(key, value []byte) error { return nil } +func (h stubHasher) Hash() common.Hash { return common.Hash{} } diff --git a/core/types/block_test.go b/plugin/evm/customtypes/block_test.go similarity index 84% rename from core/types/block_test.go rename to plugin/evm/customtypes/block_test.go index 6da8f441f9..bb49783892 100644 --- a/core/types/block_test.go +++ b/plugin/evm/customtypes/block_test.go @@ -24,7 +24,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package types +package customtypes_test import ( "bytes" @@ -34,17 +34,23 @@ import ( "github.com/ava-labs/coreth/internal/blocktest" "github.com/ava-labs/coreth/params" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" + + // This test file has to be in package types_test to avoid a circular + // dependency when importing `params`. We dot-import the package to mimic + // regular same-package behaviour. + . "github.com/ava-labs/coreth/plugin/evm/customtypes" ) // This test has been modified from https://github.com/ethereum/go-ethereum/blob/v1.9.21/core/types/block_test.go#L35 to fit // the modified block format of Coreth func TestBlockEncoding(t *testing.T) { blockEnc := common.FromHex("f90291f90217a04504ee98a94d16dbd70a35370501a3cb00c2965b012672085fbd328a72962902a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a00202e12a30c13562445052414c24dce5f1c530bb164e2a50897f0a6a1f78f158a0ecdf3b2c973d4156782b95816451fe9ed66b099cdca22f1168591ae2087765f4a0056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103837a12008252088460674e8a80a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f872f870808534630b8a00825208941954b772512974978793a809ecd8dce02dc71ba989014d1120d7b160000080830150f4a0beebf298ec38f9f4204f924686c4e5dd00f525fc1979ad224661ed2839ed55fda0267c480d1236c1684bdbad564a422e0a05007d7e8ca1acefe34e790b1d3a450ec08080") - var block Block + var block types.Block if err := rlp.DecodeBytes(blockEnc, &block); err != nil { t.Fatal("decode error: ", err) } @@ -60,7 +66,7 @@ func TestBlockEncoding(t *testing.T) { check("Root", block.Root(), common.HexToHash("0202e12a30c13562445052414c24dce5f1c530bb164e2a50897f0a6a1f78f158")) check("TxHash", block.TxHash(), common.HexToHash("ecdf3b2c973d4156782b95816451fe9ed66b099cdca22f1168591ae2087765f4")) check("ReceiptHash", block.ReceiptHash(), common.HexToHash("056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2")) - check("Bloom", block.Bloom(), BytesToBloom(common.FromHex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))) + check("Bloom", block.Bloom(), types.BytesToBloom(common.FromHex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))) check("Difficulty", block.Difficulty(), big.NewInt(1)) check("BlockNumber", block.NumberU64(), uint64(3)) check("GasLimit", block.GasLimit(), uint64(8000000)) @@ -69,10 +75,10 @@ func TestBlockEncoding(t *testing.T) { check("Extra", block.Extra(), common.FromHex("")) check("MixDigest", block.MixDigest(), common.HexToHash("0000000000000000000000000000000000000000000000000000000000000000")) check("Nonce", block.Nonce(), uint64(0)) - check("ExtDataHash", block.header.ExtDataHash, common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) + check("ExtDataHash", GetHeaderExtra(block.Header()).ExtDataHash, common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) check("BaseFee", block.BaseFee(), (*big.Int)(nil)) - check("ExtDataGasUsed", block.ExtDataGasUsed(), (*big.Int)(nil)) - check("BlockGasCost", block.BlockGasCost(), (*big.Int)(nil)) + check("ExtDataGasUsed", BlockExtDataGasUsed(&block), (*big.Int)(nil)) + check("BlockGasCost", BlockGasCost(&block), (*big.Int)(nil)) check("Size", block.Size(), uint64(len(blockEnc))) check("BlockHash", block.Hash(), common.HexToHash("0608e5d5e13c337f226b621a0b08b3d50470f1961329826fd59f5a241d1df49e")) @@ -91,7 +97,7 @@ func TestBlockEncoding(t *testing.T) { func TestEIP1559BlockEncoding(t *testing.T) { blockEnc := common.FromHex("f9032ef9021fa04504ee98a94d16dbd70a35370501a3cb00c2965b012672085fbd328a72962902a00000000000000000000000000000000000000000000000000000000000000000948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000003832fefd8825208845506eb0780a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4a00000000000000000000000000000000000000000000000000000000000000000843b9aca00f90106f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1b8a302f8a0018080843b9aca008301e24194095e7baea6a6c7c4c2dfeb977efac326af552d878080f838f7940000000000000000000000000000000000000001e1a0000000000000000000000000000000000000000000000000000000000000000080a0fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b0a06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a8c08080") - var block Block + var block types.Block if err := rlp.DecodeBytes(blockEnc, &block); err != nil { t.Fatal("decode error: ", err) } @@ -113,21 +119,21 @@ func TestEIP1559BlockEncoding(t *testing.T) { check("Time", block.Time(), uint64(1426516743)) check("Size", block.Size(), uint64(len(blockEnc))) check("BaseFee", block.BaseFee(), new(big.Int).SetUint64(1_000_000_000)) - check("ExtDataGasUsed", block.ExtDataGasUsed(), (*big.Int)(nil)) - check("BlockGasCost", block.BlockGasCost(), (*big.Int)(nil)) + check("ExtDataGasUsed", BlockExtDataGasUsed(&block), (*big.Int)(nil)) + check("BlockGasCost", BlockGasCost(&block), (*big.Int)(nil)) - tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil) - tx1, _ = tx1.WithSignature(HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100")) + tx1 := types.NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil) + tx1, _ = tx1.WithSignature(types.HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100")) addr := common.HexToAddress("0x0000000000000000000000000000000000000001") - accesses := AccessList{AccessTuple{ + accesses := types.AccessList{types.AccessTuple{ Address: addr, StorageKeys: []common.Hash{ {0}, }, }} to := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") - txdata := &DynamicFeeTx{ + txdata := &types.DynamicFeeTx{ ChainID: big.NewInt(1), Nonce: 0, To: &to, @@ -137,8 +143,8 @@ func TestEIP1559BlockEncoding(t *testing.T) { AccessList: accesses, Data: []byte{}, } - tx2 := NewTx(txdata) - tx2, err := tx2.WithSignature(LatestSignerForChainID(big.NewInt(1)), common.Hex2Bytes("fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a800")) + tx2 := types.NewTx(txdata) + tx2, err := tx2.WithSignature(types.LatestSignerForChainID(big.NewInt(1)), common.Hex2Bytes("fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a800")) if err != nil { t.Fatal("invalid signature error: ", err) } @@ -158,7 +164,7 @@ func TestEIP1559BlockEncoding(t *testing.T) { func TestEIP2718BlockEncoding(t *testing.T) { blockEnc := common.FromHex("f9033cf90232a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a0e6e49996c7ec59f7a23d22b83239a60151512c65613bf84a0d7da336399ebc4aa0cafe75574d59780665a97fbfd11365c7545aa8f1abf4e5e12e8243334ef7286bb901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000820200832fefd882a410845506eb0796636f6f6c65737420626c6f636b206f6e20636861696ea0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421f90101f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1b89e01f89b01800a8301e24194095e7baea6a6c7c4c2dfeb977efac326af552d878080f838f7940000000000000000000000000000000000000001e1a0000000000000000000000000000000000000000000000000000000000000000001a03dbacc8d0259f2508625e97fdfc57cd85fdd16e5821bc2c10bdd1a52649e8335a0476e10695b183a87b0aa292a7f4b78ef0c3fbe62aa2c42c84e1d9c3da159ef14c08080") - var block Block + var block types.Block if err := rlp.DecodeBytes(blockEnc, &block); err != nil { t.Fatal("decode error: ", err) } @@ -177,14 +183,14 @@ func TestEIP2718BlockEncoding(t *testing.T) { check("Nonce", block.Nonce(), uint64(0xa13a5a8c8f2bb1c4)) check("Time", block.Time(), uint64(1426516743)) check("Size", block.Size(), uint64(len(blockEnc))) - check("ExtDataHash", block.header.ExtDataHash, common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) + check("ExtDataHash", GetHeaderExtra(block.Header()).ExtDataHash, common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) check("BaseFee", block.BaseFee(), (*big.Int)(nil)) - check("ExtDataGasUsed", block.ExtDataGasUsed(), (*big.Int)(nil)) - check("BlockGasCost", block.BlockGasCost(), (*big.Int)(nil)) + check("ExtDataGasUsed", BlockExtDataGasUsed(&block), (*big.Int)(nil)) + check("BlockGasCost", BlockGasCost(&block), (*big.Int)(nil)) // Create legacy tx. to := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") - tx1 := NewTx(&LegacyTx{ + tx1 := types.NewTx(&types.LegacyTx{ Nonce: 0, To: &to, Value: big.NewInt(10), @@ -192,28 +198,28 @@ func TestEIP2718BlockEncoding(t *testing.T) { GasPrice: big.NewInt(10), }) sig := common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100") - tx1, _ = tx1.WithSignature(HomesteadSigner{}, sig) + tx1, _ = tx1.WithSignature(types.HomesteadSigner{}, sig) // Create ACL tx. addr := common.HexToAddress("0x0000000000000000000000000000000000000001") - tx2 := NewTx(&AccessListTx{ + tx2 := types.NewTx(&types.AccessListTx{ ChainID: big.NewInt(1), Nonce: 0, To: &to, Gas: 123457, GasPrice: big.NewInt(10), - AccessList: AccessList{{Address: addr, StorageKeys: []common.Hash{{0}}}}, + AccessList: types.AccessList{{Address: addr, StorageKeys: []common.Hash{{0}}}}, }) sig2 := common.Hex2Bytes("3dbacc8d0259f2508625e97fdfc57cd85fdd16e5821bc2c10bdd1a52649e8335476e10695b183a87b0aa292a7f4b78ef0c3fbe62aa2c42c84e1d9c3da159ef1401") - tx2, _ = tx2.WithSignature(NewEIP2930Signer(big.NewInt(1)), sig2) + tx2, _ = tx2.WithSignature(types.NewEIP2930Signer(big.NewInt(1)), sig2) check("len(Transactions)", len(block.Transactions()), 2) check("Transactions[0].Hash", block.Transactions()[0].Hash(), tx1.Hash()) check("Transactions[1].Hash", block.Transactions()[1].Hash(), tx2.Hash()) - check("Transactions[1].Type()", block.Transactions()[1].Type(), uint8(AccessListTxType)) + check("Transactions[1].Type()", block.Transactions()[1].Type(), uint8(types.AccessListTxType)) - if !bytes.Equal(block.ExtData(), []byte{}) { - t.Errorf("Block ExtraData field mismatch, expected empty byte array, but found 0x%x", block.ExtData()) + if !bytes.Equal(BlockExtData(&block), []byte{}) { + t.Errorf("Block ExtraData field mismatch, expected empty byte array, but found 0x%x", BlockExtData(&block)) } ourBlockEnc, err := rlp.EncodeToBytes(&block) @@ -227,7 +233,7 @@ func TestEIP2718BlockEncoding(t *testing.T) { func TestBlockEncodingWithExtraData(t *testing.T) { blockEnc := common.FromHex("f903f2f90215a02a0d1d68d26eb213cf1c6c1e6abbaf374f0ee9a5428558df334c36d380c6a080a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0c0caa90fe3722cb2e288f7998d54a855a6d40f67e0e77a695d0d65dad22c6290a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000102837a1200808460674e3380a00000000000000000000000000000000000000000000000000000000000000000880000000000000000a0296ff3bfdebf7c4b1fb71f589d69ed03b1c59b278d1780d54dc86ea7cb87cf17c0c080b901d400000000000000003039c85fc1980a77c5da78fe5486233fc09a769bb812bcb2cc548cf9495d046b3f1bd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf000000028a0f7c3e4d840143671a4c4ecacccb4d60fb97dce97a7aa5d60dfd072a7509cf00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500002d79883d20000000000100000000e0d5c4edc78f594b79025a56c44933c28e8ba3e51e6e23318727eeaac10eb27d00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500002d79883d20000000000100000000000000016dc8ea73dd39ab12fa2ecbc3427abaeb87d56fd800005af3107a4000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000200000009000000010d9f115cd63c3ab78b5b82cfbe4339cd6be87f21cda14cf192b269c7a6cb2d03666aa8f8b23ca0a2ceee4050e75c9b05525a17aa1dd0e9ea391a185ce395943f0000000009000000010d9f115cd63c3ab78b5b82cfbe4339cd6be87f21cda14cf192b269c7a6cb2d03666aa8f8b23ca0a2ceee4050e75c9b05525a17aa1dd0e9ea391a185ce395943f00") - var block Block + var block types.Block if err := rlp.DecodeBytes(blockEnc, &block); err != nil { t.Fatal("decode error: ", err) } @@ -243,7 +249,7 @@ func TestBlockEncodingWithExtraData(t *testing.T) { check("Root", block.Root(), common.HexToHash("c0caa90fe3722cb2e288f7998d54a855a6d40f67e0e77a695d0d65dad22c6290")) check("TxHash", block.TxHash(), common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) check("ReceiptHash", block.ReceiptHash(), common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) - check("Bloom", block.Bloom(), BytesToBloom(common.FromHex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))) + check("Bloom", block.Bloom(), types.BytesToBloom(common.FromHex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"))) check("Difficulty", block.Difficulty(), big.NewInt(1)) check("BlockNumber", block.NumberU64(), uint64(2)) check("GasLimit", block.GasLimit(), uint64(8000000)) @@ -252,10 +258,10 @@ func TestBlockEncodingWithExtraData(t *testing.T) { check("Extra", block.Extra(), common.FromHex("")) check("MixDigest", block.MixDigest(), common.HexToHash("0000000000000000000000000000000000000000000000000000000000000000")) check("Nonce", block.Nonce(), uint64(0)) - check("ExtDataHash", block.header.ExtDataHash, common.HexToHash("296ff3bfdebf7c4b1fb71f589d69ed03b1c59b278d1780d54dc86ea7cb87cf17")) + check("ExtDataHash", GetHeaderExtra(block.Header()).ExtDataHash, common.HexToHash("296ff3bfdebf7c4b1fb71f589d69ed03b1c59b278d1780d54dc86ea7cb87cf17")) check("BaseFee", block.BaseFee(), (*big.Int)(nil)) - check("ExtDataGasUsed", block.ExtDataGasUsed(), (*big.Int)(nil)) - check("BlockGasCost", block.BlockGasCost(), (*big.Int)(nil)) + check("ExtDataGasUsed", BlockExtDataGasUsed(&block), (*big.Int)(nil)) + check("BlockGasCost", BlockGasCost(&block), (*big.Int)(nil)) check("Size", block.Size(), uint64(len(blockEnc))) check("BlockHash", block.Hash(), common.HexToHash("4504ee98a94d16dbd70a35370501a3cb00c2965b012672085fbd328a72962902")) @@ -263,8 +269,8 @@ func TestBlockEncodingWithExtraData(t *testing.T) { check("len(Transactions)", len(block.Transactions()), 0) expectedBlockExtraData := common.FromHex("00000000000000003039c85fc1980a77c5da78fe5486233fc09a769bb812bcb2cc548cf9495d046b3f1bd891ad56056d9c01f18f43f58b5c784ad07a4a49cf3d1f11623804b5cba2c6bf000000028a0f7c3e4d840143671a4c4ecacccb4d60fb97dce97a7aa5d60dfd072a7509cf00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500002d79883d20000000000100000000e0d5c4edc78f594b79025a56c44933c28e8ba3e51e6e23318727eeaac10eb27d00000001dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000500002d79883d20000000000100000000000000016dc8ea73dd39ab12fa2ecbc3427abaeb87d56fd800005af3107a4000dbcf890f77f49b96857648b72b77f9f82937f28a68704af05da0dc12ba53f2db0000000200000009000000010d9f115cd63c3ab78b5b82cfbe4339cd6be87f21cda14cf192b269c7a6cb2d03666aa8f8b23ca0a2ceee4050e75c9b05525a17aa1dd0e9ea391a185ce395943f0000000009000000010d9f115cd63c3ab78b5b82cfbe4339cd6be87f21cda14cf192b269c7a6cb2d03666aa8f8b23ca0a2ceee4050e75c9b05525a17aa1dd0e9ea391a185ce395943f00") - if !bytes.Equal(block.ExtData(), expectedBlockExtraData) { - t.Errorf("Block ExtraData field mismatch, expected 0x%x, but found 0x%x", block.ExtData(), expectedBlockExtraData) + if !bytes.Equal(BlockExtData(&block), expectedBlockExtraData) { + t.Errorf("Block ExtraData field mismatch, expected 0x%x, but found 0x%x", BlockExtData(&block), expectedBlockExtraData) } ourBlockEnc, err := rlp.EncodeToBytes(&block) @@ -277,8 +283,8 @@ func TestBlockEncodingWithExtraData(t *testing.T) { } func TestUncleHash(t *testing.T) { - uncles := make([]*Header, 0) - h := CalcUncleHash(uncles) + uncles := make([]*types.Header, 0) + h := types.CalcUncleHash(uncles) exp := common.HexToHash("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347") if h != exp { t.Fatalf("empty uncle hash is wrong, got %x != %x", h, exp) @@ -299,15 +305,15 @@ func BenchmarkEncodeBlock(b *testing.B) { } } -func makeBenchBlock() *Block { +func makeBenchBlock() *types.Block { var ( key, _ = crypto.GenerateKey() - txs = make([]*Transaction, 70) - receipts = make([]*Receipt, len(txs)) - signer = LatestSigner(params.TestChainConfig) - uncles = make([]*Header, 3) + txs = make([]*types.Transaction, 70) + receipts = make([]*types.Receipt, len(txs)) + signer = types.LatestSigner(params.TestChainConfig) + uncles = make([]*types.Header, 3) ) - header := &Header{ + header := &types.Header{ Difficulty: math.BigPow(11, 11), Number: math.BigPow(2, 9), GasLimit: 12345678, @@ -319,16 +325,16 @@ func makeBenchBlock() *Block { amount := math.BigPow(2, int64(i)) price := big.NewInt(300000) data := make([]byte, 100) - tx := NewTransaction(uint64(i), common.Address{}, amount, 123457, price, data) - signedTx, err := SignTx(tx, signer, key) + tx := types.NewTransaction(uint64(i), common.Address{}, amount, 123457, price, data) + signedTx, err := types.SignTx(tx, signer, key) if err != nil { panic(err) } txs[i] = signedTx - receipts[i] = NewReceipt(make([]byte, 32), false, tx.Gas()) + receipts[i] = types.NewReceipt(make([]byte, 32), false, tx.Gas()) } for i := range uncles { - uncles[i] = &Header{ + uncles[i] = &types.Header{ Difficulty: math.BigPow(11, 11), Number: math.BigPow(2, 9), GasLimit: 12345678, @@ -337,12 +343,12 @@ func makeBenchBlock() *Block { Extra: []byte("benchmark uncle"), } } - return NewBlock(header, txs, uncles, receipts, blocktest.NewHasher()) + return types.NewBlock(header, txs, uncles, receipts, blocktest.NewHasher()) } func TestAP4BlockEncoding(t *testing.T) { blockEnc := common.FromHex("f90335f90226a04504ee98a94d16dbd70a35370501a3cb00c2965b012672085fbd328a72962902a00000000000000000000000000000000000000000000000000000000000000000948888f1f195afa192cfee860698584c030f4c9db1a0ef1552a40b7165c3cd773806b9e0c165b75356e0314bf0706f279c729f51e017a00000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000003832fefd8825208845506eb0780a0bd4472abb6659ebe3ee06ee4d7b72a00a9f4d001caca51342001075469aff49888a13a5a8c8f2bb1c4a00000000000000000000000000000000000000000000000000000000000000000843b9aca008261a8830f4240f90106f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba09bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094fa08a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b1b8a302f8a0018080843b9aca008301e24194095e7baea6a6c7c4c2dfeb977efac326af552d878080f838f7940000000000000000000000000000000000000001e1a0000000000000000000000000000000000000000000000000000000000000000080a0fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b0a06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a8c08080") - var block Block + var block types.Block if err := rlp.DecodeBytes(blockEnc, &block); err != nil { t.Fatal("decode error: ", err) } @@ -365,21 +371,21 @@ func TestAP4BlockEncoding(t *testing.T) { check("Time", block.Time(), uint64(1426516743)) check("Size", block.Size(), uint64(len(blockEnc))) check("BaseFee", block.BaseFee(), big.NewInt(1_000_000_000)) - check("ExtDataGasUsed", block.ExtDataGasUsed(), big.NewInt(25_000)) - check("BlockGasCost", block.BlockGasCost(), big.NewInt(1_000_000)) + check("ExtDataGasUsed", BlockExtDataGasUsed(&block), big.NewInt(25_000)) + check("BlockGasCost", BlockGasCost(&block), big.NewInt(1_000_000)) - tx1 := NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil) - tx1, _ = tx1.WithSignature(HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100")) + tx1 := types.NewTransaction(0, common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), big.NewInt(10), 50000, big.NewInt(10), nil) + tx1, _ = tx1.WithSignature(types.HomesteadSigner{}, common.Hex2Bytes("9bea4c4daac7c7c52e093e6a4c35dbbcf8856f1af7b059ba20253e70848d094f8a8fae537ce25ed8cb5af9adac3f141af69bd515bd2ba031522df09b97dd72b100")) addr := common.HexToAddress("0x0000000000000000000000000000000000000001") - accesses := AccessList{AccessTuple{ + accesses := types.AccessList{types.AccessTuple{ Address: addr, StorageKeys: []common.Hash{ {0}, }, }} to := common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") - txdata := &DynamicFeeTx{ + txdata := &types.DynamicFeeTx{ ChainID: big.NewInt(1), Nonce: 0, To: &to, @@ -389,8 +395,8 @@ func TestAP4BlockEncoding(t *testing.T) { AccessList: accesses, Data: []byte{}, } - tx2 := NewTx(txdata) - tx2, err := tx2.WithSignature(LatestSignerForChainID(big.NewInt(1)), common.Hex2Bytes("fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a800")) + tx2 := types.NewTx(txdata) + tx2, err := tx2.WithSignature(types.LatestSignerForChainID(big.NewInt(1)), common.Hex2Bytes("fe38ca4e44a30002ac54af7cf922a6ac2ba11b7d22f548e8ecb3f51f41cb31b06de6a5cbae13c0c856e33acf021b51819636cfc009d39eafb9f606d546e305a800")) if err != nil { t.Fatal("invalid signature error: ", err) } diff --git a/plugin/evm/customtypes/gen_header_serializable_json.go b/plugin/evm/customtypes/gen_header_serializable_json.go new file mode 100644 index 0000000000..42b7c61f72 --- /dev/null +++ b/plugin/evm/customtypes/gen_header_serializable_json.go @@ -0,0 +1,182 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package customtypes + +import ( + "encoding/json" + "errors" + "math/big" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" +) + +var _ = (*headerMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (h HeaderSerializable) MarshalJSON() ([]byte, error) { + type HeaderSerializable struct { + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom types.Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce types.BlockNonce `json:"nonce"` + ExtDataHash common.Hash `json:"extDataHash" gencodec:"required"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + ExtDataGasUsed *hexutil.Big `json:"extDataGasUsed" rlp:"optional"` + BlockGasCost *hexutil.Big `json:"blockGasCost" rlp:"optional"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` + ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` + Hash common.Hash `json:"hash"` + } + var enc HeaderSerializable + enc.ParentHash = h.ParentHash + enc.UncleHash = h.UncleHash + enc.Coinbase = h.Coinbase + enc.Root = h.Root + enc.TxHash = h.TxHash + enc.ReceiptHash = h.ReceiptHash + enc.Bloom = h.Bloom + enc.Difficulty = (*hexutil.Big)(h.Difficulty) + enc.Number = (*hexutil.Big)(h.Number) + enc.GasLimit = hexutil.Uint64(h.GasLimit) + enc.GasUsed = hexutil.Uint64(h.GasUsed) + enc.Time = hexutil.Uint64(h.Time) + enc.Extra = h.Extra + enc.MixDigest = h.MixDigest + enc.Nonce = h.Nonce + enc.ExtDataHash = h.ExtDataHash + enc.BaseFee = (*hexutil.Big)(h.BaseFee) + enc.ExtDataGasUsed = (*hexutil.Big)(h.ExtDataGasUsed) + enc.BlockGasCost = (*hexutil.Big)(h.BlockGasCost) + enc.BlobGasUsed = (*hexutil.Uint64)(h.BlobGasUsed) + enc.ExcessBlobGas = (*hexutil.Uint64)(h.ExcessBlobGas) + enc.ParentBeaconRoot = h.ParentBeaconRoot + enc.Hash = h.Hash() + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (h *HeaderSerializable) UnmarshalJSON(input []byte) error { + type HeaderSerializable struct { + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + UncleHash *common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase *common.Address `json:"miner" gencodec:"required"` + Root *common.Hash `json:"stateRoot" gencodec:"required"` + TxHash *common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash *common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom *types.Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` + Number *hexutil.Big `json:"number" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Time *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + Extra *hexutil.Bytes `json:"extraData" gencodec:"required"` + MixDigest *common.Hash `json:"mixHash"` + Nonce *types.BlockNonce `json:"nonce"` + ExtDataHash *common.Hash `json:"extDataHash" gencodec:"required"` + BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` + ExtDataGasUsed *hexutil.Big `json:"extDataGasUsed" rlp:"optional"` + BlockGasCost *hexutil.Big `json:"blockGasCost" rlp:"optional"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed" rlp:"optional"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas" rlp:"optional"` + ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` + } + var dec HeaderSerializable + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ParentHash == nil { + return errors.New("missing required field 'parentHash' for HeaderSerializable") + } + h.ParentHash = *dec.ParentHash + if dec.UncleHash == nil { + return errors.New("missing required field 'sha3Uncles' for HeaderSerializable") + } + h.UncleHash = *dec.UncleHash + if dec.Coinbase == nil { + return errors.New("missing required field 'miner' for HeaderSerializable") + } + h.Coinbase = *dec.Coinbase + if dec.Root == nil { + return errors.New("missing required field 'stateRoot' for HeaderSerializable") + } + h.Root = *dec.Root + if dec.TxHash == nil { + return errors.New("missing required field 'transactionsRoot' for HeaderSerializable") + } + h.TxHash = *dec.TxHash + if dec.ReceiptHash == nil { + return errors.New("missing required field 'receiptsRoot' for HeaderSerializable") + } + h.ReceiptHash = *dec.ReceiptHash + if dec.Bloom == nil { + return errors.New("missing required field 'logsBloom' for HeaderSerializable") + } + h.Bloom = *dec.Bloom + if dec.Difficulty == nil { + return errors.New("missing required field 'difficulty' for HeaderSerializable") + } + h.Difficulty = (*big.Int)(dec.Difficulty) + if dec.Number == nil { + return errors.New("missing required field 'number' for HeaderSerializable") + } + h.Number = (*big.Int)(dec.Number) + if dec.GasLimit == nil { + return errors.New("missing required field 'gasLimit' for HeaderSerializable") + } + h.GasLimit = uint64(*dec.GasLimit) + if dec.GasUsed == nil { + return errors.New("missing required field 'gasUsed' for HeaderSerializable") + } + h.GasUsed = uint64(*dec.GasUsed) + if dec.Time == nil { + return errors.New("missing required field 'timestamp' for HeaderSerializable") + } + h.Time = uint64(*dec.Time) + if dec.Extra == nil { + return errors.New("missing required field 'extraData' for HeaderSerializable") + } + h.Extra = *dec.Extra + if dec.MixDigest != nil { + h.MixDigest = *dec.MixDigest + } + if dec.Nonce != nil { + h.Nonce = *dec.Nonce + } + if dec.ExtDataHash == nil { + return errors.New("missing required field 'extDataHash' for HeaderSerializable") + } + h.ExtDataHash = *dec.ExtDataHash + if dec.BaseFee != nil { + h.BaseFee = (*big.Int)(dec.BaseFee) + } + if dec.ExtDataGasUsed != nil { + h.ExtDataGasUsed = (*big.Int)(dec.ExtDataGasUsed) + } + if dec.BlockGasCost != nil { + h.BlockGasCost = (*big.Int)(dec.BlockGasCost) + } + if dec.BlobGasUsed != nil { + h.BlobGasUsed = (*uint64)(dec.BlobGasUsed) + } + if dec.ExcessBlobGas != nil { + h.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) + } + if dec.ParentBeaconRoot != nil { + h.ParentBeaconRoot = dec.ParentBeaconRoot + } + return nil +} diff --git a/core/types/gen_header_rlp.go b/plugin/evm/customtypes/gen_header_serializable_rlp.go similarity index 94% rename from core/types/gen_header_rlp.go rename to plugin/evm/customtypes/gen_header_serializable_rlp.go index 711a33b8ca..7768d81f26 100644 --- a/core/types/gen_header_rlp.go +++ b/plugin/evm/customtypes/gen_header_serializable_rlp.go @@ -1,11 +1,11 @@ // Code generated by rlpgen. DO NOT EDIT. -package types +package customtypes -import "github.com/ethereum/go-ethereum/rlp" +import "github.com/ava-labs/libevm/rlp" import "io" -func (obj *Header) EncodeRLP(_w io.Writer) error { +func (obj *HeaderSerializable) EncodeRLP(_w io.Writer) error { w := rlp.NewEncoderBuffer(_w) _tmp0 := w.List() w.WriteBytes(obj.ParentHash[:]) diff --git a/plugin/evm/customtypes/hashes_ext.go b/plugin/evm/customtypes/hashes_ext.go new file mode 100644 index 0000000000..7e3a537ff3 --- /dev/null +++ b/plugin/evm/customtypes/hashes_ext.go @@ -0,0 +1,7 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customtypes + +// EmptyExtDataHash is the known hash of empty extdata bytes. +var EmptyExtDataHash = rlpHash([]byte(nil)) diff --git a/core/vm/stack_table.go b/plugin/evm/customtypes/hashing.go similarity index 63% rename from core/vm/stack_table.go rename to plugin/evm/customtypes/hashing.go index 487acaefdb..d2141526d2 100644 --- a/core/vm/stack_table.go +++ b/plugin/evm/customtypes/hashing.go @@ -1,4 +1,4 @@ -// (c) 2019-2020, Ava Labs, Inc. +// (c) 2019-2021, Ava Labs, Inc. // // This file is a derived work, based on the go-ethereum library whose original // notices appear below. @@ -8,7 +8,7 @@ // // Much love to the original authors for their work. // ********** -// Copyright 2017 The go-ethereum Authors +// Copyright 2021 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -24,29 +24,28 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package vm +package customtypes import ( - "github.com/ava-labs/coreth/params" -) + "sync" -func minSwapStack(n int) int { - return minStack(n, n) -} -func maxSwapStack(n int) int { - return maxStack(n, n) -} + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" + "golang.org/x/crypto/sha3" +) -func minDupStack(n int) int { - return minStack(n, n+1) -} -func maxDupStack(n int) int { - return maxStack(n, n+1) +// hasherPool holds LegacyKeccak256 hashers for rlpHash. +var hasherPool = sync.Pool{ + New: func() interface{} { return sha3.NewLegacyKeccak256() }, } -func maxStack(pop, push int) int { - return int(params.StackLimit) + pop - push -} -func minStack(pops, push int) int { - return pops +// rlpHash encodes x and hashes the encoded bytes. +func rlpHash(x interface{}) (h common.Hash) { + sha := hasherPool.Get().(crypto.KeccakState) + defer hasherPool.Put(sha) + sha.Reset() + rlp.Encode(sha, x) + sha.Read(h[:]) + return h } diff --git a/core/types/hashing_test.go b/plugin/evm/customtypes/hashing_test.go similarity index 95% rename from core/types/hashing_test.go rename to plugin/evm/customtypes/hashing_test.go index 82e17b817f..31c15e2d61 100644 --- a/core/types/hashing_test.go +++ b/plugin/evm/customtypes/hashing_test.go @@ -24,7 +24,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package types_test +package customtypes_test import ( "bytes" @@ -34,14 +34,14 @@ import ( mrand "math/rand" "testing" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" ) func TestDeriveSha(t *testing.T) { diff --git a/plugin/evm/customtypes/header_ext.go b/plugin/evm/customtypes/header_ext.go new file mode 100644 index 0000000000..e2898a58bd --- /dev/null +++ b/plugin/evm/customtypes/header_ext.go @@ -0,0 +1,235 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customtypes + +import ( + "io" + "math/big" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + ethtypes "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" +) + +// GetHeaderExtra returns the [HeaderExtra] from the given [Header]. +func GetHeaderExtra(h *ethtypes.Header) *HeaderExtra { + return extras.Header.Get(h) +} + +// SetHeaderExtra sets the given [HeaderExtra] on the [Header]. +func SetHeaderExtra(h *ethtypes.Header, extra *HeaderExtra) { + extras.Header.Set(h, extra) +} + +// WithHeaderExtra sets the given [HeaderExtra] on the [Header] +// and returns the [Header] for chaining. +func WithHeaderExtra(h *ethtypes.Header, extra *HeaderExtra) *ethtypes.Header { + SetHeaderExtra(h, extra) + return h +} + +// HeaderExtra is a struct that contains extra fields used by Avalanche +// in the block header. +// This type uses [HeaderSerializable] to encode and decode the extra fields +// along with the upstream type for compatibility with existing network blocks. +type HeaderExtra struct { + ExtDataHash common.Hash + ExtDataGasUsed *big.Int + BlockGasCost *big.Int +} + +// EncodeRLP RLP encodes the given [ethtypes.Header] and [HeaderExtra] together +// to the `writer`. It does merge both structs into a single [HeaderSerializable]. +func (h *HeaderExtra) EncodeRLP(eth *ethtypes.Header, writer io.Writer) error { + temp := new(HeaderSerializable) + + temp.updateFromEth(eth) + temp.updateFromExtras(h) + + return rlp.Encode(writer, temp) +} + +// DecodeRLP RLP decodes from the [*rlp.Stream] and writes the output to both the +// [ethtypes.Header] passed as argument and to the receiver [HeaderExtra]. +func (h *HeaderExtra) DecodeRLP(eth *ethtypes.Header, stream *rlp.Stream) error { + temp := new(HeaderSerializable) + if err := stream.Decode(temp); err != nil { + return err + } + + temp.updateToEth(eth) + temp.updateToExtras(h) + + return nil +} + +// EncodeJSON JSON encodes the given [ethtypes.Header] and [HeaderExtra] together +// to the `writer`. It does merge both structs into a single [HeaderSerializable]. +func (h *HeaderExtra) EncodeJSON(eth *ethtypes.Header) ([]byte, error) { + temp := new(HeaderSerializable) + + temp.updateFromEth(eth) + temp.updateFromExtras(h) + + return temp.MarshalJSON() +} + +// DecodeJSON JSON decodes from the `input` bytes and writes the output to both the +// [ethtypes.Header] passed as argument and to the receiver [HeaderExtra]. +func (h *HeaderExtra) DecodeJSON(eth *ethtypes.Header, input []byte) error { + temp := new(HeaderSerializable) + if err := temp.UnmarshalJSON(input); err != nil { + return err + } + + temp.updateToEth(eth) + temp.updateToExtras(h) + + return nil +} + +func (h *HeaderExtra) PostCopy(dst *ethtypes.Header) { + cp := &HeaderExtra{ + ExtDataHash: h.ExtDataHash, + } + if h.BlockGasCost != nil { + cp.BlockGasCost = new(big.Int).Set(h.BlockGasCost) + } + if h.ExtDataGasUsed != nil { + cp.ExtDataGasUsed = new(big.Int).Set(h.ExtDataGasUsed) + } + SetHeaderExtra(dst, cp) +} + +func (h *HeaderSerializable) updateFromEth(eth *ethtypes.Header) { + h.ParentHash = eth.ParentHash + h.UncleHash = eth.UncleHash + h.Coinbase = eth.Coinbase + h.Root = eth.Root + h.TxHash = eth.TxHash + h.ReceiptHash = eth.ReceiptHash + h.Bloom = eth.Bloom + h.Difficulty = eth.Difficulty + h.Number = eth.Number + h.GasLimit = eth.GasLimit + h.GasUsed = eth.GasUsed + h.Time = eth.Time + h.Extra = eth.Extra + h.MixDigest = eth.MixDigest + h.Nonce = eth.Nonce + h.BaseFee = eth.BaseFee + h.BlobGasUsed = eth.BlobGasUsed + h.ExcessBlobGas = eth.ExcessBlobGas + h.ParentBeaconRoot = eth.ParentBeaconRoot +} + +func (h *HeaderSerializable) updateToEth(eth *ethtypes.Header) { + eth.ParentHash = h.ParentHash + eth.UncleHash = h.UncleHash + eth.Coinbase = h.Coinbase + eth.Root = h.Root + eth.TxHash = h.TxHash + eth.ReceiptHash = h.ReceiptHash + eth.Bloom = h.Bloom + eth.Difficulty = h.Difficulty + eth.Number = h.Number + eth.GasLimit = h.GasLimit + eth.GasUsed = h.GasUsed + eth.Time = h.Time + eth.Extra = h.Extra + eth.MixDigest = h.MixDigest + eth.Nonce = h.Nonce + eth.BaseFee = h.BaseFee + eth.BlobGasUsed = h.BlobGasUsed + eth.ExcessBlobGas = h.ExcessBlobGas + eth.ParentBeaconRoot = h.ParentBeaconRoot +} + +func (h *HeaderSerializable) updateFromExtras(extras *HeaderExtra) { + h.ExtDataHash = extras.ExtDataHash + h.ExtDataGasUsed = extras.ExtDataGasUsed + h.BlockGasCost = extras.BlockGasCost +} + +func (h *HeaderSerializable) updateToExtras(extras *HeaderExtra) { + extras.ExtDataHash = h.ExtDataHash + extras.ExtDataGasUsed = h.ExtDataGasUsed + extras.BlockGasCost = h.BlockGasCost +} + +// NOTE: both generators currently do not support type aliases. +// We are using custom versions of these programs for now to support type aliases, +// see https://github.com/ava-labs/coreth/pull/746#discussion_r1969673252 +//go:generate go run github.com/fjl/gencodec -type HeaderSerializable -field-override headerMarshaling -out gen_header_serializable_json.go +//go:generate go run github.com/ava-labs/libevm/rlp/rlpgen -type HeaderSerializable -out gen_header_serializable_rlp.go + +// HeaderSerializable defines the header of a block in the Ethereum blockchain, +// as it is to be serialized into RLP and JSON. Note it must be exported so that +// rlpgen can generate the serialization code from it. +type HeaderSerializable struct { + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` + Coinbase common.Address `json:"miner" gencodec:"required"` + Root common.Hash `json:"stateRoot" gencodec:"required"` + TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` + ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` + Bloom ethtypes.Bloom `json:"logsBloom" gencodec:"required"` + Difficulty *big.Int `json:"difficulty" gencodec:"required"` + Number *big.Int `json:"number" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Time uint64 `json:"timestamp" gencodec:"required"` + Extra []byte `json:"extraData" gencodec:"required"` + MixDigest common.Hash `json:"mixHash"` + Nonce ethtypes.BlockNonce `json:"nonce"` + ExtDataHash common.Hash `json:"extDataHash" gencodec:"required"` + + // BaseFee was added by EIP-1559 and is ignored in legacy headers. + BaseFee *big.Int `json:"baseFeePerGas" rlp:"optional"` + + // ExtDataGasUsed was added by Apricot Phase 4 and is ignored in legacy + // headers. + // + // It is not a uint64 like GasLimit or GasUsed because it is not possible to + // correctly encode this field optionally with uint64. + ExtDataGasUsed *big.Int `json:"extDataGasUsed" rlp:"optional"` + + // BlockGasCost was added by Apricot Phase 4 and is ignored in legacy + // headers. + BlockGasCost *big.Int `json:"blockGasCost" rlp:"optional"` + + // BlobGasUsed was added by EIP-4844 and is ignored in legacy headers. + BlobGasUsed *uint64 `json:"blobGasUsed" rlp:"optional"` + + // ExcessBlobGas was added by EIP-4844 and is ignored in legacy headers. + ExcessBlobGas *uint64 `json:"excessBlobGas" rlp:"optional"` + + // ParentBeaconRoot was added by EIP-4788 and is ignored in legacy headers. + ParentBeaconRoot *common.Hash `json:"parentBeaconBlockRoot" rlp:"optional"` +} + +// field type overrides for gencodec +type headerMarshaling struct { + Difficulty *hexutil.Big + Number *hexutil.Big + GasLimit hexutil.Uint64 + GasUsed hexutil.Uint64 + Time hexutil.Uint64 + Extra hexutil.Bytes + BaseFee *hexutil.Big + ExtDataGasUsed *hexutil.Big + BlockGasCost *hexutil.Big + Hash common.Hash `json:"hash"` // adds call to Hash() in MarshalJSON + BlobGasUsed *hexutil.Uint64 + ExcessBlobGas *hexutil.Uint64 +} + +// Hash returns the block hash of the header, which is simply the keccak256 hash of its +// RLP encoding. +// This function MUST be exported and is used in [HeaderSerializable.EncodeJSON] which is +// generated to the file gen_header_json.go. +func (h *HeaderSerializable) Hash() common.Hash { + return rlpHash(h) +} diff --git a/plugin/evm/customtypes/header_ext_test.go b/plugin/evm/customtypes/header_ext_test.go new file mode 100644 index 0000000000..24363a4108 --- /dev/null +++ b/plugin/evm/customtypes/header_ext_test.go @@ -0,0 +1,193 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customtypes + +import ( + "encoding/hex" + "encoding/json" + "math/big" + "reflect" + "slices" + "testing" + "unsafe" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/rlp" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + // TODO(arr4n) These tests were originally part of the `coreth/core/types` + // package so assume the presence of identifiers. A dot-import reduces PR + // noise during the refactoring. + . "github.com/ava-labs/libevm/core/types" +) + +func TestHeaderRLP(t *testing.T) { + t.Parallel() + + got := testHeaderEncodeDecode(t, rlp.EncodeToBytes, rlp.DecodeBytes) + + // Golden data from original coreth implementation, before integration of + // libevm. WARNING: changing these values can break backwards compatibility + // with extreme consequences as block-hash calculation may break. + const ( + wantHex = "f90234a00100000000000000000000000000000000000000000000000000000000000000a00200000000000000000000000000000000000000000000000000000000000000940300000000000000000000000000000000000000a00400000000000000000000000000000000000000000000000000000000000000a00500000000000000000000000000000000000000000000000000000000000000a00600000000000000000000000000000000000000000000000000000000000000b901000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008090a0b0c0da00e00000000000000000000000000000000000000000000000000000000000000880f00000000000000a015000000000000000000000000000000000000000000000000000000000000001016171213a01400000000000000000000000000000000000000000000000000000000000000" + wantHashHex = "7b63c1c763cc1527f12de7e5331b92d66ea201d1e6d7cd65a79bf8e3b99c104d" + ) + + assert.Equal(t, wantHex, hex.EncodeToString(got), "Header RLP") + + header, _ := headerWithNonZeroFields() + gotHashHex := header.Hash().Hex() + assert.Equal(t, "0x"+wantHashHex, gotHashHex, "Header.Hash()") +} + +func TestHeaderJSON(t *testing.T) { + t.Parallel() + + // Note we ignore the returned encoded bytes because we don't + // need to compare them to a JSON gold standard. + _ = testHeaderEncodeDecode(t, json.Marshal, json.Unmarshal) +} + +func testHeaderEncodeDecode( + t *testing.T, + encode func(any) ([]byte, error), + decode func([]byte, any) error, +) (encoded []byte) { + t.Helper() + + input, _ := headerWithNonZeroFields() // the Header carries the HeaderExtra so we can ignore it + encoded, err := encode(input) + require.NoError(t, err, "encode") + + gotHeader := new(Header) + err = decode(encoded, gotHeader) + require.NoError(t, err, "decode") + gotExtra := GetHeaderExtra(gotHeader) + + wantHeader, wantExtra := headerWithNonZeroFields() + wantHeader.WithdrawalsHash = nil + assert.Equal(t, wantHeader, gotHeader) + assert.Equal(t, wantExtra, gotExtra) + + return encoded +} + +func TestHeaderWithNonZeroFields(t *testing.T) { + t.Parallel() + + header, extra := headerWithNonZeroFields() + t.Run("Header", func(t *testing.T) { allFieldsSet(t, header, "extra") }) + t.Run("HeaderExtra", func(t *testing.T) { allFieldsSet(t, extra) }) +} + +// headerWithNonZeroFields returns a [Header] and a [HeaderExtra], +// each with all fields set to non-zero values. +// The [HeaderExtra] extra payload is set in the [Header] via [WithHeaderExtra]. +// +// NOTE: They can be used to demonstrate that RLP and JSON round-trip encoding +// can recover all fields, but not that the encoded format is correct. This is +// very important as the RLP encoding of a [Header] defines its hash. +func headerWithNonZeroFields() (*Header, *HeaderExtra) { + header := &Header{ + ParentHash: common.Hash{1}, + UncleHash: common.Hash{2}, + Coinbase: common.Address{3}, + Root: common.Hash{4}, + TxHash: common.Hash{5}, + ReceiptHash: common.Hash{6}, + Bloom: Bloom{7}, + Difficulty: big.NewInt(8), + Number: big.NewInt(9), + GasLimit: 10, + GasUsed: 11, + Time: 12, + Extra: []byte{13}, + MixDigest: common.Hash{14}, + Nonce: BlockNonce{15}, + BaseFee: big.NewInt(16), + WithdrawalsHash: &common.Hash{17}, + BlobGasUsed: ptrTo(uint64(18)), + ExcessBlobGas: ptrTo(uint64(19)), + ParentBeaconRoot: &common.Hash{20}, + } + extra := &HeaderExtra{ + ExtDataHash: common.Hash{21}, + ExtDataGasUsed: big.NewInt(22), + BlockGasCost: big.NewInt(23), + } + return WithHeaderExtra(header, extra), extra +} + +func allFieldsSet[T interface { + Header | HeaderExtra | Block | Body | BlockBodyExtra +}](t *testing.T, x *T, ignoredFields ...string) { + // We don't test for nil pointers because we're only confirming that + // test-input data is well-formed. A panic due to a dereference will be + // reported anyway. + + v := reflect.ValueOf(x).Elem() + for i := range v.Type().NumField() { + field := v.Type().Field(i) + if slices.Contains(ignoredFields, field.Name) { + continue + } + + t.Run(field.Name, func(t *testing.T) { + fieldValue := v.Field(i) + if !field.IsExported() { + // Note: we need to check unexported fields especially for [Block]. + if fieldValue.Kind() == reflect.Ptr { + require.Falsef(t, fieldValue.IsNil(), "field %q is nil", field.Name) + } + fieldValue = reflect.NewAt(fieldValue.Type(), unsafe.Pointer(fieldValue.UnsafeAddr())).Elem() //nolint:gosec + } + + switch f := fieldValue.Interface().(type) { + case common.Hash: + assertNonZero(t, f) + case common.Address: + assertNonZero(t, f) + case BlockNonce: + assertNonZero(t, f) + case Bloom: + assertNonZero(t, f) + case uint32: + assertNonZero(t, f) + case uint64: + assertNonZero(t, f) + case *big.Int: + assertNonZero(t, f) + case *common.Hash: + assertNonZero(t, f) + case *uint64: + assertNonZero(t, f) + case *[]uint8: + assertNonZero(t, f) + case *Header: + assertNonZero(t, f) + case []uint8, []*Header, Transactions, []*Transaction, Withdrawals, []*Withdrawal: + assert.NotEmpty(t, f) + default: + t.Errorf("Field %q has unsupported type %T", field.Name, f) + } + }) + } +} + +func assertNonZero[T interface { + common.Hash | common.Address | BlockNonce | uint32 | uint64 | Bloom | + *big.Int | *common.Hash | *uint64 | *[]uint8 | *Header +}](t *testing.T, v T) { + t.Helper() + var zero T + if v == zero { + t.Errorf("must not be zero value for %T", v) + } +} + +// Note [TestCopyHeader] tests the [HeaderExtra.PostCopy] method. + +func ptrTo[T any](x T) *T { return &x } diff --git a/plugin/evm/customtypes/libevm.go b/plugin/evm/customtypes/libevm.go new file mode 100644 index 0000000000..3f93dc7acd --- /dev/null +++ b/plugin/evm/customtypes/libevm.go @@ -0,0 +1,14 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customtypes + +import ( + ethtypes "github.com/ava-labs/libevm/core/types" +) + +var extras = ethtypes.RegisterExtras[ + HeaderExtra, *HeaderExtra, + BlockBodyExtra, *BlockBodyExtra, + isMultiCoin, +]() diff --git a/plugin/evm/customtypes/log_ext.go b/plugin/evm/customtypes/log_ext.go new file mode 100644 index 0000000000..25fab842e0 --- /dev/null +++ b/plugin/evm/customtypes/log_ext.go @@ -0,0 +1,14 @@ +// (c) 2019-2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. +package customtypes + +import ethtypes "github.com/ava-labs/libevm/core/types" + +// FlattenLogs converts a nested array of logs to a single array of logs. +func FlattenLogs(list [][]*ethtypes.Log) []*ethtypes.Log { + var flat []*ethtypes.Log + for _, logs := range list { + flat = append(flat, logs...) + } + return flat +} diff --git a/core/types/rlp_fuzzer_test.go b/plugin/evm/customtypes/rlp_fuzzer_test.go similarity index 91% rename from core/types/rlp_fuzzer_test.go rename to plugin/evm/customtypes/rlp_fuzzer_test.go index a3b9f72436..2ea84f181f 100644 --- a/core/types/rlp_fuzzer_test.go +++ b/plugin/evm/customtypes/rlp_fuzzer_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package types +package customtypes import ( "bytes" @@ -22,8 +22,13 @@ import ( "math/big" "testing" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/rlp" "github.com/holiman/uint256" + + // TODO(arr4n) These tests were originally part of the `coreth/core/types` + // package so assume the presence of identifiers. A dot-import reduces PR + // noise during the refactoring. + . "github.com/ava-labs/libevm/core/types" ) func decodeEncode(input []byte, val interface{}) error { diff --git a/plugin/evm/customtypes/state_account_ext.go b/plugin/evm/customtypes/state_account_ext.go new file mode 100644 index 0000000000..8006c9ba32 --- /dev/null +++ b/plugin/evm/customtypes/state_account_ext.go @@ -0,0 +1,16 @@ +// (c) 2025, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package customtypes + +import ( + ethtypes "github.com/ava-labs/libevm/core/types" +) + +type isMultiCoin bool + +var IsMultiCoinPayloads = extras.StateAccount + +func IsMultiCoin(s ethtypes.StateOrSlimAccount) bool { + return bool(IsMultiCoinPayloads.Get(s)) +} diff --git a/core/types/types_test.go b/plugin/evm/customtypes/types_test.go similarity index 91% rename from core/types/types_test.go rename to plugin/evm/customtypes/types_test.go index 7b68db9b4b..2ff4d47a69 100644 --- a/core/types/types_test.go +++ b/plugin/evm/customtypes/types_test.go @@ -24,15 +24,20 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package types +package customtypes import ( "math/big" "testing" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" + + // TODO(arr4n) These tests were originally part of the `coreth/core/types` + // package so assume the presence of identifiers. A dot-import reduces PR + // noise during the refactoring. + . "github.com/ava-labs/libevm/core/types" ) type devnull struct{ len int } diff --git a/plugin/evm/database/wrapped_database.go b/plugin/evm/database/wrapped_database.go index f8a36913bb..86e3bbd239 100644 --- a/plugin/evm/database/wrapped_database.go +++ b/plugin/evm/database/wrapped_database.go @@ -7,7 +7,7 @@ import ( "errors" "github.com/ava-labs/avalanchego/database" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/ethdb" ) var ( diff --git a/plugin/evm/export_tx_test.go b/plugin/evm/export_tx_test.go index dd6ff84fb3..91c23aeae8 100644 --- a/plugin/evm/export_tx_test.go +++ b/plugin/evm/export_tx_test.go @@ -17,10 +17,10 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/vms/components/avax" "github.com/ava-labs/avalanchego/vms/secp256k1fx" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/holiman/uint256" ) @@ -532,7 +532,7 @@ func TestExportTxSemanticVerify(t *testing.T) { tx *atomic.Tx signers [][]*secp256k1.PrivateKey baseFee *big.Int - rules params.Rules + rules extras.Rules shouldErr bool }{ { @@ -1648,7 +1648,7 @@ func TestNewExportTx(t *testing.T) { tests := []struct { name string genesis string - rules params.Rules + rules extras.Rules bal uint64 expectedBurnedAVAX uint64 }{ @@ -1835,7 +1835,7 @@ func TestNewExportTxMulticoin(t *testing.T) { tests := []struct { name string genesis string - rules params.Rules + rules extras.Rules bal uint64 balmc uint64 }{ diff --git a/plugin/evm/ext_data_hashes.go b/plugin/evm/ext_data_hashes.go index 7648c3bcdb..ae2b4612cc 100644 --- a/plugin/evm/ext_data_hashes.go +++ b/plugin/evm/ext_data_hashes.go @@ -4,7 +4,7 @@ import ( _ "embed" "encoding/json" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) var ( diff --git a/plugin/evm/gossip.go b/plugin/evm/gossip.go index e1bf58b0fc..327e8d30b5 100644 --- a/plugin/evm/gossip.go +++ b/plugin/evm/gossip.go @@ -12,8 +12,8 @@ import ( "sync/atomic" "time" - ethcommon "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + ethcommon "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/avalanchego/ids" @@ -24,9 +24,9 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth" "github.com/ava-labs/coreth/plugin/evm/config" + "github.com/ava-labs/libevm/core/types" ) const pendingTxsBuffer = 10 diff --git a/plugin/evm/gossip_test.go b/plugin/evm/gossip_test.go index 807d03b5df..5d5df6eec2 100644 --- a/plugin/evm/gossip_test.go +++ b/plugin/evm/gossip_test.go @@ -12,15 +12,15 @@ import ( "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/txpool" "github.com/ava-labs/coreth/core/txpool/legacypool" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/plugin/evm/gossiper_eth_gossiping_test.go b/plugin/evm/gossiper_eth_gossiping_test.go index 47416f0bf1..28a0b62e98 100644 --- a/plugin/evm/gossiper_eth_gossiping_test.go +++ b/plugin/evm/gossiper_eth_gossiping_test.go @@ -18,14 +18,14 @@ import ( commonEng "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/assert" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/libevm/core/types" ) func fundAddressByGenesis(addrs []common.Address) (string, error) { @@ -34,9 +34,9 @@ func fundAddressByGenesis(addrs []common.Address) (string, error) { Difficulty: common.Big0, GasLimit: uint64(5000000), } - funds := make(map[common.Address]types.GenesisAccount) + funds := make(map[common.Address]types.Account) for _, addr := range addrs { - funds[addr] = types.GenesisAccount{ + funds[addr] = types.Account{ Balance: balance, } } diff --git a/plugin/evm/header/base_fee.go b/plugin/evm/header/base_fee.go index a9a8f0126b..73494217c1 100644 --- a/plugin/evm/header/base_fee.go +++ b/plugin/evm/header/base_fee.go @@ -8,8 +8,8 @@ import ( "fmt" "math/big" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/libevm/core/types" ) var errEstimateBaseFeeWithoutActivation = errors.New("cannot estimate base fee for chain without apricot phase 3 scheduled") @@ -19,7 +19,7 @@ var errEstimateBaseFeeWithoutActivation = errors.New("cannot estimate base fee f // // Prior to AP3, the returned base fee will be nil. func BaseFee( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, timestamp uint64, ) (*big.Int, error) { @@ -48,7 +48,7 @@ func BaseFee( // Warning: This function should only be used in estimation and should not be // used when calculating the canonical base fee for a block. func EstimateNextBaseFee( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, timestamp uint64, ) (*big.Int, error) { diff --git a/plugin/evm/header/base_fee_test.go b/plugin/evm/header/base_fee_test.go index 3193f5cdd6..a04a4026b9 100644 --- a/plugin/evm/header/base_fee_test.go +++ b/plugin/evm/header/base_fee_test.go @@ -8,22 +8,23 @@ import ( "testing" "github.com/ava-labs/avalanchego/vms/components/gas" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/plugin/evm/upgrade/etna" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" ) func TestBaseFee(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header timestamp uint64 want *big.Int @@ -31,13 +32,13 @@ func TestBaseFee(t *testing.T) { }{ { name: "ap2", - upgrades: params.TestApricotPhase2Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase2Config.NetworkUpgrades, want: nil, wantErr: nil, }, { name: "ap3_first_block", - upgrades: params.NetworkUpgrades{ + upgrades: extras.NetworkUpgrades{ ApricotPhase3BlockTimestamp: utils.NewUint64(1), }, parent: &types.Header{ @@ -48,7 +49,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_genesis_block", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -56,7 +57,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_invalid_fee_window", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -64,7 +65,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_invalid_timestamp", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Time: 1, @@ -75,7 +76,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_no_change", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas - ap3.IntrinsicBlockGas, @@ -88,7 +89,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_small_decrease", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&ap3.Window{}).Bytes(), @@ -111,7 +112,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_large_decrease", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&ap3.Window{}).Bytes(), @@ -135,7 +136,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_increase", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: 2 * ap3.TargetGas, @@ -159,7 +160,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap3_big_1_not_modified", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: 1, @@ -171,7 +172,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap4_genesis_block", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -179,13 +180,17 @@ func TestBaseFee(t *testing.T) { }, { name: "ap4_decrease", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - Extra: (&ap3.Window{}).Bytes(), - BaseFee: big.NewInt(ap4.MaxBaseFee), - BlockGasCost: big.NewInt(ap4.MinBlockGasCost), - }, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + Extra: (&ap3.Window{}).Bytes(), + BaseFee: big.NewInt(ap4.MaxBaseFee), + }, + &customtypes.HeaderExtra{ + BlockGasCost: big.NewInt(ap4.MinBlockGasCost), + }, + ), timestamp: 1, want: func() *big.Int { const ( @@ -203,15 +208,19 @@ func TestBaseFee(t *testing.T) { }, { name: "ap4_increase", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap3.TargetGas, - Extra: (&ap3.Window{}).Bytes(), - BaseFee: big.NewInt(ap4.MinBaseFee), - ExtDataGasUsed: big.NewInt(ap3.TargetGas), - BlockGasCost: big.NewInt(ap4.MinBlockGasCost), - }, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap3.TargetGas, + Extra: (&ap3.Window{}).Bytes(), + BaseFee: big.NewInt(ap4.MinBaseFee), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(ap3.TargetGas), + BlockGasCost: big.NewInt(ap4.MinBlockGasCost), + }, + ), timestamp: 1, want: func() *big.Int { const ( @@ -229,7 +238,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap5_genesis_block", - upgrades: params.TestApricotPhase5Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -237,7 +246,7 @@ func TestBaseFee(t *testing.T) { }, { name: "ap5_decrease", - upgrades: params.TestApricotPhase5Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&ap3.Window{}).Bytes(), @@ -260,14 +269,18 @@ func TestBaseFee(t *testing.T) { }, { name: "ap5_increase", - upgrades: params.TestApricotPhase5Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap5.TargetGas, - Extra: (&ap3.Window{}).Bytes(), - BaseFee: big.NewInt(ap4.MinBaseFee), - ExtDataGasUsed: big.NewInt(ap5.TargetGas), - }, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap5.TargetGas, + Extra: (&ap3.Window{}).Bytes(), + BaseFee: big.NewInt(ap4.MinBaseFee), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(ap5.TargetGas), + }, + ), timestamp: 1, want: func() *big.Int { const ( @@ -285,7 +298,7 @@ func TestBaseFee(t *testing.T) { }, { name: "etna_genesis_block", - upgrades: params.TestEtnaChainConfig.NetworkUpgrades, + upgrades: extras.TestEtnaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -293,14 +306,18 @@ func TestBaseFee(t *testing.T) { }, { name: "etna_increase", - upgrades: params.TestEtnaChainConfig.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap5.TargetGas, - Extra: (&ap3.Window{}).Bytes(), - BaseFee: big.NewInt(etna.MinBaseFee), - ExtDataGasUsed: big.NewInt(ap5.TargetGas), - }, + upgrades: extras.TestEtnaChainConfig.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap5.TargetGas, + Extra: (&ap3.Window{}).Bytes(), + BaseFee: big.NewInt(etna.MinBaseFee), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(ap5.TargetGas), + }, + ), timestamp: 1, want: func() *big.Int { const ( @@ -318,7 +335,7 @@ func TestBaseFee(t *testing.T) { }, { name: "fortuna_invalid_timestamp", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Time: 1, @@ -329,7 +346,7 @@ func TestBaseFee(t *testing.T) { }, { name: "fortuna_first_block", - upgrades: params.NetworkUpgrades{ + upgrades: extras.NetworkUpgrades{ FortunaTimestamp: utils.NewUint64(1), }, parent: &types.Header{ @@ -340,7 +357,7 @@ func TestBaseFee(t *testing.T) { }, { name: "fortuna_genesis_block", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -348,7 +365,7 @@ func TestBaseFee(t *testing.T) { }, { name: "fortuna_invalid_fee_state", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: make([]byte, acp176.StateSize-1), @@ -357,7 +374,7 @@ func TestBaseFee(t *testing.T) { }, { name: "fortuna_current", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&acp176.State{ @@ -371,7 +388,7 @@ func TestBaseFee(t *testing.T) { }, { name: "fortuna_decrease", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&acp176.State{ @@ -389,7 +406,7 @@ func TestBaseFee(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } got, err := BaseFee(config, test.parent, test.timestamp) @@ -405,7 +422,7 @@ func TestBaseFee(t *testing.T) { func TestEstimateNextBaseFee(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header timestamp uint64 want *big.Int @@ -413,7 +430,7 @@ func TestEstimateNextBaseFee(t *testing.T) { }{ { name: "ap3", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&ap3.Window{}).Bytes(), @@ -436,7 +453,7 @@ func TestEstimateNextBaseFee(t *testing.T) { }, { name: "ap3_not_scheduled", - upgrades: params.TestApricotPhase2Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase2Config.NetworkUpgrades, wantErr: errEstimateBaseFeeWithoutActivation, }, } @@ -444,7 +461,7 @@ func TestEstimateNextBaseFee(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } got, err := EstimateNextBaseFee(config, test.parent, test.timestamp) diff --git a/plugin/evm/header/block_gas_cost.go b/plugin/evm/header/block_gas_cost.go index 26c8eaa4e8..638adec5b2 100644 --- a/plugin/evm/header/block_gas_cost.go +++ b/plugin/evm/header/block_gas_cost.go @@ -7,11 +7,12 @@ import ( "errors" "math/big" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) var ( @@ -25,7 +26,7 @@ var ( // header and the timestamp of the new block. // Prior to AP4, the returned block gas cost will be nil. func BlockGasCost( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, timestamp uint64, ) *big.Int { @@ -45,7 +46,7 @@ func BlockGasCost( timeElapsed = timestamp - parent.Time } return new(big.Int).SetUint64(BlockGasCostWithStep( - parent.BlockGasCost, + customtypes.GetHeaderExtra(parent).BlockGasCost, step, timeElapsed, )) @@ -85,23 +86,24 @@ func BlockGasCostWithStep( // // This function will return nil for all return values prior to Apricot Phase 4. func EstimateRequiredTip( - config *params.ChainConfig, + config *extras.ChainConfig, header *types.Header, ) (*big.Int, error) { + extra := customtypes.GetHeaderExtra(header) switch { case !config.IsApricotPhase4(header.Time): return nil, nil case header.BaseFee == nil: return nil, errBaseFeeNil - case header.BlockGasCost == nil: + case extra.BlockGasCost == nil: return nil, errBlockGasCostNil - case header.ExtDataGasUsed == nil: + case extra.ExtDataGasUsed == nil: return nil, errExtDataGasUsedNil } // totalGasUsed = GasUsed + ExtDataGasUsed totalGasUsed := new(big.Int).SetUint64(header.GasUsed) - totalGasUsed.Add(totalGasUsed, header.ExtDataGasUsed) + totalGasUsed.Add(totalGasUsed, extra.ExtDataGasUsed) if totalGasUsed.Sign() == 0 { return nil, errNoGasUsed } @@ -111,7 +113,7 @@ func EstimateRequiredTip( // We add totalGasUsed - 1 to ensure that the total required tips // calculation rounds up. totalRequiredTips := new(big.Int) - totalRequiredTips.Mul(header.BlockGasCost, header.BaseFee) + totalRequiredTips.Mul(extra.BlockGasCost, header.BaseFee) totalRequiredTips.Add(totalRequiredTips, totalGasUsed) totalRequiredTips.Sub(totalRequiredTips, common.Big1) diff --git a/plugin/evm/header/block_gas_cost_test.go b/plugin/evm/header/block_gas_cost_test.go index 3640b9368f..ecf3496354 100644 --- a/plugin/evm/header/block_gas_cost_test.go +++ b/plugin/evm/header/block_gas_cost_test.go @@ -7,11 +7,12 @@ import ( "math/big" "testing" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -19,7 +20,7 @@ import ( func TestBlockGasCost(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parentTime uint64 parentCost *big.Int timestamp uint64 @@ -28,7 +29,7 @@ func TestBlockGasCost(t *testing.T) { { name: "before_ap4", parentTime: 10, - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parentCost: big.NewInt(ap4.MaxBlockGasCost), timestamp: 10 + ap4.TargetBlockRate + 1, expected: nil, @@ -36,14 +37,14 @@ func TestBlockGasCost(t *testing.T) { { name: "normal_ap4", parentTime: 10, - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parentCost: big.NewInt(ap4.MaxBlockGasCost), timestamp: 10 + ap4.TargetBlockRate + 1, expected: big.NewInt(ap4.MaxBlockGasCost - ap4.BlockGasCostStep), }, { name: "normal_ap5", - upgrades: params.TestApricotPhase5Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, parentTime: 10, parentCost: big.NewInt(ap4.MaxBlockGasCost), timestamp: 10 + ap4.TargetBlockRate + 1, @@ -51,7 +52,7 @@ func TestBlockGasCost(t *testing.T) { }, { name: "negative_time_elapsed", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parentTime: 10, parentCost: big.NewInt(ap4.MinBlockGasCost), timestamp: 9, @@ -61,13 +62,17 @@ func TestBlockGasCost(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } - parent := &types.Header{ - Time: test.parentTime, - BlockGasCost: test.parentCost, - } + parent := customtypes.WithHeaderExtra( + &types.Header{ + Time: test.parentTime, + }, + &customtypes.HeaderExtra{ + BlockGasCost: test.parentCost, + }, + ) assert.Equal(t, test.expected, BlockGasCost( config, @@ -186,50 +191,69 @@ func TestEstimateRequiredTip(t *testing.T) { { name: "nil_base_fee", ap4Timestamp: utils.NewUint64(0), - header: &types.Header{ - ExtDataGasUsed: big.NewInt(1), - BlockGasCost: big.NewInt(1), - }, + header: customtypes.WithHeaderExtra( + &types.Header{}, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(1), + BlockGasCost: big.NewInt(1), + }, + ), wantErr: errBaseFeeNil, }, { name: "nil_block_gas_cost", ap4Timestamp: utils.NewUint64(0), - header: &types.Header{ - BaseFee: big.NewInt(1), - ExtDataGasUsed: big.NewInt(1), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + BaseFee: big.NewInt(1), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(1), + }, + ), wantErr: errBlockGasCostNil, }, { name: "nil_extra_data_gas_used", ap4Timestamp: utils.NewUint64(0), - header: &types.Header{ - BaseFee: big.NewInt(1), - BlockGasCost: big.NewInt(1), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + BaseFee: big.NewInt(1), + }, + &customtypes.HeaderExtra{ + BlockGasCost: big.NewInt(1), + }, + ), wantErr: errExtDataGasUsedNil, }, { name: "no_gas_used", ap4Timestamp: utils.NewUint64(0), - header: &types.Header{ - GasUsed: 0, - ExtDataGasUsed: big.NewInt(0), - BaseFee: big.NewInt(1), - BlockGasCost: big.NewInt(1), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + GasUsed: 0, + BaseFee: big.NewInt(1), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(0), + BlockGasCost: big.NewInt(1), + }, + ), wantErr: errNoGasUsed, }, { name: "success", ap4Timestamp: utils.NewUint64(0), - header: &types.Header{ - GasUsed: 123, - ExtDataGasUsed: big.NewInt(789), - BaseFee: big.NewInt(456), - BlockGasCost: big.NewInt(101112), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + GasUsed: 123, + BaseFee: big.NewInt(456), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(789), + BlockGasCost: big.NewInt(101112), + }, + ), // totalGasUsed = GasUsed + ExtDataGasUsed // totalRequiredTips = BlockGasCost * BaseFee // estimatedTip = totalRequiredTips / totalGasUsed @@ -238,12 +262,16 @@ func TestEstimateRequiredTip(t *testing.T) { { name: "success_rounds_up", ap4Timestamp: utils.NewUint64(0), - header: &types.Header{ - GasUsed: 124, - ExtDataGasUsed: big.NewInt(789), - BaseFee: big.NewInt(456), - BlockGasCost: big.NewInt(101112), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + GasUsed: 124, + BaseFee: big.NewInt(456), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(789), + BlockGasCost: big.NewInt(101112), + }, + ), // totalGasUsed = GasUsed + ExtDataGasUsed // totalRequiredTips = BlockGasCost * BaseFee // estimatedTip = totalRequiredTips / totalGasUsed @@ -254,8 +282,8 @@ func TestEstimateRequiredTip(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - config := ¶ms.ChainConfig{ - NetworkUpgrades: params.NetworkUpgrades{ + config := &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ ApricotPhase4BlockTimestamp: test.ap4Timestamp, }, } diff --git a/plugin/evm/header/dynamic_fee_state.go b/plugin/evm/header/dynamic_fee_state.go index 362eb2a93b..0103d1aaec 100644 --- a/plugin/evm/header/dynamic_fee_state.go +++ b/plugin/evm/header/dynamic_fee_state.go @@ -7,16 +7,17 @@ import ( "fmt" "github.com/ava-labs/avalanchego/vms/components/gas" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // feeStateBeforeBlock takes the previous header and the timestamp of its child // block and calculates the fee state before the child block is executed. func feeStateBeforeBlock( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, timestamp uint64, ) (acp176.State, error) { @@ -48,7 +49,7 @@ func feeStateBeforeBlock( // feeStateAfterBlock takes the previous header and returns the fee state after // the execution of the provided child. func feeStateAfterBlock( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, header *types.Header, desiredTargetExcess *gas.Gas, @@ -60,7 +61,8 @@ func feeStateAfterBlock( } // Consume the gas used by the block - if err := state.ConsumeGas(header.GasUsed, header.ExtDataGasUsed); err != nil { + extDataGasUsed := customtypes.GetHeaderExtra(header).ExtDataGasUsed + if err := state.ConsumeGas(header.GasUsed, extDataGasUsed); err != nil { return acp176.State{}, fmt.Errorf("advancing the fee state: %w", err) } diff --git a/plugin/evm/header/dynamic_fee_windower.go b/plugin/evm/header/dynamic_fee_windower.go index eb92512120..6b696e0cc3 100644 --- a/plugin/evm/header/dynamic_fee_windower.go +++ b/plugin/evm/header/dynamic_fee_windower.go @@ -8,14 +8,15 @@ import ( "fmt" "math/big" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/plugin/evm/upgrade/etna" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/types" ) var ( @@ -36,7 +37,7 @@ var ( ) // baseFeeFromWindow should only be called if `timestamp` >= `config.ApricotPhase3Timestamp` -func baseFeeFromWindow(config *params.ChainConfig, parent *types.Header, timestamp uint64) (*big.Int, error) { +func baseFeeFromWindow(config *extras.ChainConfig, parent *types.Header, timestamp uint64) (*big.Int, error) { // If the current block is the first EIP-1559 block, or it is the genesis block // return the initial slice and initial base fee. if !config.IsApricotPhase3(parent.Time) || parent.Number.Cmp(common.Big0) == 0 { @@ -145,7 +146,7 @@ func baseFeeFromWindow(config *params.ChainConfig, parent *types.Header, timesta // // feeWindow should only be called if timestamp >= config.ApricotPhase3Timestamp func feeWindow( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, timestamp uint64, ) (ap3.Window, error) { @@ -178,8 +179,8 @@ func feeWindow( // At the start of a new network, the parent may not have a populated // ExtDataGasUsed. - if parent.ExtDataGasUsed != nil { - parentExtraStateGasUsed = parent.ExtDataGasUsed.Uint64() + if used := customtypes.GetHeaderExtra(parent).ExtDataGasUsed; used != nil { + parentExtraStateGasUsed = used.Uint64() } case config.IsApricotPhase4(parent.Time): // The blockGasCost is paid by the effective tips in the block using @@ -189,16 +190,17 @@ func feeWindow( // still calculated using the AP4 step. This is different than the // actual BlockGasCost calculation used for the child block. This // behavior is kept to preserve the original behavior of this function. + parentExtra := customtypes.GetHeaderExtra(parent) blockGasCost = BlockGasCostWithStep( - parent.BlockGasCost, + parentExtra.BlockGasCost, ap4.BlockGasCostStep, timeElapsed, ) // On the boundary of AP3 and AP4 or at the start of a new network, the // parent may not have a populated ExtDataGasUsed. - if parent.ExtDataGasUsed != nil { - parentExtraStateGasUsed = parent.ExtDataGasUsed.Uint64() + if parentExtra.ExtDataGasUsed != nil { + parentExtraStateGasUsed = parentExtra.ExtDataGasUsed.Uint64() } default: blockGasCost = ap3.IntrinsicBlockGas diff --git a/plugin/evm/header/extra.go b/plugin/evm/header/extra.go index 5e31457c6c..646f5528da 100644 --- a/plugin/evm/header/extra.go +++ b/plugin/evm/header/extra.go @@ -9,10 +9,11 @@ import ( "fmt" "github.com/ava-labs/avalanchego/vms/components/gas" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" + "github.com/ava-labs/libevm/core/types" ) var ( @@ -26,7 +27,7 @@ var ( // // If the `desiredTargetExcess` is nil, the parent's target excess is used. func ExtraPrefix( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, header *types.Header, desiredTargetExcess *gas.Gas, @@ -58,7 +59,7 @@ func ExtraPrefix( // VerifyExtraPrefix verifies that the header's Extra field is correctly // formatted. func VerifyExtraPrefix( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, header *types.Header, ) error { @@ -112,7 +113,7 @@ func VerifyExtraPrefix( // rules. // // TODO: Should this be merged with VerifyExtraPrefix? -func VerifyExtra(rules params.AvalancheRules, extra []byte) error { +func VerifyExtra(rules extras.AvalancheRules, extra []byte) error { extraLen := len(extra) switch { case rules.IsFortuna: @@ -151,11 +152,11 @@ func VerifyExtra(rules params.AvalancheRules, extra []byte) error { ) } default: - if uint64(extraLen) > params.MaximumExtraDataSize { + if uint64(extraLen) > ap0.MaximumExtraDataSize { return fmt.Errorf( "%w: expected <= %d but got %d", errInvalidExtraLength, - params.MaximumExtraDataSize, + ap0.MaximumExtraDataSize, extraLen, ) } @@ -165,7 +166,7 @@ func VerifyExtra(rules params.AvalancheRules, extra []byte) error { // PredicateBytesFromExtra returns the predicate result bytes from the header's // extra data. If the extra data is not long enough, an empty slice is returned. -func PredicateBytesFromExtra(rules params.AvalancheRules, extra []byte) []byte { +func PredicateBytesFromExtra(rules extras.AvalancheRules, extra []byte) []byte { offset := ap3.WindowSize if rules.IsFortuna { offset = acp176.StateSize @@ -179,3 +180,23 @@ func PredicateBytesFromExtra(rules params.AvalancheRules, extra []byte) []byte { } return extra[offset:] } + +// SetPredicateBytesInExtra sets the predicate result bytes in the header's extra +// data. If the extra data is not long enough (i.e., an incomplete header.Extra +// as built in the miner), it is padded with zeros. +func SetPredicateBytesInExtra(rules extras.AvalancheRules, extra []byte, predicateBytes []byte) []byte { + offset := ap3.WindowSize + if rules.IsFortuna { + offset = acp176.StateSize + } + + if len(extra) < offset { + // pad extra with zeros + extra = append(extra, make([]byte, offset-len(extra))...) + } else { + // truncate extra to the offset + extra = extra[:offset] + } + extra = append(extra, predicateBytes...) + return extra +} diff --git a/plugin/evm/header/extra_test.go b/plugin/evm/header/extra_test.go index c3628c0a20..99fe3abdbe 100644 --- a/plugin/evm/header/extra_test.go +++ b/plugin/evm/header/extra_test.go @@ -8,20 +8,22 @@ import ( "testing" "github.com/ava-labs/avalanchego/vms/components/gas" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap3" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap4" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" ) func TestExtraPrefix(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header header *types.Header desiredTargetExcess *gas.Gas @@ -30,14 +32,14 @@ func TestExtraPrefix(t *testing.T) { }{ { name: "ap2", - upgrades: params.TestApricotPhase2Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase2Config.NetworkUpgrades, header: &types.Header{}, want: nil, wantErr: nil, }, { name: "ap3_first_block", - upgrades: params.NetworkUpgrades{ + upgrades: extras.NetworkUpgrades{ ApricotPhase3BlockTimestamp: utils.NewUint64(1), }, parent: &types.Header{ @@ -50,7 +52,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_genesis_block", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -59,7 +61,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_invalid_fee_window", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -68,7 +70,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_invalid_timestamp", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Time: 1, @@ -81,7 +83,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap3_normal", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -103,7 +105,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_genesis_block", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -112,7 +114,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_no_block_gas_cost", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), GasUsed: ap3.TargetGas, @@ -130,13 +132,17 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_with_block_gas_cost", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap3.TargetGas, - Extra: (&ap3.Window{}).Bytes(), - BlockGasCost: big.NewInt(ap4.MinBlockGasCost), - }, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap3.TargetGas, + Extra: (&ap3.Window{}).Bytes(), + }, + &customtypes.HeaderExtra{ + BlockGasCost: big.NewInt(ap4.MinBlockGasCost), + }, + ), header: &types.Header{ Time: 1, }, @@ -152,13 +158,17 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_with_extra_data_gas", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap3.TargetGas, - Extra: (&ap3.Window{}).Bytes(), - ExtDataGasUsed: big.NewInt(5), - }, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap3.TargetGas, + Extra: (&ap3.Window{}).Bytes(), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(5), + }, + ), header: &types.Header{ Time: 1, }, @@ -174,16 +184,20 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap4_normal", - upgrades: params.TestApricotPhase4Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap3.TargetGas, - Extra: (&ap3.Window{ - 1, 2, 3, 4, - }).Bytes(), - ExtDataGasUsed: big.NewInt(5), - BlockGasCost: big.NewInt(ap4.MinBlockGasCost), - }, + upgrades: extras.TestApricotPhase4Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap3.TargetGas, + Extra: (&ap3.Window{ + 1, 2, 3, 4, + }).Bytes(), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(5), + BlockGasCost: big.NewInt(ap4.MinBlockGasCost), + }, + ), header: &types.Header{ Time: 1, }, @@ -202,13 +216,17 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap5_no_extra_data_gas", - upgrades: params.TestApricotPhase5Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap5.TargetGas, - Extra: (&ap3.Window{}).Bytes(), - BlockGasCost: big.NewInt(ap4.MinBlockGasCost), - }, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap5.TargetGas, + Extra: (&ap3.Window{}).Bytes(), + }, + &customtypes.HeaderExtra{ + BlockGasCost: big.NewInt(ap4.MinBlockGasCost), + }, + ), header: &types.Header{ Time: 1, }, @@ -221,16 +239,20 @@ func TestExtraPrefix(t *testing.T) { }, { name: "ap5_normal", - upgrades: params.TestApricotPhase5Config.NetworkUpgrades, - parent: &types.Header{ - Number: big.NewInt(1), - GasUsed: ap5.TargetGas, - Extra: (&ap3.Window{ - 1, 2, 3, 4, - }).Bytes(), - ExtDataGasUsed: big.NewInt(5), - BlockGasCost: big.NewInt(ap4.MinBlockGasCost), - }, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, + parent: customtypes.WithHeaderExtra( + &types.Header{ + Number: big.NewInt(1), + GasUsed: ap5.TargetGas, + Extra: (&ap3.Window{ + 1, 2, 3, 4, + }).Bytes(), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(5), + BlockGasCost: big.NewInt(ap4.MinBlockGasCost), + }, + ), header: &types.Header{ Time: 1, }, @@ -248,17 +270,21 @@ func TestExtraPrefix(t *testing.T) { }, { name: "fortuna_first_block", - upgrades: params.NetworkUpgrades{ + upgrades: extras.NetworkUpgrades{ FortunaTimestamp: utils.NewUint64(1), }, parent: &types.Header{ Number: big.NewInt(1), }, - header: &types.Header{ - Time: 1, - GasUsed: 1, - ExtDataGasUsed: big.NewInt(5), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + Time: 1, + GasUsed: 1, + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(5), + }, + ), want: (&acp176.State{ Gas: gas.State{ Capacity: acp176.MinMaxPerSecond - 6, @@ -269,15 +295,19 @@ func TestExtraPrefix(t *testing.T) { }, { name: "fortuna_genesis_block", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, - header: &types.Header{ - Time: 1, - GasUsed: 2, - ExtDataGasUsed: big.NewInt(1), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + Time: 1, + GasUsed: 2, + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(1), + }, + ), desiredTargetExcess: (*gas.Gas)(utils.NewUint64(3)), want: (&acp176.State{ Gas: gas.State{ @@ -289,7 +319,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "fortuna_invalid_fee_state", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -298,7 +328,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "fortuna_invalid_gas_used", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&acp176.State{}).Bytes(), @@ -310,7 +340,7 @@ func TestExtraPrefix(t *testing.T) { }, { name: "fortuna_reduce_capacity", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), Extra: (&acp176.State{ @@ -321,10 +351,14 @@ func TestExtraPrefix(t *testing.T) { TargetExcess: 2 * acp176.MaxTargetExcessDiff, }).Bytes(), }, - header: &types.Header{ - GasUsed: 2, - ExtDataGasUsed: big.NewInt(1), - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + GasUsed: 2, + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: big.NewInt(1), + }, + ), desiredTargetExcess: (*gas.Gas)(utils.NewUint64(0)), want: (&acp176.State{ Gas: gas.State{ @@ -339,7 +373,7 @@ func TestExtraPrefix(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } got, err := ExtraPrefix(config, test.parent, test.header, test.desiredTargetExcess) @@ -352,20 +386,20 @@ func TestExtraPrefix(t *testing.T) { func TestVerifyExtraPrefix(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header header *types.Header wantErr error }{ { name: "ap2", - upgrades: params.TestApricotPhase2Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase2Config.NetworkUpgrades, header: &types.Header{}, wantErr: nil, }, { name: "ap3_invalid_parent_header", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -374,7 +408,7 @@ func TestVerifyExtraPrefix(t *testing.T) { }, { name: "ap3_invalid_header", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -383,7 +417,7 @@ func TestVerifyExtraPrefix(t *testing.T) { }, { name: "ap3_valid", - upgrades: params.TestApricotPhase3Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase3Config.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -394,13 +428,13 @@ func TestVerifyExtraPrefix(t *testing.T) { }, { name: "fortuna_invalid_header", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, header: &types.Header{}, wantErr: acp176.ErrStateInsufficientLength, }, { name: "fortuna_invalid_gas_consumed", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -412,7 +446,7 @@ func TestVerifyExtraPrefix(t *testing.T) { }, { name: "fortuna_wrong_fee_state", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -431,7 +465,7 @@ func TestVerifyExtraPrefix(t *testing.T) { }, { name: "fortuna_valid", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -451,7 +485,7 @@ func TestVerifyExtraPrefix(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } err := VerifyExtraPrefix(config, test.parent, test.header) @@ -463,25 +497,25 @@ func TestVerifyExtraPrefix(t *testing.T) { func TestVerifyExtra(t *testing.T) { tests := []struct { name string - rules params.AvalancheRules + rules extras.AvalancheRules extra []byte expected error }{ { name: "initial_valid", - rules: params.AvalancheRules{}, - extra: make([]byte, params.MaximumExtraDataSize), + rules: extras.AvalancheRules{}, + extra: make([]byte, ap0.MaximumExtraDataSize), expected: nil, }, { name: "initial_invalid", - rules: params.AvalancheRules{}, - extra: make([]byte, params.MaximumExtraDataSize+1), + rules: extras.AvalancheRules{}, + extra: make([]byte, ap0.MaximumExtraDataSize+1), expected: errInvalidExtraLength, }, { name: "ap1_valid", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsApricotPhase1: true, }, extra: nil, @@ -489,7 +523,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "ap1_invalid", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsApricotPhase1: true, }, extra: make([]byte, 1), @@ -497,7 +531,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "ap3_valid", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsApricotPhase3: true, }, extra: make([]byte, ap3.WindowSize), @@ -505,7 +539,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "ap3_invalid_less", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsApricotPhase3: true, }, extra: make([]byte, ap3.WindowSize-1), @@ -513,7 +547,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "ap3_invalid_more", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsApricotPhase3: true, }, extra: make([]byte, ap3.WindowSize+1), @@ -521,7 +555,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "durango_valid_min", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsDurango: true, }, extra: make([]byte, ap3.WindowSize), @@ -529,7 +563,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "durango_valid_extra", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsDurango: true, }, extra: make([]byte, ap3.WindowSize+1), @@ -537,7 +571,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "durango_invalid", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsDurango: true, }, extra: make([]byte, ap3.WindowSize-1), @@ -545,7 +579,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "fortuna_valid_min", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsFortuna: true, }, extra: make([]byte, acp176.StateSize), @@ -553,7 +587,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "fortuna_valid_extra", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsFortuna: true, }, extra: make([]byte, acp176.StateSize+1), @@ -561,7 +595,7 @@ func TestVerifyExtra(t *testing.T) { }, { name: "fortuna_invalid", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsFortuna: true, }, extra: make([]byte, acp176.StateSize-1), @@ -579,7 +613,7 @@ func TestVerifyExtra(t *testing.T) { func TestPredicateBytesFromExtra(t *testing.T) { tests := []struct { name string - rules params.AvalancheRules + rules extras.AvalancheRules extra []byte expected []byte }{ @@ -607,7 +641,7 @@ func TestPredicateBytesFromExtra(t *testing.T) { }, { name: "fortuna_empty_extra", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsFortuna: true, }, extra: nil, @@ -615,7 +649,7 @@ func TestPredicateBytesFromExtra(t *testing.T) { }, { name: "fortuna_too_short", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsFortuna: true, }, extra: make([]byte, acp176.StateSize-1), @@ -623,7 +657,7 @@ func TestPredicateBytesFromExtra(t *testing.T) { }, { name: "fortuna_empty_predicate", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsFortuna: true, }, extra: make([]byte, acp176.StateSize), @@ -631,7 +665,7 @@ func TestPredicateBytesFromExtra(t *testing.T) { }, { name: "fortuna_non_empty_predicate", - rules: params.AvalancheRules{ + rules: extras.AvalancheRules{ IsFortuna: true, }, extra: []byte{ @@ -647,3 +681,142 @@ func TestPredicateBytesFromExtra(t *testing.T) { }) } } + +func TestSetPredicateBytesInExtra(t *testing.T) { + tests := []struct { + name string + rules extras.AvalancheRules + extra []byte + predicate []byte + want []byte + }{ + { + name: "empty_extra_predicate", + want: make([]byte, ap3.WindowSize), + }, + { + name: "empty_extra_predicate_fortuna", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + want: make([]byte, acp176.StateSize), + }, + { + name: "extra_too_short", + extra: []byte{1}, + predicate: []byte{2}, + want: []byte{ + 0: 1, + ap3.WindowSize: 2, + }, + }, + { + name: "extra_too_short_fortuna", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: []byte{1}, + predicate: []byte{2}, + want: []byte{ + 0: 1, + acp176.StateSize: 2, + }, + }, + { + name: "extra_too_long", + extra: []byte{ + ap3.WindowSize: 1, + }, + predicate: []byte{2}, + want: []byte{ + ap3.WindowSize: 2, + }, + }, + { + name: "extra_too_long_fortuna", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: []byte{ + acp176.StateSize: 1, + }, + predicate: []byte{2}, + want: []byte{ + acp176.StateSize: 2, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := SetPredicateBytesInExtra(test.rules, test.extra, test.predicate) + require.Equal(t, test.want, got) + }) + } +} + +func TestPredicateBytesExtra(t *testing.T) { + tests := []struct { + name string + rules extras.AvalancheRules + extra []byte + predicate []byte + wantExtraWithPredicate []byte + }{ + { + name: "empty_extra_predicate", + extra: nil, + predicate: nil, + wantExtraWithPredicate: make([]byte, ap3.WindowSize), + }, + { + name: "empty_extra_predicate_fortuna", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: nil, + predicate: nil, + wantExtraWithPredicate: make([]byte, acp176.StateSize), + }, + { + name: "extra_too_short", + extra: []byte{ + 0: 1, + ap3.WindowSize - 1: 0, + }, + predicate: []byte{2}, + wantExtraWithPredicate: []byte{ + 0: 1, + ap3.WindowSize: 2, + }, + }, + { + name: "extra_too_short_fortuna", + rules: extras.AvalancheRules{ + IsFortuna: true, + }, + extra: []byte{ + 0: 1, + acp176.StateSize - 1: 0, + }, + predicate: []byte{2}, + wantExtraWithPredicate: []byte{ + 0: 1, + acp176.StateSize: 2, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var wantPredicate []byte + if test.predicate != nil { + wantPredicate = make([]byte, len(test.predicate)) + copy(wantPredicate, test.predicate) + } + + gotExtra := SetPredicateBytesInExtra(test.rules, test.extra, test.predicate) + require.Equal(t, test.wantExtraWithPredicate, gotExtra) + gotPredicate := PredicateBytesFromExtra(test.rules, gotExtra) + require.Equal(t, wantPredicate, gotPredicate) + }) + } +} diff --git a/plugin/evm/header/gas_limit.go b/plugin/evm/header/gas_limit.go index 1a63341716..fffe6983aa 100644 --- a/plugin/evm/header/gas_limit.go +++ b/plugin/evm/header/gas_limit.go @@ -8,11 +8,13 @@ import ( "fmt" "github.com/ava-labs/avalanchego/utils/math" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" + "github.com/ava-labs/libevm/core/types" ) var ( @@ -24,7 +26,7 @@ var ( // GasLimit takes the previous header and the timestamp of its child block and // calculates the gas limit for the child block. func GasLimit( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, timestamp uint64, ) (uint64, error) { @@ -57,20 +59,21 @@ func GasLimit( // VerifyGasUsed verifies that the gas used is less than or equal to the gas // limit. func VerifyGasUsed( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, header *types.Header, ) error { gasUsed := header.GasUsed - if config.IsFortuna(header.Time) && header.ExtDataGasUsed != nil { - if !header.ExtDataGasUsed.IsUint64() { + extDataGasUsed := customtypes.GetHeaderExtra(header).ExtDataGasUsed + if config.IsFortuna(header.Time) && extDataGasUsed != nil { + if !extDataGasUsed.IsUint64() { return fmt.Errorf("%w: %d is not a uint64", errInvalidExtraDataGasUsed, - header.ExtDataGasUsed, + extDataGasUsed, ) } var err error - gasUsed, err = math.Add(gasUsed, header.ExtDataGasUsed.Uint64()) + gasUsed, err = math.Add(gasUsed, extDataGasUsed.Uint64()) if err != nil { return fmt.Errorf("%w while calculating gas used", err) } @@ -92,7 +95,7 @@ func VerifyGasUsed( // VerifyGasLimit verifies that the gas limit for the header is valid. func VerifyGasLimit( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, header *types.Header, ) error { @@ -127,18 +130,18 @@ func VerifyGasLimit( ) } default: - if header.GasLimit < params.MinGasLimit || header.GasLimit > params.MaxGasLimit { + if header.GasLimit < ap0.MinGasLimit || header.GasLimit > ap0.MaxGasLimit { return fmt.Errorf("%w: %d not in range [%d, %d]", errInvalidGasLimit, header.GasLimit, - params.MinGasLimit, - params.MaxGasLimit, + ap0.MinGasLimit, + ap0.MaxGasLimit, ) } // Verify that the gas limit remains within allowed bounds diff := math.AbsDiff(parent.GasLimit, header.GasLimit) - limit := parent.GasLimit / params.GasLimitBoundDivisor + limit := parent.GasLimit / ap0.GasLimitBoundDivisor if diff >= limit { return fmt.Errorf("%w: have %d, want %d += %d", errInvalidGasLimit, @@ -154,7 +157,7 @@ func VerifyGasLimit( // GasCapacity takes the previous header and the timestamp of its child block // and calculates the available gas that can be consumed in the child block. func GasCapacity( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, timestamp uint64, ) (uint64, error) { @@ -174,7 +177,7 @@ func GasCapacity( // on `header` while still being valid based on the initial capacity and // consumed gas. func RemainingAtomicGasCapacity( - config *params.ChainConfig, + config *extras.ChainConfig, parent *types.Header, header *types.Header, ) (uint64, error) { diff --git a/plugin/evm/header/gas_limit_test.go b/plugin/evm/header/gas_limit_test.go index 77dea0302f..b34a2095a6 100644 --- a/plugin/evm/header/gas_limit_test.go +++ b/plugin/evm/header/gas_limit_test.go @@ -9,20 +9,22 @@ import ( "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/vms/components/gas" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" + "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" "github.com/ava-labs/coreth/plugin/evm/upgrade/cortina" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" "github.com/stretchr/testify/require" ) func TestGasLimit(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header timestamp uint64 want uint64 @@ -30,7 +32,7 @@ func TestGasLimit(t *testing.T) { }{ { name: "fortuna_invalid_parent_header", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -38,7 +40,7 @@ func TestGasLimit(t *testing.T) { }, { name: "fortuna_initial_max_capacity", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -46,17 +48,17 @@ func TestGasLimit(t *testing.T) { }, { name: "cortina", - upgrades: params.TestCortinaChainConfig.NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, want: cortina.GasLimit, }, { name: "ap1", - upgrades: params.TestApricotPhase1Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase1Config.NetworkUpgrades, want: ap1.GasLimit, }, { name: "launch", - upgrades: params.TestLaunchConfig.NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ GasLimit: 1, }, @@ -67,7 +69,7 @@ func TestGasLimit(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } got, err := GasLimit(config, test.parent, test.timestamp) @@ -80,31 +82,38 @@ func TestGasLimit(t *testing.T) { func TestVerifyGasUsed(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header header *types.Header want error }{ { name: "fortuna_massive_extra_gas_used", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, - header: &types.Header{ - ExtDataGasUsed: new(big.Int).Lsh(common.Big1, 64), - }, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + header: customtypes.WithHeaderExtra( + &types.Header{}, + &customtypes.HeaderExtra{ + ExtDataGasUsed: new(big.Int).Lsh(common.Big1, 64), + }, + ), want: errInvalidExtraDataGasUsed, }, { name: "fortuna_gas_used_overflow", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, - header: &types.Header{ - GasUsed: math.MaxUint[uint64](), - ExtDataGasUsed: common.Big1, - }, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, + header: customtypes.WithHeaderExtra( + &types.Header{ + GasUsed: math.MaxUint[uint64](), + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: common.Big1, + }, + ), want: math.ErrOverflow, }, { name: "fortuna_invalid_capacity", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -113,7 +122,7 @@ func TestVerifyGasUsed(t *testing.T) { }, { name: "fortuna_invalid_usage", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -128,7 +137,7 @@ func TestVerifyGasUsed(t *testing.T) { }, { name: "fortuna_max_consumption", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -140,20 +149,24 @@ func TestVerifyGasUsed(t *testing.T) { }, { name: "cortina_does_not_include_extra_gas_used", - upgrades: params.TestCortinaChainConfig.NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, - header: &types.Header{ - GasUsed: cortina.GasLimit, - ExtDataGasUsed: common.Big1, - }, + header: customtypes.WithHeaderExtra( + &types.Header{ + GasUsed: cortina.GasLimit, + }, + &customtypes.HeaderExtra{ + ExtDataGasUsed: common.Big1, + }, + ), want: nil, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } err := VerifyGasUsed(config, test.parent, test.header) @@ -165,14 +178,14 @@ func TestVerifyGasUsed(t *testing.T) { func TestVerifyGasLimit(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header header *types.Header want error }{ { name: "fortuna_invalid_header", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -181,7 +194,7 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "fortuna_invalid", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -192,7 +205,7 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "fortuna_valid", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -202,14 +215,14 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "cortina_valid", - upgrades: params.TestCortinaChainConfig.NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, header: &types.Header{ GasLimit: cortina.GasLimit, }, }, { name: "cortina_invalid", - upgrades: params.TestCortinaChainConfig.NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, header: &types.Header{ GasLimit: cortina.GasLimit + 1, }, @@ -217,14 +230,14 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "ap1_valid", - upgrades: params.TestApricotPhase1Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase1Config.NetworkUpgrades, header: &types.Header{ GasLimit: ap1.GasLimit, }, }, { name: "ap1_invalid", - upgrades: params.TestApricotPhase1Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase1Config.NetworkUpgrades, header: &types.Header{ GasLimit: ap1.GasLimit + 1, }, @@ -232,7 +245,7 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "launch_valid", - upgrades: params.TestLaunchConfig.NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ GasLimit: 50_000, }, @@ -242,41 +255,41 @@ func TestVerifyGasLimit(t *testing.T) { }, { name: "launch_too_low", - upgrades: params.TestLaunchConfig.NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: params.MinGasLimit, + GasLimit: ap0.MinGasLimit, }, header: &types.Header{ - GasLimit: params.MinGasLimit - 1, + GasLimit: ap0.MinGasLimit - 1, }, want: errInvalidGasLimit, }, { name: "launch_too_high", - upgrades: params.TestLaunchConfig.NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: params.MaxGasLimit, + GasLimit: ap0.MaxGasLimit, }, header: &types.Header{ - GasLimit: params.MaxGasLimit + 1, + GasLimit: ap0.MaxGasLimit + 1, }, want: errInvalidGasLimit, }, { name: "change_too_large", - upgrades: params.TestLaunchConfig.NetworkUpgrades, + upgrades: extras.TestLaunchConfig.NetworkUpgrades, parent: &types.Header{ - GasLimit: params.MinGasLimit, + GasLimit: ap0.MinGasLimit, }, header: &types.Header{ - GasLimit: params.MaxGasLimit, + GasLimit: ap0.MaxGasLimit, }, want: errInvalidGasLimit, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } err := VerifyGasLimit(config, test.parent, test.header) @@ -288,7 +301,7 @@ func TestVerifyGasLimit(t *testing.T) { func TestGasCapacity(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header timestamp uint64 want uint64 @@ -296,12 +309,12 @@ func TestGasCapacity(t *testing.T) { }{ { name: "cortina", - upgrades: params.TestCortinaChainConfig.NetworkUpgrades, + upgrades: extras.TestCortinaChainConfig.NetworkUpgrades, want: cortina.GasLimit, }, { name: "fortuna_invalid_header", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -309,7 +322,7 @@ func TestGasCapacity(t *testing.T) { }, { name: "fortuna_after_1s", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -321,7 +334,7 @@ func TestGasCapacity(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } got, err := GasCapacity(config, test.parent, test.timestamp) @@ -334,7 +347,7 @@ func TestGasCapacity(t *testing.T) { func TestRemainingAtomicGasCapacity(t *testing.T) { tests := []struct { name string - upgrades params.NetworkUpgrades + upgrades extras.NetworkUpgrades parent *types.Header header *types.Header want uint64 @@ -342,13 +355,13 @@ func TestRemainingAtomicGasCapacity(t *testing.T) { }{ { name: "ap5", - upgrades: params.TestApricotPhase5Config.NetworkUpgrades, + upgrades: extras.TestApricotPhase5Config.NetworkUpgrades, header: &types.Header{}, want: ap5.AtomicGasLimit, }, { name: "fortuna_invalid_header", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(1), }, @@ -357,7 +370,7 @@ func TestRemainingAtomicGasCapacity(t *testing.T) { }, { name: "fortuna_negative_capacity", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -368,7 +381,7 @@ func TestRemainingAtomicGasCapacity(t *testing.T) { }, { name: "f", - upgrades: params.TestFortunaChainConfig.NetworkUpgrades, + upgrades: extras.TestFortunaChainConfig.NetworkUpgrades, parent: &types.Header{ Number: big.NewInt(0), }, @@ -383,7 +396,7 @@ func TestRemainingAtomicGasCapacity(t *testing.T) { t.Run(test.name, func(t *testing.T) { require := require.New(t) - config := ¶ms.ChainConfig{ + config := &extras.ChainConfig{ NetworkUpgrades: test.upgrades, } got, err := RemainingAtomicGasCapacity(config, test.parent, test.header) diff --git a/plugin/evm/import_tx_test.go b/plugin/evm/import_tx_test.go index 495b3a514c..65d5fb707d 100644 --- a/plugin/evm/import_tx_test.go +++ b/plugin/evm/import_tx_test.go @@ -10,7 +10,7 @@ import ( "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/holiman/uint256" avalancheatomic "github.com/ava-labs/avalanchego/chains/atomic" diff --git a/plugin/evm/imports_test.go b/plugin/evm/imports_test.go index 8b7ac4c4a9..5089605493 100644 --- a/plugin/evm/imports_test.go +++ b/plugin/evm/imports_test.go @@ -54,9 +54,10 @@ func TestMustNotImport(t *testing.T) { // Importing these packages configures libevm globally and it is not // possible to do so for both coreth and subnet-evm, where the client may // wish to connect to multiple chains. - "plugin/evm/atomic": {"core", "core/vm"}, - "plugin/evm/client": {"core", "core/vm"}, - "plugin/evm/config": {"core", "core/vm"}, + "plugin/evm/atomic": {"core", "core/vm", "params"}, + "plugin/evm/client": {"core", "core/vm", "params"}, + "plugin/evm/config": {"core", "core/vm", "params"}, + "plugin/evm/header": {"core", "core/vm", "params"}, } for packageName, forbiddenImports := range mustNotImport { diff --git a/plugin/evm/log.go b/plugin/evm/log.go index 9eb00fc7be..83612ce03c 100644 --- a/plugin/evm/log.go +++ b/plugin/evm/log.go @@ -11,12 +11,12 @@ import ( "strings" "github.com/ava-labs/coreth/log" - gethlog "github.com/ethereum/go-ethereum/log" + ethlog "github.com/ava-labs/libevm/log" "golang.org/x/exp/slog" ) type CorethLogger struct { - gethlog.Logger + ethlog.Logger logLevel *slog.LevelVar } @@ -47,14 +47,14 @@ func InitLogger(alias string, level string, jsonFormat bool, writer io.Writer) ( // Create handler c := CorethLogger{ - Logger: gethlog.NewLogger(handler), + Logger: ethlog.NewLogger(handler), logLevel: logLevel, } if err := c.SetLogLevel(level); err != nil { return CorethLogger{}, err } - gethlog.SetDefault(c.Logger) + ethlog.SetDefault(c.Logger) return c, nil } diff --git a/plugin/evm/log_test.go b/plugin/evm/log_test.go index b39fa8cc3c..eb61a4e5e5 100644 --- a/plugin/evm/log_test.go +++ b/plugin/evm/log_test.go @@ -7,7 +7,7 @@ import ( "os" "testing" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" "github.com/stretchr/testify/require" ) diff --git a/plugin/evm/message/block_request.go b/plugin/evm/message/block_request.go index f1f353f2f7..009e6b0155 100644 --- a/plugin/evm/message/block_request.go +++ b/plugin/evm/message/block_request.go @@ -9,7 +9,7 @@ import ( "github.com/ava-labs/avalanchego/ids" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) var ( diff --git a/plugin/evm/message/block_request_test.go b/plugin/evm/message/block_request_test.go index cd9070117d..7d5b286551 100644 --- a/plugin/evm/message/block_request_test.go +++ b/plugin/evm/message/block_request_test.go @@ -8,7 +8,7 @@ import ( "math/rand" "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/assert" ) diff --git a/plugin/evm/message/code_request.go b/plugin/evm/message/code_request.go index cd1ffef844..d1aeb7f2f6 100644 --- a/plugin/evm/message/code_request.go +++ b/plugin/evm/message/code_request.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/ava-labs/avalanchego/ids" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) var _ Request = CodeRequest{} diff --git a/plugin/evm/message/code_request_test.go b/plugin/evm/message/code_request_test.go index 88cedb54d4..3faf12949d 100644 --- a/plugin/evm/message/code_request_test.go +++ b/plugin/evm/message/code_request_test.go @@ -8,7 +8,7 @@ import ( "math/rand" "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/assert" ) diff --git a/plugin/evm/message/leafs_request.go b/plugin/evm/message/leafs_request.go index 22629e62ef..32ae4dc45d 100644 --- a/plugin/evm/message/leafs_request.go +++ b/plugin/evm/message/leafs_request.go @@ -8,8 +8,8 @@ import ( "fmt" "github.com/ava-labs/avalanchego/ids" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) const MaxCodeHashesPerRequest = 5 diff --git a/plugin/evm/message/leafs_request_test.go b/plugin/evm/message/leafs_request_test.go index ab6cab5124..68784fe04c 100644 --- a/plugin/evm/message/leafs_request_test.go +++ b/plugin/evm/message/leafs_request_test.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/ids" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/assert" ) diff --git a/plugin/evm/message/syncable.go b/plugin/evm/message/syncable.go index c8631bbb5e..680a18b421 100644 --- a/plugin/evm/message/syncable.go +++ b/plugin/evm/message/syncable.go @@ -8,8 +8,8 @@ import ( "fmt" "github.com/ava-labs/avalanchego/ids" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" ) diff --git a/plugin/evm/network_handler.go b/plugin/evm/network_handler.go index a461122cf6..b207bc2ca1 100644 --- a/plugin/evm/network_handler.go +++ b/plugin/evm/network_handler.go @@ -11,11 +11,11 @@ import ( "github.com/ava-labs/coreth/plugin/evm/message" syncHandlers "github.com/ava-labs/coreth/sync/handlers" syncStats "github.com/ava-labs/coreth/sync/handlers/stats" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/warp" warpHandlers "github.com/ava-labs/coreth/warp/handlers" + "github.com/ava-labs/libevm/ethdb" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/triedb" ) var _ message.RequestHandler = &networkHandler{} diff --git a/plugin/evm/prestate_tracer_test.go b/plugin/evm/prestate_tracer_test.go index 511098bb62..ae53294e30 100644 --- a/plugin/evm/prestate_tracer_test.go +++ b/plugin/evm/prestate_tracer_test.go @@ -13,13 +13,14 @@ import ( "unicode" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/core/vm" "github.com/ava-labs/coreth/eth/tracers" "github.com/ava-labs/coreth/tests" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + ethtypes "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" ) func TestPrestateWithDiffModeANTTracer(t *testing.T) { @@ -57,16 +58,18 @@ func testPrestateDiffTracer(tracerName string, dirPath string, t *testing.T) { var ( signer = types.MakeSigner(test.Genesis.Config, new(big.Int).SetUint64(uint64(test.Context.Number)), uint64(test.Context.Time)) context = vm.BlockContext{ - CanTransfer: core.CanTransfer, - CanTransferMC: core.CanTransferMC, - Transfer: core.Transfer, - TransferMultiCoin: core.TransferMultiCoin, - Coinbase: test.Context.Miner, - BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), - Time: uint64(test.Context.Time), - Difficulty: (*big.Int)(test.Context.Difficulty), - GasLimit: uint64(test.Context.GasLimit), - BaseFee: test.Genesis.BaseFee, + CanTransfer: core.CanTransfer, + Transfer: core.Transfer, + Coinbase: test.Context.Miner, + BlockNumber: new(big.Int).SetUint64(uint64(test.Context.Number)), + Time: uint64(test.Context.Time), + Difficulty: (*big.Int)(test.Context.Difficulty), + GasLimit: uint64(test.Context.GasLimit), + BaseFee: test.Genesis.BaseFee, + Header: ðtypes.Header{ + Number: new(big.Int).SetUint64(uint64(test.Context.Number)), + Time: uint64(test.Context.Time), + }, } state = tests.MakePreState(rawdb.NewMemoryDatabase(), test.Genesis.Alloc, false, rawdb.HashScheme) ) diff --git a/plugin/evm/syncervm_client.go b/plugin/evm/syncervm_client.go index c25f68c46b..d0da18a713 100644 --- a/plugin/evm/syncervm_client.go +++ b/plugin/evm/syncervm_client.go @@ -14,16 +14,16 @@ import ( commonEng "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/vms/components/chain" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state/snapshot" "github.com/ava-labs/coreth/eth" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/message" syncclient "github.com/ava-labs/coreth/sync/client" "github.com/ava-labs/coreth/sync/statesync" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" ) const ( diff --git a/plugin/evm/syncervm_server.go b/plugin/evm/syncervm_server.go index 3bf051bf87..f249169193 100644 --- a/plugin/evm/syncervm_server.go +++ b/plugin/evm/syncervm_server.go @@ -12,8 +12,8 @@ import ( "github.com/ava-labs/coreth/core" "github.com/ava-labs/coreth/plugin/evm/message" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) type stateSyncServerConfig struct { diff --git a/plugin/evm/syncervm_test.go b/plugin/evm/syncervm_test.go index 4e42bfac7e..d6f479dfbb 100644 --- a/plugin/evm/syncervm_test.go +++ b/plugin/evm/syncervm_test.go @@ -28,24 +28,26 @@ import ( "github.com/ava-labs/avalanchego/utils/set" "github.com/ava-labs/avalanchego/utils/units" - "github.com/ava-labs/coreth/accounts/keystore" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/constants" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/atomic" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/plugin/evm/database" "github.com/ava-labs/coreth/predicate" statesyncclient "github.com/ava-labs/coreth/sync/client" "github.com/ava-labs/coreth/sync/statesync" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" ) func TestSkipStateSync(t *testing.T) { @@ -426,7 +428,7 @@ type syncVMSetup struct { serverAppSender *enginetest.Sender includedAtomicTxs []*atomic.Tx - fundedAccounts map[*keystore.Key]*types.StateAccount + fundedAccounts map[*utils.Key]*types.StateAccount syncerVM *VM syncerDB avalanchedatabase.Database @@ -604,8 +606,8 @@ func patchBlock(blk *types.Block, root common.Hash, db ethdb.Database) *types.Bl header := blk.Header() header.Root = root receipts := rawdb.ReadRawReceipts(db, blk.Hash(), blk.NumberU64()) - newBlk := types.NewBlockWithExtData( - header, blk.Transactions(), blk.Uncles(), receipts, trie.NewStackTrie(nil), blk.ExtData(), true, + newBlk := customtypes.NewBlockWithExtData( + header, blk.Transactions(), blk.Uncles(), receipts, trie.NewStackTrie(nil), customtypes.BlockExtData(blk), true, ) rawdb.WriteBlock(db, newBlk) rawdb.WriteCanonicalHash(db, newBlk.Hash(), newBlk.NumberU64()) @@ -662,12 +664,12 @@ func generateAndAcceptBlocks(t *testing.T, vm *VM, numBlocks int, gen func(int, // assertSyncPerformedHeights iterates over all heights the VM has synced to and // verifies it matches [expected]. func assertSyncPerformedHeights(t *testing.T, db ethdb.Iteratee, expected map[uint64]struct{}) { - it := rawdb.NewSyncPerformedIterator(db) + it := customrawdb.NewSyncPerformedIterator(db) defer it.Release() found := make(map[uint64]struct{}, len(expected)) for it.Next() { - found[rawdb.UnpackSyncPerformedKey(it.Key())] = struct{}{} + found[customrawdb.UnpackSyncPerformedKey(it.Key())] = struct{}{} } require.NoError(t, it.Error()) require.Equal(t, expected, found) diff --git a/plugin/evm/testdata/prestate_tracer_ant/sload.json b/plugin/evm/testdata/prestate_tracer_ant/sload.json index eb91e878f7..2ed6c8a110 100644 --- a/plugin/evm/testdata/prestate_tracer_ant/sload.json +++ b/plugin/evm/testdata/prestate_tracer_ant/sload.json @@ -33,6 +33,7 @@ "petersburgBlock": 0, "istanbulBlock": 0, "muirGlacierBlock": 0, + "berlinBlock": 0, "apricotPhase1BlockTimestamp": 0, "apricotPhase2BlockTimestamp": 0 }, diff --git a/plugin/evm/tx_gossip_test.go b/plugin/evm/tx_gossip_test.go index cf39d62515..96e6b21449 100644 --- a/plugin/evm/tx_gossip_test.go +++ b/plugin/evm/tx_gossip_test.go @@ -33,11 +33,11 @@ import ( "google.golang.org/protobuf/proto" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/plugin/evm/config" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/core/types" ) func TestEthTxGossip(t *testing.T) { diff --git a/plugin/evm/tx_test.go b/plugin/evm/tx_test.go index 1395766fe8..d7f5c6bc10 100644 --- a/plugin/evm/tx_test.go +++ b/plugin/evm/tx_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/require" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" - "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/utils" @@ -62,7 +62,7 @@ func TestCalculateDynamicFee(t *testing.T) { type atomicTxVerifyTest struct { ctx *snow.Context generate func(t *testing.T) atomic.UnsignedAtomicTx - rules params.Rules + rules extras.Rules expectedErr string } diff --git a/plugin/evm/upgrade/acp176/acp176_test.go b/plugin/evm/upgrade/acp176/acp176_test.go index ab6e4b1f1f..a717c8c3d1 100644 --- a/plugin/evm/upgrade/acp176/acp176_test.go +++ b/plugin/evm/upgrade/acp176/acp176_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/ava-labs/avalanchego/vms/components/gas" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/require" ) diff --git a/plugin/evm/upgrade/ap0/params.go b/plugin/evm/upgrade/ap0/params.go index 48625ecade..f353bce8ec 100644 --- a/plugin/evm/upgrade/ap0/params.go +++ b/plugin/evm/upgrade/ap0/params.go @@ -19,4 +19,12 @@ const ( // // This value was replaced with the Apricot Phase 3 dynamic fee mechanism. AtomicTxFee = units.MilliAvax + + // Note: MaximumExtraDataSize has been reduced to 32 in Geth, but is kept the same in Coreth for + // backwards compatibility. + MaximumExtraDataSize = 64 // Maximum size extra data may be after Genesis. + + MinGasLimit = 5000 // Minimum the gas limit may ever be. + MaxGasLimit = 0x7fffffffffffffff // Maximum the gas limit (2^63-1). + GasLimitBoundDivisor = 1024 // The bound divisor of the gas limit, used in update calculations. ) diff --git a/plugin/evm/upgrade/ap3/window.go b/plugin/evm/upgrade/ap3/window.go index ce1f0a4d4d..487eb244c2 100644 --- a/plugin/evm/upgrade/ap3/window.go +++ b/plugin/evm/upgrade/ap3/window.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/coreth/utils" - safemath "github.com/ethereum/go-ethereum/common/math" + safemath "github.com/ava-labs/libevm/common/math" ) const ( diff --git a/plugin/evm/upgrade/ap3/window_test.go b/plugin/evm/upgrade/ap3/window_test.go index 96731c54cf..4e5fd3af6f 100644 --- a/plugin/evm/upgrade/ap3/window_test.go +++ b/plugin/evm/upgrade/ap3/window_test.go @@ -7,7 +7,7 @@ import ( "strconv" "testing" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common/math" "github.com/stretchr/testify/require" ) diff --git a/plugin/evm/vm.go b/plugin/evm/vm.go index acd59d4585..ed93b95e89 100644 --- a/plugin/evm/vm.go +++ b/plugin/evm/vm.go @@ -23,21 +23,21 @@ import ( "github.com/ava-labs/avalanchego/network/p2p/gossip" "github.com/ava-labs/avalanchego/upgrade" avalanchegoConstants "github.com/ava-labs/avalanchego/utils/constants" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/prometheus/client_golang/prometheus" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/constants" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/txpool" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth" "github.com/ava-labs/coreth/eth/ethconfig" corethprometheus "github.com/ava-labs/coreth/metrics/prometheus" "github.com/ava-labs/coreth/miner" "github.com/ava-labs/coreth/node" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/peer" "github.com/ava-labs/coreth/plugin/evm/atomic" "github.com/ava-labs/coreth/plugin/evm/config" @@ -45,10 +45,13 @@ import ( "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/plugin/evm/upgrade/acp176" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap5" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/triedb/hashdb" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" "github.com/ava-labs/libevm/metrics" + ethparams "github.com/ava-labs/libevm/params" + "github.com/ava-labs/libevm/triedb" warpcontract "github.com/ava-labs/coreth/precompile/contracts/warp" "github.com/ava-labs/coreth/rpc" @@ -61,17 +64,17 @@ import ( // We must import this package (not referenced elsewhere) so that the native "callTracer" // is added to a map of client-accessible tracers. In geth, this is done // inside of cmd/geth. - _ "github.com/ava-labs/coreth/eth/tracers/js" - _ "github.com/ava-labs/coreth/eth/tracers/native" + _ "github.com/ava-labs/libevm/eth/tracers/js" + _ "github.com/ava-labs/libevm/eth/tracers/native" "github.com/ava-labs/coreth/precompile/precompileconfig" // Force-load precompiles to trigger registration _ "github.com/ava-labs/coreth/precompile/registry" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" avalancheRPC "github.com/gorilla/rpc/v2" @@ -333,7 +336,7 @@ func (vm *VM) Logger() logging.Logger { return vm.ctx.Log } // implements SnowmanPlusPlusVM interface func (vm *VM) GetActivationTime() time.Time { - return utils.Uint64ToTime(vm.chainConfig.ApricotPhase4BlockTimestamp) + return utils.Uint64ToTime(vm.chainConfigExtra().ApricotPhase4BlockTimestamp) } // Initialize implements the snowman.ChainVM interface @@ -383,7 +386,7 @@ func (vm *VM) Initialize( } vm.logger = corethLogger - log.Info("Initializing Coreth VM", "Version", Version, "Config", vm.config) + log.Info("Initializing Coreth VM", "Version", Version, "libevm version", ethparams.LibEVMVersion, "Config", vm.config) if deprecateMsg != "" { log.Warn("Deprecation Warning", "msg", deprecateMsg) @@ -430,18 +433,19 @@ func (vm *VM) Initialize( // if the chainCtx.NetworkUpgrades is not empty, set the chain config // normally it should not be empty, but some tests may not set it if chainCtx.NetworkUpgrades != (upgrade.Config{}) { - g.Config.NetworkUpgrades = params.GetNetworkUpgrades(chainCtx.NetworkUpgrades) + params.GetExtra(g.Config).NetworkUpgrades = extras.GetNetworkUpgrades(chainCtx.NetworkUpgrades) } // If the Durango is activated, activate the Warp Precompile at the same time - if g.Config.DurangoBlockTimestamp != nil { - g.Config.PrecompileUpgrades = append(g.Config.PrecompileUpgrades, params.PrecompileUpgrade{ - Config: warpcontract.NewDefaultConfig(g.Config.DurangoBlockTimestamp), + configExtra := params.GetExtra(g.Config) + if configExtra.DurangoBlockTimestamp != nil { + configExtra.PrecompileUpgrades = append(configExtra.PrecompileUpgrades, extras.PrecompileUpgrade{ + Config: warpcontract.NewDefaultConfig(configExtra.DurangoBlockTimestamp), }) } // Set the Avalanche Context on the ChainConfig - g.Config.AvalancheContext = params.AvalancheContext{ + configExtra.AvalancheContext = extras.AvalancheContext{ SnowCtx: chainCtx, } vm.syntacticBlockValidator = NewBlockValidator(extDataHashes) @@ -453,7 +457,7 @@ func (vm *VM) Initialize( vm.chainID = g.Config.ChainID - g.Config.SetEthUpgrades() + params.SetEthUpgrades(g.Config) vm.ethConfig = ethconfig.NewDefaultConfig() vm.ethConfig.Genesis = g @@ -527,7 +531,7 @@ func (vm *VM) Initialize( }, } - if err := vm.chainConfig.Verify(); err != nil { + if err := configExtra.Verify(); err != nil { return fmt.Errorf("failed to verify chain config: %w", err) } @@ -803,7 +807,7 @@ func (vm *VM) preBatchOnFinalizeAndAssemble(header *types.Header, state *state.S // Note: snapshot is taken inside the loop because you cannot revert to the same snapshot more than // once. snapshot := state.Snapshot() - rules := vm.chainConfig.Rules(header.Number, header.Time) + rules := vm.rules(header.Number, header.Time) if err := vm.verifyTx(tx, header.ParentHash, header.BaseFee, state, rules); err != nil { // Discard the transaction from the mempool on failed verification. log.Debug("discarding tx from mempool on failed verification", "txID", tx.ID(), "err", err) @@ -850,11 +854,11 @@ func (vm *VM) postBatchOnFinalizeAndAssemble( batchAtomicUTXOs set.Set[ids.ID] batchContribution *big.Int = new(big.Int).Set(common.Big0) batchGasUsed *big.Int = new(big.Int).Set(common.Big0) - rules = vm.chainConfig.Rules(header.Number, header.Time) + rules = vm.rules(header.Number, header.Time) size int ) - atomicGasLimit, err := customheader.RemainingAtomicGasCapacity(vm.chainConfig, parent, header) + atomicGasLimit, err := customheader.RemainingAtomicGasCapacity(vm.chainConfigExtra(), parent, header) if err != nil { return nil, nil, nil, err } @@ -955,7 +959,7 @@ func (vm *VM) onFinalizeAndAssemble( state *state.StateDB, txs []*types.Transaction, ) ([]byte, *big.Int, *big.Int, error) { - if !vm.chainConfig.IsApricotPhase5(header.Time) { + if !vm.chainConfigExtra().IsApricotPhase5(header.Time) { return vm.preBatchOnFinalizeAndAssemble(header, state, txs) } return vm.postBatchOnFinalizeAndAssemble(header, parent, state, txs) @@ -966,10 +970,10 @@ func (vm *VM) onExtraStateChange(block *types.Block, parent *types.Header, state batchContribution *big.Int = big.NewInt(0) batchGasUsed *big.Int = big.NewInt(0) header = block.Header() - rules = vm.chainConfig.Rules(header.Number, header.Time) + rules = vm.rules(header.Number, header.Time) ) - txs, err := atomic.ExtractAtomicTxs(block.ExtData(), rules.IsApricotPhase5, atomic.Codec) + txs, err := atomic.ExtractAtomicTxs(customtypes.BlockExtData(block), rules.IsApricotPhase5, atomic.Codec) if err != nil { return nil, nil, err } @@ -1018,7 +1022,7 @@ func (vm *VM) onExtraStateChange(block *types.Block, parent *types.Header, state // If ApricotPhase5 is enabled, enforce that the atomic gas used does not exceed the // atomic gas limit. if rules.IsApricotPhase5 { - atomicGasLimit, err := customheader.RemainingAtomicGasCapacity(vm.chainConfig, parent, header) + atomicGasLimit, err := customheader.RemainingAtomicGasCapacity(vm.chainConfigExtra(), parent, header) if err != nil { return nil, nil, err } @@ -1270,9 +1274,9 @@ func (vm *VM) setAppRequestHandlers() { evmTrieDB := triedb.NewDatabase( vm.chaindb, &triedb.Config{ - HashDB: &hashdb.Config{ + DBOverride: hashdb.Config{ CleanCacheSize: vm.config.StateSyncServerTrieCache * units.MiB, - }, + }.BackendConstructor, }, ) networkHandler := newNetworkHandler( @@ -1625,8 +1629,8 @@ func (vm *VM) verifyTxAtTip(tx *atomic.Tx) error { parentHeader := preferredBlock var nextBaseFee *big.Int timestamp := uint64(vm.clock.Time().Unix()) - if vm.chainConfig.IsApricotPhase3(timestamp) { - nextBaseFee, err = customheader.EstimateNextBaseFee(vm.chainConfig, parentHeader, timestamp) + if vm.chainConfigExtra().IsApricotPhase3(timestamp) { + nextBaseFee, err = customheader.EstimateNextBaseFee(vm.chainConfigExtra(), parentHeader, timestamp) if err != nil { // Return extremely detailed error since CalcBaseFee should never encounter an issue here return fmt.Errorf("failed to calculate base fee with parent timestamp (%d), parent ExtraData: (0x%x), and current timestamp (%d): %w", parentHeader.Time, parentHeader.Extra, timestamp, err) @@ -1643,7 +1647,7 @@ func (vm *VM) verifyTxAtTip(tx *atomic.Tx) error { // Note: verifyTx may modify [state]. If [state] needs to be properly maintained, the caller is responsible // for reverting to the correct snapshot after calling this function. If this function is called with a // throwaway state, then this is not necessary. -func (vm *VM) verifyTx(tx *atomic.Tx, parentHash common.Hash, baseFee *big.Int, state *state.StateDB, rules params.Rules) error { +func (vm *VM) verifyTx(tx *atomic.Tx, parentHash common.Hash, baseFee *big.Int, state *state.StateDB, rules extras.Rules) error { parentIntf, err := vm.GetBlockInternal(context.TODO(), ids.ID(parentHash)) if err != nil { return fmt.Errorf("failed to get parent block: %w", err) @@ -1668,7 +1672,7 @@ func (vm *VM) verifyTx(tx *atomic.Tx, parentHash common.Hash, baseFee *big.Int, // verifyTxs verifies that [txs] are valid to be issued into a block with parent block [parentHash] // using [rules] as the current rule set. -func (vm *VM) verifyTxs(txs []*atomic.Tx, parentHash common.Hash, baseFee *big.Int, height uint64, rules params.Rules) error { +func (vm *VM) verifyTxs(txs []*atomic.Tx, parentHash common.Hash, baseFee *big.Int, height uint64, rules extras.Rules) error { // Ensure that the parent was verified and inserted correctly. if !vm.blockChain.HasBlock(parentHash, height-1) { return errRejectedParent @@ -1737,17 +1741,26 @@ func (vm *VM) GetAtomicUTXOs( ) } +func (vm *VM) chainConfigExtra() *extras.ChainConfig { + return params.GetExtra(vm.chainConfig) +} + +func (vm *VM) rules(number *big.Int, time uint64) extras.Rules { + ethrules := vm.chainConfig.Rules(number, params.IsMergeTODO, time) + return *params.GetRulesExtra(ethrules) +} + // currentRules returns the chain rules for the current block. -func (vm *VM) currentRules() params.Rules { +func (vm *VM) currentRules() extras.Rules { header := vm.eth.APIBackend.CurrentHeader() - return vm.chainConfig.Rules(header.Number, header.Time) + return vm.rules(header.Number, header.Time) } // requirePrimaryNetworkSigners returns true if warp messages from the primary // network must be signed by the primary network validators. // This is necessary when the subnet is not validating the primary network. func (vm *VM) requirePrimaryNetworkSigners() bool { - switch c := vm.currentRules().ActivePrecompiles[warpcontract.ContractAddress].(type) { + switch c := vm.currentRules().Precompiles[warpcontract.ContractAddress].(type) { case *warpcontract.Config: return c.RequirePrimaryNetworkSigners default: // includes nil due to non-presence diff --git a/plugin/evm/vm_database.go b/plugin/evm/vm_database.go index f2a5b4c344..8ec3b22b15 100644 --- a/plugin/evm/vm_database.go +++ b/plugin/evm/vm_database.go @@ -9,10 +9,10 @@ import ( avalanchedatabase "github.com/ava-labs/avalanchego/database" "github.com/ava-labs/avalanchego/database/prefixdb" "github.com/ava-labs/avalanchego/database/versiondb" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/plugin/evm/database" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/log" ) // initializeDBs initializes the databases used by the VM. diff --git a/plugin/evm/vm_test.go b/plugin/evm/vm_test.go index 8c0d58f834..4cd681aeff 100644 --- a/plugin/evm/vm_test.go +++ b/plugin/evm/vm_test.go @@ -5,7 +5,6 @@ package evm import ( "context" - "crypto/rand" "encoding/json" "errors" "fmt" @@ -16,9 +15,9 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" "github.com/holiman/uint256" "github.com/ava-labs/coreth/constants" @@ -28,8 +27,8 @@ import ( "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap1" - "github.com/ava-labs/coreth/trie" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/trie" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -61,13 +60,13 @@ import ( "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/plugin/evm/customtypes" "github.com/ava-labs/coreth/rpc" + "github.com/ava-labs/libevm/core/types" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" - accountKeystore "github.com/ava-labs/coreth/accounts/keystore" ) var ( @@ -96,10 +95,10 @@ var ( json.Unmarshal([]byte(allocStr), &g.Alloc) // After Durango, an additional account is funded in tests to use // with warp messages. - if cfg.IsDurango(0) { + if params.GetExtra(cfg).IsDurango(0) { addr := common.HexToAddress("0x99b9DEA54C48Dfea6aA9A4Ca4623633EE04ddbB5") balance := new(big.Int).Mul(big.NewInt(params.Ether), big.NewInt(10)) - g.Alloc[addr] = types.GenesisAccount{Balance: balance} + g.Alloc[addr] = types.Account{Balance: balance} } b, err := json.Marshal(g) @@ -134,15 +133,14 @@ var ( genesisJSONCancun = genesisJSON(activateCancun(params.TestChainConfig)) - apricotRulesPhase0 = params.Rules{} - apricotRulesPhase1 = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true}} - apricotRulesPhase2 = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true, IsApricotPhase2: true}} - apricotRulesPhase3 = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true, IsApricotPhase2: true, IsApricotPhase3: true}} - apricotRulesPhase4 = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true, IsApricotPhase2: true, IsApricotPhase3: true, IsApricotPhase4: true}} - apricotRulesPhase5 = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true, IsApricotPhase2: true, IsApricotPhase3: true, IsApricotPhase4: true, IsApricotPhase5: true}} - apricotRulesPhase6 = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true, IsApricotPhase2: true, IsApricotPhase3: true, IsApricotPhase4: true, IsApricotPhase5: true, IsApricotPhasePre6: true, IsApricotPhase6: true, IsApricotPhasePost6: true}} - banffRules = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true, IsApricotPhase2: true, IsApricotPhase3: true, IsApricotPhase4: true, IsApricotPhase5: true, IsApricotPhasePre6: true, IsApricotPhase6: true, IsApricotPhasePost6: true, IsBanff: true}} - // cortinaRules = params.Rules{AvalancheRules: params.AvalancheRules{IsApricotPhase1: true, IsApricotPhase2: true, IsApricotPhase3: true, IsApricotPhase4: true, IsApricotPhase5: true, IsApricotPhasePre6: true, IsApricotPhase6: true, IsApricotPhasePost6: true, IsBanff: true, IsCortina: true}} + apricotRulesPhase0 = *params.GetRulesExtra(params.TestLaunchConfig.Rules(common.Big0, params.IsMergeTODO, 0)) + apricotRulesPhase1 = *params.GetRulesExtra(params.TestApricotPhase1Config.Rules(common.Big0, params.IsMergeTODO, 0)) + apricotRulesPhase2 = *params.GetRulesExtra(params.TestApricotPhase2Config.Rules(common.Big0, params.IsMergeTODO, 0)) + apricotRulesPhase3 = *params.GetRulesExtra(params.TestApricotPhase3Config.Rules(common.Big0, params.IsMergeTODO, 0)) + apricotRulesPhase4 = *params.GetRulesExtra(params.TestApricotPhase4Config.Rules(common.Big0, params.IsMergeTODO, 0)) + apricotRulesPhase5 = *params.GetRulesExtra(params.TestApricotPhase5Config.Rules(common.Big0, params.IsMergeTODO, 0)) + apricotRulesPhase6 = *params.GetRulesExtra(params.TestApricotPhase6Config.Rules(common.Big0, params.IsMergeTODO, 0)) + banffRules = *params.GetRulesExtra(params.TestBanffChainConfig.Rules(common.Big0, params.IsMergeTODO, 0)) ) func init() { @@ -167,7 +165,7 @@ func newPrefundedGenesis( ) *core.Genesis { alloc := types.GenesisAlloc{} for _, address := range addresses { - alloc[address] = types.GenesisAccount{ + alloc[address] = types.Account{ Balance: big.NewInt(int64(balance)), } } @@ -948,7 +946,7 @@ func testConflictingImportTxs(t *testing.T, genesis string) { t.Fatal(err) } - conflictingAtomicTxBlock := types.NewBlockWithExtData( + conflictingAtomicTxBlock := customtypes.NewBlockWithExtData( types.CopyHeader(validEthBlock.Header()), nil, nil, @@ -982,9 +980,10 @@ func testConflictingImportTxs(t *testing.T, genesis string) { } header := types.CopyHeader(validEthBlock.Header()) - header.ExtDataGasUsed.Mul(common.Big2, header.ExtDataGasUsed) + headerExtra := customtypes.GetHeaderExtra(header) + headerExtra.ExtDataGasUsed.Mul(common.Big2, headerExtra.ExtDataGasUsed) - internalConflictBlock := types.NewBlockWithExtData( + internalConflictBlock := customtypes.NewBlockWithExtData( header, nil, nil, @@ -1378,10 +1377,7 @@ func TestSetPreferenceRace(t *testing.T) { } func TestConflictingTransitiveAncestryWithGap(t *testing.T) { - key, err := accountKeystore.NewKey(rand.Reader) - if err != nil { - t.Fatal(err) - } + key := utils.NewKey(t) key0 := testKeys[0] addr0 := key0.Address() @@ -2384,13 +2380,13 @@ func TestUncleBlock(t *testing.T) { uncleBlockHeader := types.CopyHeader(blkDEthBlock.Header()) uncleBlockHeader.UncleHash = types.CalcUncleHash(uncles) - uncleEthBlock := types.NewBlockWithExtData( + uncleEthBlock := customtypes.NewBlockWithExtData( uncleBlockHeader, blkDEthBlock.Transactions(), uncles, nil, trie.NewStackTrie(nil), - blkDEthBlock.ExtData(), + customtypes.BlockExtData(blkDEthBlock), false, ) uncleBlock, err := vm2.newBlock(uncleEthBlock) @@ -2441,7 +2437,7 @@ func TestEmptyBlock(t *testing.T) { // Create empty block from blkA ethBlock := blk.(*chain.BlockWrapper).Block.(*Block).ethBlock - emptyEthBlock := types.NewBlockWithExtData( + emptyEthBlock := customtypes.NewBlockWithExtData( types.CopyHeader(ethBlock.Header()), nil, nil, @@ -2451,7 +2447,7 @@ func TestEmptyBlock(t *testing.T) { false, ) - if len(emptyEthBlock.ExtData()) != 0 || emptyEthBlock.Header().ExtDataHash != (common.Hash{}) { + if len(customtypes.BlockExtData(emptyEthBlock)) != 0 || customtypes.GetHeaderExtra(emptyEthBlock.Header()).ExtDataHash != (common.Hash{}) { t.Fatalf("emptyEthBlock should not have any extra data") } @@ -2711,13 +2707,13 @@ func TestFutureBlock(t *testing.T) { // Set the modified time to exceed the allowed future time modifiedTime := modifiedHeader.Time + uint64(maxFutureBlockTime.Seconds()+1) modifiedHeader.Time = modifiedTime - modifiedBlock := types.NewBlockWithExtData( + modifiedBlock := customtypes.NewBlockWithExtData( modifiedHeader, nil, nil, nil, new(trie.Trie), - internalBlkA.ethBlock.ExtData(), + customtypes.BlockExtData(internalBlkA.ethBlock), false, ) @@ -3272,13 +3268,13 @@ func TestBuildApricotPhase4Block(t *testing.T) { } ethBlk := blk.(*chain.BlockWrapper).Block.(*Block).ethBlock - if eBlockGasCost := ethBlk.BlockGasCost(); eBlockGasCost == nil || eBlockGasCost.Cmp(common.Big0) != 0 { + if eBlockGasCost := customtypes.BlockGasCost(ethBlk); eBlockGasCost == nil || eBlockGasCost.Cmp(common.Big0) != 0 { t.Fatalf("expected blockGasCost to be 0 but got %d", eBlockGasCost) } - if eExtDataGasUsed := ethBlk.ExtDataGasUsed(); eExtDataGasUsed == nil || eExtDataGasUsed.Cmp(big.NewInt(1230)) != 0 { + if eExtDataGasUsed := customtypes.BlockExtDataGasUsed(ethBlk); eExtDataGasUsed == nil || eExtDataGasUsed.Cmp(big.NewInt(1230)) != 0 { t.Fatalf("expected extDataGasUsed to be 1000 but got %d", eExtDataGasUsed) } - minRequiredTip, err := header.EstimateRequiredTip(vm.chainConfig, ethBlk.Header()) + minRequiredTip, err := header.EstimateRequiredTip(vm.chainConfigExtra(), ethBlk.Header()) if err != nil { t.Fatal(err) } @@ -3331,13 +3327,13 @@ func TestBuildApricotPhase4Block(t *testing.T) { } ethBlk = blk.(*chain.BlockWrapper).Block.(*Block).ethBlock - if ethBlk.BlockGasCost() == nil || ethBlk.BlockGasCost().Cmp(big.NewInt(100)) < 0 { - t.Fatalf("expected blockGasCost to be at least 100 but got %d", ethBlk.BlockGasCost()) + if customtypes.BlockGasCost(ethBlk) == nil || customtypes.BlockGasCost(ethBlk).Cmp(big.NewInt(100)) < 0 { + t.Fatalf("expected blockGasCost to be at least 100 but got %d", customtypes.BlockGasCost(ethBlk)) } - if ethBlk.ExtDataGasUsed() == nil || ethBlk.ExtDataGasUsed().Cmp(common.Big0) != 0 { - t.Fatalf("expected extDataGasUsed to be 0 but got %d", ethBlk.ExtDataGasUsed()) + if customtypes.BlockExtDataGasUsed(ethBlk) == nil || customtypes.BlockExtDataGasUsed(ethBlk).Cmp(common.Big0) != 0 { + t.Fatalf("expected extDataGasUsed to be 0 but got %d", customtypes.BlockExtDataGasUsed(ethBlk)) } - minRequiredTip, err = header.EstimateRequiredTip(vm.chainConfig, ethBlk.Header()) + minRequiredTip, err = header.EstimateRequiredTip(vm.chainConfigExtra(), ethBlk.Header()) if err != nil { t.Fatal(err) } @@ -3442,13 +3438,13 @@ func TestBuildApricotPhase5Block(t *testing.T) { } ethBlk := blk.(*chain.BlockWrapper).Block.(*Block).ethBlock - if eBlockGasCost := ethBlk.BlockGasCost(); eBlockGasCost == nil || eBlockGasCost.Cmp(common.Big0) != 0 { + if eBlockGasCost := customtypes.BlockGasCost(ethBlk); eBlockGasCost == nil || eBlockGasCost.Cmp(common.Big0) != 0 { t.Fatalf("expected blockGasCost to be 0 but got %d", eBlockGasCost) } - if eExtDataGasUsed := ethBlk.ExtDataGasUsed(); eExtDataGasUsed == nil || eExtDataGasUsed.Cmp(big.NewInt(11230)) != 0 { + if eExtDataGasUsed := customtypes.BlockExtDataGasUsed(ethBlk); eExtDataGasUsed == nil || eExtDataGasUsed.Cmp(big.NewInt(11230)) != 0 { t.Fatalf("expected extDataGasUsed to be 11230 but got %d", eExtDataGasUsed) } - minRequiredTip, err := header.EstimateRequiredTip(vm.chainConfig, ethBlk.Header()) + minRequiredTip, err := header.EstimateRequiredTip(vm.chainConfigExtra(), ethBlk.Header()) if err != nil { t.Fatal(err) } @@ -3493,13 +3489,13 @@ func TestBuildApricotPhase5Block(t *testing.T) { } ethBlk = blk.(*chain.BlockWrapper).Block.(*Block).ethBlock - if ethBlk.BlockGasCost() == nil || ethBlk.BlockGasCost().Cmp(big.NewInt(100)) < 0 { - t.Fatalf("expected blockGasCost to be at least 100 but got %d", ethBlk.BlockGasCost()) + if customtypes.BlockGasCost(ethBlk) == nil || customtypes.BlockGasCost(ethBlk).Cmp(big.NewInt(100)) < 0 { + t.Fatalf("expected blockGasCost to be at least 100 but got %d", customtypes.BlockGasCost(ethBlk)) } - if ethBlk.ExtDataGasUsed() == nil || ethBlk.ExtDataGasUsed().Cmp(common.Big0) != 0 { - t.Fatalf("expected extDataGasUsed to be 0 but got %d", ethBlk.ExtDataGasUsed()) + if customtypes.BlockExtDataGasUsed(ethBlk) == nil || customtypes.BlockExtDataGasUsed(ethBlk).Cmp(common.Big0) != 0 { + t.Fatalf("expected extDataGasUsed to be 0 but got %d", customtypes.BlockExtDataGasUsed(ethBlk)) } - minRequiredTip, err = header.EstimateRequiredTip(vm.chainConfig, ethBlk.Header()) + minRequiredTip, err = header.EstimateRequiredTip(vm.chainConfigExtra(), ethBlk.Header()) if err != nil { t.Fatal(err) } @@ -3591,10 +3587,7 @@ func TestAtomicTxBuildBlockDropsConflicts(t *testing.T) { testShortIDAddrs[1]: importAmount, testShortIDAddrs[2]: importAmount, }) - conflictKey, err := accountKeystore.NewKey(rand.Reader) - if err != nil { - t.Fatal(err) - } + conflictKey := utils.NewKey(t) defer func() { if err := vm.Shutdown(context.Background()); err != nil { t.Fatal(err) @@ -3757,7 +3750,7 @@ func TestExtraStateChangeAtomicGasLimitExceeded(t *testing.T) { } // Construct the new block with the extra data in the new format (slice of atomic transactions). - ethBlk2 := types.NewBlockWithExtData( + ethBlk2 := customtypes.NewBlockWithExtData( types.CopyHeader(validEthBlock.Header()), nil, nil, @@ -3803,7 +3796,7 @@ func TestSkipChainConfigCheckCompatible(t *testing.T) { // is hardcoded to be allowed in core/genesis.go. genesisWithUpgrade := &core.Genesis{} require.NoError(t, json.Unmarshal([]byte(genesisJSONApricotPhase1), genesisWithUpgrade)) - genesisWithUpgrade.Config.ApricotPhase2BlockTimestamp = utils.TimeToNewUint64(blk.Timestamp()) + params.GetExtra(genesisWithUpgrade.Config).ApricotPhase2BlockTimestamp = utils.TimeToNewUint64(blk.Timestamp()) genesisWithUpgradeBytes, err := json.Marshal(genesisWithUpgrade) require.NoError(t, err) @@ -3904,13 +3897,13 @@ func TestParentBeaconRootBlock(t *testing.T) { ethBlock := blk.(*chain.BlockWrapper).Block.(*Block).ethBlock header := types.CopyHeader(ethBlock.Header()) header.ParentBeaconRoot = test.beaconRoot - parentBeaconEthBlock := types.NewBlockWithExtData( + parentBeaconEthBlock := customtypes.NewBlockWithExtData( header, nil, nil, nil, new(trie.Trie), - ethBlock.ExtData(), + customtypes.BlockExtData(ethBlock), false, ) diff --git a/plugin/evm/vm_warp_test.go b/plugin/evm/vm_warp_test.go index abcb8b058c..a6017bfd59 100644 --- a/plugin/evm/vm_warp_test.go +++ b/plugin/evm/vm_warp_test.go @@ -27,10 +27,9 @@ import ( "github.com/ava-labs/avalanchego/vms/components/chain" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/eth/tracers" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" customheader "github.com/ava-labs/coreth/plugin/evm/header" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/plugin/evm/upgrade/ap0" @@ -39,8 +38,10 @@ import ( "github.com/ava-labs/coreth/predicate" "github.com/ava-labs/coreth/utils" "github.com/ava-labs/coreth/warp" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" "github.com/stretchr/testify/require" ) @@ -430,8 +431,8 @@ func TestReceiveWarpMessage(t *testing.T) { true, // RequirePrimaryNetworkSigners ) - vm.chainConfig.UpgradeConfig = params.UpgradeConfig{ - PrecompileUpgrades: []params.PrecompileUpgrade{ + vm.chainConfigExtra().UpgradeConfig = extras.UpgradeConfig{ + PrecompileUpgrades: []extras.PrecompileUpgrade{ {Config: enableConfig}, {Config: disableConfig}, {Config: reEnableConfig}, @@ -653,7 +654,7 @@ func testReceiveWarpMessage( // Require the block was built with a successful predicate result ethBlock := block2.(*chain.BlockWrapper).Block.(*Block).ethBlock - rules := vm.chainConfig.GetAvalancheRules(ethBlock.Time()) + rules := params.GetExtra(vm.chainConfig).GetAvalancheRules(ethBlock.Time()) headerPredicateResultsBytes := customheader.PredicateBytesFromExtra(rules, ethBlock.Extra()) results, err := predicate.ParseResults(headerPredicateResultsBytes) require.NoError(err) diff --git a/precompile/contract/contract.go b/precompile/contract/contract.go index 0be76a8955..b64c8058dc 100644 --- a/precompile/contract/contract.go +++ b/precompile/contract/contract.go @@ -6,7 +6,7 @@ package contract import ( "fmt" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) const ( diff --git a/precompile/contract/interfaces.go b/precompile/contract/interfaces.go index 44c3cfa633..188c3a0933 100644 --- a/precompile/contract/interfaces.go +++ b/precompile/contract/interfaces.go @@ -9,7 +9,9 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/coreth/precompile/precompileconfig" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + ethtypes "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/core/vm" "github.com/holiman/uint256" ) @@ -30,12 +32,14 @@ type StateDB interface { GetBalance(common.Address) *uint256.Int AddBalance(common.Address, *uint256.Int) GetBalanceMultiCoin(common.Address, common.Hash) *big.Int + AddBalanceMultiCoin(common.Address, common.Hash, *big.Int) + SubBalanceMultiCoin(common.Address, common.Hash, *big.Int) CreateAccount(common.Address) Exist(common.Address) bool - AddLog(addr common.Address, topics []common.Hash, data []byte, blockNumber uint64) - GetLogData() (topics [][]common.Hash, data [][]byte) + AddLog(*ethtypes.Log) + Logs() []*ethtypes.Log GetPredicateStorageSlots(address common.Address, index int) ([]byte, bool) SetPredicateStorageSlots(address common.Address, predicates [][]byte) @@ -51,7 +55,7 @@ type AccessibleState interface { GetBlockContext() BlockContext GetSnowContext() *snow.Context GetChainConfig() precompileconfig.ChainConfig - NativeAssetCall(caller common.Address, input []byte, suppliedGas uint64, gasCost uint64, readOnly bool) (ret []byte, remainingGas uint64, err error) + GetPrecompileEnv() vm.PrecompileEnvironment } // ConfigurationBlockContext defines the interface required to configure a precompile. @@ -62,8 +66,8 @@ type ConfigurationBlockContext interface { type BlockContext interface { ConfigurationBlockContext - // GetPredicateResults returns an arbitrary byte array result of verifying the predicates - // of the given transaction, precompile address pair. + // GetPredicateResults returns the result of verifying the predicates of the + // given transaction, precompile address pair as a byte array. GetPredicateResults(txHash common.Hash, precompileAddress common.Address) []byte } diff --git a/precompile/contract/mocks.go b/precompile/contract/mocks.go index 546090339f..3964bdb55a 100644 --- a/precompile/contract/mocks.go +++ b/precompile/contract/mocks.go @@ -1,9 +1,9 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/ava-labs/coreth/precompile/contract (interfaces: BlockContext,AccessibleState,StateDB) +// Source: interfaces.go // // Generated by this command: // -// mockgen -package=contract -destination=mocks.go . BlockContext,AccessibleState,StateDB +// mockgen -package=contract -source=interfaces.go -destination=mocks.go -exclude_interfaces StatefulPrecompiledContract,StateReader,ConfigurationBlockContext,Configurator // // Package contract is a generated GoMock package. @@ -15,173 +15,13 @@ import ( snow "github.com/ava-labs/avalanchego/snow" precompileconfig "github.com/ava-labs/coreth/precompile/precompileconfig" - common "github.com/ethereum/go-ethereum/common" + common "github.com/ava-labs/libevm/common" + types "github.com/ava-labs/libevm/core/types" + vm "github.com/ava-labs/libevm/core/vm" uint256 "github.com/holiman/uint256" gomock "go.uber.org/mock/gomock" ) -// MockBlockContext is a mock of BlockContext interface. -type MockBlockContext struct { - ctrl *gomock.Controller - recorder *MockBlockContextMockRecorder - isgomock struct{} -} - -// MockBlockContextMockRecorder is the mock recorder for MockBlockContext. -type MockBlockContextMockRecorder struct { - mock *MockBlockContext -} - -// NewMockBlockContext creates a new mock instance. -func NewMockBlockContext(ctrl *gomock.Controller) *MockBlockContext { - mock := &MockBlockContext{ctrl: ctrl} - mock.recorder = &MockBlockContextMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockBlockContext) EXPECT() *MockBlockContextMockRecorder { - return m.recorder -} - -// GetPredicateResults mocks base method. -func (m *MockBlockContext) GetPredicateResults(txHash common.Hash, precompileAddress common.Address) []byte { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetPredicateResults", txHash, precompileAddress) - ret0, _ := ret[0].([]byte) - return ret0 -} - -// GetPredicateResults indicates an expected call of GetPredicateResults. -func (mr *MockBlockContextMockRecorder) GetPredicateResults(txHash, precompileAddress any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPredicateResults", reflect.TypeOf((*MockBlockContext)(nil).GetPredicateResults), txHash, precompileAddress) -} - -// Number mocks base method. -func (m *MockBlockContext) Number() *big.Int { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Number") - ret0, _ := ret[0].(*big.Int) - return ret0 -} - -// Number indicates an expected call of Number. -func (mr *MockBlockContextMockRecorder) Number() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Number", reflect.TypeOf((*MockBlockContext)(nil).Number)) -} - -// Timestamp mocks base method. -func (m *MockBlockContext) Timestamp() uint64 { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Timestamp") - ret0, _ := ret[0].(uint64) - return ret0 -} - -// Timestamp indicates an expected call of Timestamp. -func (mr *MockBlockContextMockRecorder) Timestamp() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Timestamp", reflect.TypeOf((*MockBlockContext)(nil).Timestamp)) -} - -// MockAccessibleState is a mock of AccessibleState interface. -type MockAccessibleState struct { - ctrl *gomock.Controller - recorder *MockAccessibleStateMockRecorder - isgomock struct{} -} - -// MockAccessibleStateMockRecorder is the mock recorder for MockAccessibleState. -type MockAccessibleStateMockRecorder struct { - mock *MockAccessibleState -} - -// NewMockAccessibleState creates a new mock instance. -func NewMockAccessibleState(ctrl *gomock.Controller) *MockAccessibleState { - mock := &MockAccessibleState{ctrl: ctrl} - mock.recorder = &MockAccessibleStateMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockAccessibleState) EXPECT() *MockAccessibleStateMockRecorder { - return m.recorder -} - -// GetBlockContext mocks base method. -func (m *MockAccessibleState) GetBlockContext() BlockContext { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetBlockContext") - ret0, _ := ret[0].(BlockContext) - return ret0 -} - -// GetBlockContext indicates an expected call of GetBlockContext. -func (mr *MockAccessibleStateMockRecorder) GetBlockContext() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockContext", reflect.TypeOf((*MockAccessibleState)(nil).GetBlockContext)) -} - -// GetChainConfig mocks base method. -func (m *MockAccessibleState) GetChainConfig() precompileconfig.ChainConfig { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetChainConfig") - ret0, _ := ret[0].(precompileconfig.ChainConfig) - return ret0 -} - -// GetChainConfig indicates an expected call of GetChainConfig. -func (mr *MockAccessibleStateMockRecorder) GetChainConfig() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChainConfig", reflect.TypeOf((*MockAccessibleState)(nil).GetChainConfig)) -} - -// GetSnowContext mocks base method. -func (m *MockAccessibleState) GetSnowContext() *snow.Context { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetSnowContext") - ret0, _ := ret[0].(*snow.Context) - return ret0 -} - -// GetSnowContext indicates an expected call of GetSnowContext. -func (mr *MockAccessibleStateMockRecorder) GetSnowContext() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSnowContext", reflect.TypeOf((*MockAccessibleState)(nil).GetSnowContext)) -} - -// GetStateDB mocks base method. -func (m *MockAccessibleState) GetStateDB() StateDB { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStateDB") - ret0, _ := ret[0].(StateDB) - return ret0 -} - -// GetStateDB indicates an expected call of GetStateDB. -func (mr *MockAccessibleStateMockRecorder) GetStateDB() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateDB", reflect.TypeOf((*MockAccessibleState)(nil).GetStateDB)) -} - -// NativeAssetCall mocks base method. -func (m *MockAccessibleState) NativeAssetCall(caller common.Address, input []byte, suppliedGas, gasCost uint64, readOnly bool) ([]byte, uint64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "NativeAssetCall", caller, input, suppliedGas, gasCost, readOnly) - ret0, _ := ret[0].([]byte) - ret1, _ := ret[1].(uint64) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// NativeAssetCall indicates an expected call of NativeAssetCall. -func (mr *MockAccessibleStateMockRecorder) NativeAssetCall(caller, input, suppliedGas, gasCost, readOnly any) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NativeAssetCall", reflect.TypeOf((*MockAccessibleState)(nil).NativeAssetCall), caller, input, suppliedGas, gasCost, readOnly) -} - // MockStateDB is a mock of StateDB interface. type MockStateDB struct { ctrl *gomock.Controller @@ -218,16 +58,28 @@ func (mr *MockStateDBMockRecorder) AddBalance(arg0, arg1 any) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBalance", reflect.TypeOf((*MockStateDB)(nil).AddBalance), arg0, arg1) } +// AddBalanceMultiCoin mocks base method. +func (m *MockStateDB) AddBalanceMultiCoin(arg0 common.Address, arg1 common.Hash, arg2 *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "AddBalanceMultiCoin", arg0, arg1, arg2) +} + +// AddBalanceMultiCoin indicates an expected call of AddBalanceMultiCoin. +func (mr *MockStateDBMockRecorder) AddBalanceMultiCoin(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddBalanceMultiCoin", reflect.TypeOf((*MockStateDB)(nil).AddBalanceMultiCoin), arg0, arg1, arg2) +} + // AddLog mocks base method. -func (m *MockStateDB) AddLog(addr common.Address, topics []common.Hash, data []byte, blockNumber uint64) { +func (m *MockStateDB) AddLog(arg0 *types.Log) { m.ctrl.T.Helper() - m.ctrl.Call(m, "AddLog", addr, topics, data, blockNumber) + m.ctrl.Call(m, "AddLog", arg0) } // AddLog indicates an expected call of AddLog. -func (mr *MockStateDBMockRecorder) AddLog(addr, topics, data, blockNumber any) *gomock.Call { +func (mr *MockStateDBMockRecorder) AddLog(arg0 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLog", reflect.TypeOf((*MockStateDB)(nil).AddLog), addr, topics, data, blockNumber) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLog", reflect.TypeOf((*MockStateDB)(nil).AddLog), arg0) } // CreateAccount mocks base method. @@ -284,21 +136,6 @@ func (mr *MockStateDBMockRecorder) GetBalanceMultiCoin(arg0, arg1 any) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBalanceMultiCoin", reflect.TypeOf((*MockStateDB)(nil).GetBalanceMultiCoin), arg0, arg1) } -// GetLogData mocks base method. -func (m *MockStateDB) GetLogData() ([][]common.Hash, [][]byte) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetLogData") - ret0, _ := ret[0].([][]common.Hash) - ret1, _ := ret[1].([][]byte) - return ret0, ret1 -} - -// GetLogData indicates an expected call of GetLogData. -func (mr *MockStateDBMockRecorder) GetLogData() *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogData", reflect.TypeOf((*MockStateDB)(nil).GetLogData)) -} - // GetNonce mocks base method. func (m *MockStateDB) GetNonce(arg0 common.Address) uint64 { m.ctrl.T.Helper() @@ -356,6 +193,20 @@ func (mr *MockStateDBMockRecorder) GetTxHash() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxHash", reflect.TypeOf((*MockStateDB)(nil).GetTxHash)) } +// Logs mocks base method. +func (m *MockStateDB) Logs() []*types.Log { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Logs") + ret0, _ := ret[0].([]*types.Log) + return ret0 +} + +// Logs indicates an expected call of Logs. +func (mr *MockStateDBMockRecorder) Logs() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Logs", reflect.TypeOf((*MockStateDB)(nil).Logs)) +} + // RevertToSnapshot mocks base method. func (m *MockStateDB) RevertToSnapshot(arg0 int) { m.ctrl.T.Helper() @@ -417,3 +268,175 @@ func (mr *MockStateDBMockRecorder) Snapshot() *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Snapshot", reflect.TypeOf((*MockStateDB)(nil).Snapshot)) } + +// SubBalanceMultiCoin mocks base method. +func (m *MockStateDB) SubBalanceMultiCoin(arg0 common.Address, arg1 common.Hash, arg2 *big.Int) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SubBalanceMultiCoin", arg0, arg1, arg2) +} + +// SubBalanceMultiCoin indicates an expected call of SubBalanceMultiCoin. +func (mr *MockStateDBMockRecorder) SubBalanceMultiCoin(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SubBalanceMultiCoin", reflect.TypeOf((*MockStateDB)(nil).SubBalanceMultiCoin), arg0, arg1, arg2) +} + +// MockAccessibleState is a mock of AccessibleState interface. +type MockAccessibleState struct { + ctrl *gomock.Controller + recorder *MockAccessibleStateMockRecorder + isgomock struct{} +} + +// MockAccessibleStateMockRecorder is the mock recorder for MockAccessibleState. +type MockAccessibleStateMockRecorder struct { + mock *MockAccessibleState +} + +// NewMockAccessibleState creates a new mock instance. +func NewMockAccessibleState(ctrl *gomock.Controller) *MockAccessibleState { + mock := &MockAccessibleState{ctrl: ctrl} + mock.recorder = &MockAccessibleStateMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockAccessibleState) EXPECT() *MockAccessibleStateMockRecorder { + return m.recorder +} + +// GetBlockContext mocks base method. +func (m *MockAccessibleState) GetBlockContext() BlockContext { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetBlockContext") + ret0, _ := ret[0].(BlockContext) + return ret0 +} + +// GetBlockContext indicates an expected call of GetBlockContext. +func (mr *MockAccessibleStateMockRecorder) GetBlockContext() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBlockContext", reflect.TypeOf((*MockAccessibleState)(nil).GetBlockContext)) +} + +// GetChainConfig mocks base method. +func (m *MockAccessibleState) GetChainConfig() precompileconfig.ChainConfig { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetChainConfig") + ret0, _ := ret[0].(precompileconfig.ChainConfig) + return ret0 +} + +// GetChainConfig indicates an expected call of GetChainConfig. +func (mr *MockAccessibleStateMockRecorder) GetChainConfig() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChainConfig", reflect.TypeOf((*MockAccessibleState)(nil).GetChainConfig)) +} + +// GetPrecompileEnv mocks base method. +func (m *MockAccessibleState) GetPrecompileEnv() vm.PrecompileEnvironment { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPrecompileEnv") + ret0, _ := ret[0].(vm.PrecompileEnvironment) + return ret0 +} + +// GetPrecompileEnv indicates an expected call of GetPrecompileEnv. +func (mr *MockAccessibleStateMockRecorder) GetPrecompileEnv() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrecompileEnv", reflect.TypeOf((*MockAccessibleState)(nil).GetPrecompileEnv)) +} + +// GetSnowContext mocks base method. +func (m *MockAccessibleState) GetSnowContext() *snow.Context { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetSnowContext") + ret0, _ := ret[0].(*snow.Context) + return ret0 +} + +// GetSnowContext indicates an expected call of GetSnowContext. +func (mr *MockAccessibleStateMockRecorder) GetSnowContext() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSnowContext", reflect.TypeOf((*MockAccessibleState)(nil).GetSnowContext)) +} + +// GetStateDB mocks base method. +func (m *MockAccessibleState) GetStateDB() StateDB { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetStateDB") + ret0, _ := ret[0].(StateDB) + return ret0 +} + +// GetStateDB indicates an expected call of GetStateDB. +func (mr *MockAccessibleStateMockRecorder) GetStateDB() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStateDB", reflect.TypeOf((*MockAccessibleState)(nil).GetStateDB)) +} + +// MockBlockContext is a mock of BlockContext interface. +type MockBlockContext struct { + ctrl *gomock.Controller + recorder *MockBlockContextMockRecorder + isgomock struct{} +} + +// MockBlockContextMockRecorder is the mock recorder for MockBlockContext. +type MockBlockContextMockRecorder struct { + mock *MockBlockContext +} + +// NewMockBlockContext creates a new mock instance. +func NewMockBlockContext(ctrl *gomock.Controller) *MockBlockContext { + mock := &MockBlockContext{ctrl: ctrl} + mock.recorder = &MockBlockContextMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockBlockContext) EXPECT() *MockBlockContextMockRecorder { + return m.recorder +} + +// GetPredicateResults mocks base method. +func (m *MockBlockContext) GetPredicateResults(txHash common.Hash, precompileAddress common.Address) []byte { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetPredicateResults", txHash, precompileAddress) + ret0, _ := ret[0].([]byte) + return ret0 +} + +// GetPredicateResults indicates an expected call of GetPredicateResults. +func (mr *MockBlockContextMockRecorder) GetPredicateResults(txHash, precompileAddress any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPredicateResults", reflect.TypeOf((*MockBlockContext)(nil).GetPredicateResults), txHash, precompileAddress) +} + +// Number mocks base method. +func (m *MockBlockContext) Number() *big.Int { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Number") + ret0, _ := ret[0].(*big.Int) + return ret0 +} + +// Number indicates an expected call of Number. +func (mr *MockBlockContextMockRecorder) Number() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Number", reflect.TypeOf((*MockBlockContext)(nil).Number)) +} + +// Timestamp mocks base method. +func (m *MockBlockContext) Timestamp() uint64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Timestamp") + ret0, _ := ret[0].(uint64) + return ret0 +} + +// Timestamp indicates an expected call of Timestamp. +func (mr *MockBlockContextMockRecorder) Timestamp() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Timestamp", reflect.TypeOf((*MockBlockContext)(nil).Timestamp)) +} diff --git a/precompile/contract/mocks_generate_test.go b/precompile/contract/mocks_generate_test.go index ab422832da..dbb1f56115 100644 --- a/precompile/contract/mocks_generate_test.go +++ b/precompile/contract/mocks_generate_test.go @@ -3,4 +3,4 @@ package contract -//go:generate go run go.uber.org/mock/mockgen -package=$GOPACKAGE -destination=mocks.go . BlockContext,AccessibleState,StateDB +//go:generate go run go.uber.org/mock/mockgen -package=$GOPACKAGE -source=interfaces.go -destination=mocks.go -exclude_interfaces StatefulPrecompiledContract,StateReader,ConfigurationBlockContext,Configurator diff --git a/precompile/contract/utils.go b/precompile/contract/utils.go index 6b8ed7c832..b84f88a955 100644 --- a/precompile/contract/utils.go +++ b/precompile/contract/utils.go @@ -9,8 +9,8 @@ import ( "strings" "github.com/ava-labs/coreth/accounts/abi" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/core/vm" + "github.com/ava-labs/libevm/crypto" ) // Gas costs for stateful precompiles @@ -43,7 +43,7 @@ func CalculateFunctionSelector(functionSignature string) []byte { // DeductGas checks if [suppliedGas] is sufficient against [requiredGas] and deducts [requiredGas] from [suppliedGas]. func DeductGas(suppliedGas uint64, requiredGas uint64) (uint64, error) { if suppliedGas < requiredGas { - return 0, vmerrs.ErrOutOfGas + return 0, vm.ErrOutOfGas } return suppliedGas - requiredGas, nil } diff --git a/precompile/contracts/warp/config.go b/precompile/contracts/warp/config.go index 23b3bbdbe3..07d86c763f 100644 --- a/precompile/contracts/warp/config.go +++ b/precompile/contracts/warp/config.go @@ -13,9 +13,9 @@ import ( "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/predicate" warpValidators "github.com/ava-labs/coreth/warp/validators" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/log" ) const ( diff --git a/precompile/contracts/warp/contract.go b/precompile/contracts/warp/contract.go index 7e30f9f9eb..bfedbe10c3 100644 --- a/precompile/contracts/warp/contract.go +++ b/precompile/contracts/warp/contract.go @@ -11,12 +11,13 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" "github.com/ava-labs/coreth/accounts/abi" "github.com/ava-labs/coreth/precompile/contract" - "github.com/ava-labs/coreth/vmerrs" + "github.com/ava-labs/libevm/core/types" _ "embed" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/vm" ) const ( @@ -236,13 +237,13 @@ func sendWarpMessage(accessibleState contract.AccessibleState, caller common.Add // This ensures that we charge gas before we unpack the variable sized input. payloadGas, overflow := math.SafeMul(SendWarpMessageGasCostPerByte, uint64(len(input))) if overflow { - return nil, 0, vmerrs.ErrOutOfGas + return nil, 0, vm.ErrOutOfGas } if remainingGas, err = contract.DeductGas(remainingGas, payloadGas); err != nil { return nil, 0, err } if readOnly { - return nil, remainingGas, vmerrs.ErrWriteProtection + return nil, remainingGas, vm.ErrWriteProtection } // unpack the arguments payloadData, err := UnpackSendWarpMessageInput(input) @@ -280,12 +281,12 @@ func sendWarpMessage(accessibleState contract.AccessibleState, caller common.Add if err != nil { return nil, remainingGas, err } - accessibleState.GetStateDB().AddLog( - ContractAddress, - topics, - data, - accessibleState.GetBlockContext().Number().Uint64(), - ) + accessibleState.GetStateDB().AddLog(&types.Log{ + Address: ContractAddress, + Topics: topics, + Data: data, + BlockNumber: accessibleState.GetBlockContext().Number().Uint64(), + }) packed, err := PackSendWarpMessageOutput(common.Hash(unsignedWarpMessage.ID())) if err != nil { diff --git a/precompile/contracts/warp/contract_test.go b/precompile/contracts/warp/contract_test.go index a3bb563b3b..1a248bd05a 100644 --- a/precompile/contracts/warp/contract_test.go +++ b/precompile/contracts/warp/contract_test.go @@ -13,13 +13,13 @@ import ( "github.com/ava-labs/avalanchego/utils/set" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" - "github.com/ava-labs/coreth/core/state" + "github.com/ava-labs/coreth/core/extstate" "github.com/ava-labs/coreth/precompile/contract" "github.com/ava-labs/coreth/precompile/testutils" "github.com/ava-labs/coreth/predicate" "github.com/ava-labs/coreth/utils" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/vm" "github.com/stretchr/testify/require" ) @@ -74,11 +74,11 @@ func TestGetBlockchainID(t *testing.T) { }, SuppliedGas: GetBlockchainIDGasCost - 1, ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), + ExpectedErr: vm.ErrOutOfGas.Error(), }, } - testutils.RunPrecompileTests(t, Module, state.NewTestStateDB, tests) + testutils.RunPrecompileTests(t, Module, extstate.NewTestStateDB, tests) } func TestSendWarpMessage(t *testing.T) { @@ -108,21 +108,21 @@ func TestSendWarpMessage(t *testing.T) { InputFn: func(t testing.TB) []byte { return sendWarpMessageInput }, SuppliedGas: SendWarpMessageGasCost + uint64(len(sendWarpMessageInput[4:])*int(SendWarpMessageGasCostPerByte)), ReadOnly: true, - ExpectedErr: vmerrs.ErrWriteProtection.Error(), + ExpectedErr: vm.ErrWriteProtection.Error(), }, "send warp message insufficient gas for first step": { Caller: callerAddr, InputFn: func(t testing.TB) []byte { return sendWarpMessageInput }, SuppliedGas: SendWarpMessageGasCost - 1, ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), + ExpectedErr: vm.ErrOutOfGas.Error(), }, "send warp message insufficient gas for payload bytes": { Caller: callerAddr, InputFn: func(t testing.TB) []byte { return sendWarpMessageInput }, SuppliedGas: SendWarpMessageGasCost + uint64(len(sendWarpMessageInput[4:])*int(SendWarpMessageGasCostPerByte)) - 1, ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), + ExpectedErr: vm.ErrOutOfGas.Error(), }, "send warp message invalid input": { Caller: callerAddr, @@ -146,7 +146,12 @@ func TestSendWarpMessage(t *testing.T) { return bytes }(), AfterHook: func(t testing.TB, state contract.StateDB) { - logsTopics, logsData := state.GetLogData() + var logsTopics [][]common.Hash + var logsData [][]byte + for _, log := range state.Logs() { + logsTopics = append(logsTopics, log.Topics) + logsData = append(logsData, common.CopyBytes(log.Data)) + } require.Len(t, logsTopics, 1) topics := logsTopics[0] require.Len(t, topics, 3) @@ -168,7 +173,7 @@ func TestSendWarpMessage(t *testing.T) { }, } - testutils.RunPrecompileTests(t, Module, state.NewTestStateDB, tests) + testutils.RunPrecompileTests(t, Module, extstate.NewTestStateDB, tests) } func TestGetVerifiedWarpMessage(t *testing.T) { @@ -361,7 +366,7 @@ func TestGetVerifiedWarpMessage(t *testing.T) { }, SuppliedGas: GetVerifiedWarpMessageBaseCost - 1, ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), + ExpectedErr: vm.ErrOutOfGas.Error(), }, "get message out of gas": { Caller: callerAddr, @@ -374,7 +379,7 @@ func TestGetVerifiedWarpMessage(t *testing.T) { }, SuppliedGas: GetVerifiedWarpMessageBaseCost + GasCostPerWarpMessageBytes*uint64(len(warpMessagePredicateBytes)) - 1, ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), + ExpectedErr: vm.ErrOutOfGas.Error(), }, "get message invalid predicate packing": { Caller: callerAddr, @@ -453,7 +458,7 @@ func TestGetVerifiedWarpMessage(t *testing.T) { }, } - testutils.RunPrecompileTests(t, Module, state.NewTestStateDB, tests) + testutils.RunPrecompileTests(t, Module, extstate.NewTestStateDB, tests) } func TestGetVerifiedWarpBlockHash(t *testing.T) { @@ -639,7 +644,7 @@ func TestGetVerifiedWarpBlockHash(t *testing.T) { }, SuppliedGas: GetVerifiedWarpMessageBaseCost - 1, ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), + ExpectedErr: vm.ErrOutOfGas.Error(), }, "get message out of gas": { Caller: callerAddr, @@ -652,7 +657,7 @@ func TestGetVerifiedWarpBlockHash(t *testing.T) { }, SuppliedGas: GetVerifiedWarpMessageBaseCost + GasCostPerWarpMessageBytes*uint64(len(warpMessagePredicateBytes)) - 1, ReadOnly: false, - ExpectedErr: vmerrs.ErrOutOfGas.Error(), + ExpectedErr: vm.ErrOutOfGas.Error(), }, "get message invalid predicate packing": { Caller: callerAddr, @@ -731,7 +736,7 @@ func TestGetVerifiedWarpBlockHash(t *testing.T) { }, } - testutils.RunPrecompileTests(t, Module, state.NewTestStateDB, tests) + testutils.RunPrecompileTests(t, Module, extstate.NewTestStateDB, tests) } func TestPackEvents(t *testing.T) { diff --git a/precompile/contracts/warp/contract_warp_handler.go b/precompile/contracts/warp/contract_warp_handler.go index 71142ed084..d96f47b65a 100644 --- a/precompile/contracts/warp/contract_warp_handler.go +++ b/precompile/contracts/warp/contract_warp_handler.go @@ -11,9 +11,9 @@ import ( "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" "github.com/ava-labs/coreth/precompile/contract" "github.com/ava-labs/coreth/predicate" - "github.com/ava-labs/coreth/vmerrs" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" + "github.com/ava-labs/libevm/core/vm" ) var ( @@ -71,7 +71,7 @@ func handleWarpMessage(accessibleState contract.AccessibleState, input []byte, s // EVM execution because each execution incurs an additional read cost. msgBytesGas, overflow := math.SafeMul(GasCostPerWarpMessageBytes, uint64(len(predicateBytes))) if overflow { - return nil, 0, vmerrs.ErrOutOfGas + return nil, 0, vm.ErrOutOfGas } if remainingGas, err = contract.DeductGas(remainingGas, msgBytesGas); err != nil { return nil, 0, err diff --git a/precompile/contracts/warp/module.go b/precompile/contracts/warp/module.go index 336100da34..b333d8f7ec 100644 --- a/precompile/contracts/warp/module.go +++ b/precompile/contracts/warp/module.go @@ -10,7 +10,7 @@ import ( "github.com/ava-labs/coreth/precompile/modules" "github.com/ava-labs/coreth/precompile/precompileconfig" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) var _ contract.Configurator = &configurator{} diff --git a/precompile/modules/module.go b/precompile/modules/module.go index fefa9fd2da..a5fca0cc38 100644 --- a/precompile/modules/module.go +++ b/precompile/modules/module.go @@ -7,7 +7,7 @@ import ( "bytes" "github.com/ava-labs/coreth/precompile/contract" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) type Module struct { diff --git a/precompile/modules/registerer.go b/precompile/modules/registerer.go index a7f3b92c60..068170bd2c 100644 --- a/precompile/modules/registerer.go +++ b/precompile/modules/registerer.go @@ -9,7 +9,7 @@ import ( "github.com/ava-labs/coreth/constants" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) var ( diff --git a/precompile/modules/registerer_test.go b/precompile/modules/registerer_test.go index f2519046df..665f1aa860 100644 --- a/precompile/modules/registerer_test.go +++ b/precompile/modules/registerer_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/ava-labs/coreth/constants" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/require" ) diff --git a/precompile/precompileconfig/config.go b/precompile/precompileconfig/config.go index eb741cbc55..7dd027aadc 100644 --- a/precompile/precompileconfig/config.go +++ b/precompile/precompileconfig/config.go @@ -8,7 +8,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" "github.com/ava-labs/avalanchego/vms/platformvm/warp" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // StatefulPrecompileConfig defines the interface for a stateful precompile to diff --git a/precompile/precompileconfig/mocks.go b/precompile/precompileconfig/mocks.go index cba1ca13a3..6843eaa6b4 100644 --- a/precompile/precompileconfig/mocks.go +++ b/precompile/precompileconfig/mocks.go @@ -12,7 +12,7 @@ package precompileconfig import ( reflect "reflect" - common "github.com/ethereum/go-ethereum/common" + common "github.com/ava-labs/libevm/common" gomock "go.uber.org/mock/gomock" ) diff --git a/precompile/testutils/test_precompile.go b/precompile/testutils/test_precompile.go index a0bc279ff9..86c29c6323 100644 --- a/precompile/testutils/test_precompile.go +++ b/precompile/testutils/test_precompile.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/coreth/precompile/modules" "github.com/ava-labs/coreth/precompile/precompileconfig" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) diff --git a/predicate/predicate_bytes.go b/predicate/predicate_bytes.go index 8947741b3c..9d5766b4f3 100644 --- a/predicate/predicate_bytes.go +++ b/predicate/predicate_bytes.go @@ -6,7 +6,7 @@ package predicate import ( "fmt" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // EndByte is used as a delimiter for the bytes packed into a precompile predicate. diff --git a/predicate/predicate_results.go b/predicate/predicate_results.go index f87b181f44..2d8eeea5ca 100644 --- a/predicate/predicate_results.go +++ b/predicate/predicate_results.go @@ -11,7 +11,7 @@ import ( "github.com/ava-labs/avalanchego/codec/linearcodec" "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) const ( @@ -44,6 +44,14 @@ type Results struct { Results map[common.Hash]TxResults `serialize:"true"` } +func (r Results) GetPredicateResults(txHash common.Hash, address common.Address) []byte { + results, ok := r.Results[txHash] + if !ok { + return nil + } + return results[address] +} + // NewResults returns an empty predicate results. func NewResults() *Results { return &Results{ diff --git a/predicate/predicate_results_test.go b/predicate/predicate_results_test.go index e3daefa706..45b8efc0d6 100644 --- a/predicate/predicate_results_test.go +++ b/predicate/predicate_results_test.go @@ -6,7 +6,7 @@ package predicate import ( "testing" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/require" ) diff --git a/predicate/predicate_slots.go b/predicate/predicate_slots.go index 6eccc5bcae..6b9f0e2286 100644 --- a/predicate/predicate_slots.go +++ b/predicate/predicate_slots.go @@ -4,17 +4,20 @@ package predicate import ( - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) +type PredicaterExistChecker interface { + PredicaterExists(common.Address) bool +} + // PreparePredicateStorageSlots populates the the predicate storage slots of a transaction's access list // Note: if an address is specified multiple times in the access list, each storage slot for that address is // appended to a slice of byte slices. Each byte slice represents a predicate, making it a slice of predicates // for each access list address, and every predicate in the slice goes through verification. -func PreparePredicateStorageSlots(rules params.Rules, list types.AccessList) map[common.Address][][]byte { +func PreparePredicateStorageSlots(rules PredicaterExistChecker, list types.AccessList) map[common.Address][][]byte { predicateStorageSlots := make(map[common.Address][][]byte) for _, el := range list { if !rules.PredicaterExists(el.Address) { diff --git a/predicate/predicate_tx.go b/predicate/predicate_tx.go index 76bb3ce6bd..9f7f215e3d 100644 --- a/predicate/predicate_tx.go +++ b/predicate/predicate_tx.go @@ -6,9 +6,9 @@ package predicate import ( "math/big" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) // NewPredicateTx returns a transaction with the predicateAddress/predicateBytes tuple diff --git a/rpc/client.go b/rpc/client.go index 6c11365560..ff351485f0 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -37,7 +37,7 @@ import ( "sync/atomic" "time" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) var ( diff --git a/rpc/client_test.go b/rpc/client_test.go index 97bc69e61b..826d1eed48 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -42,8 +42,8 @@ import ( "testing" "time" + "github.com/ava-labs/libevm/log" "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/log" ) func TestClientRequest(t *testing.T) { diff --git a/rpc/handler.go b/rpc/handler.go index cabbd10cde..e589b0292a 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -38,8 +38,8 @@ import ( "sync" "time" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/log" "golang.org/x/time/rate" ) diff --git a/rpc/metrics.go b/rpc/metrics.go index a4469545d7..ee6f1f8f42 100644 --- a/rpc/metrics.go +++ b/rpc/metrics.go @@ -31,17 +31,26 @@ import ( "time" "github.com/ava-labs/libevm/metrics" + + // Force libevm metrics of the same name to be registered first. + _ "github.com/ava-labs/libevm/rpc" ) +// ====== If resolving merge conflicts ====== +// +// All calls to metrics.NewRegistered*() for metrics also defined in libevm/rpc have +// been replaced with metrics.GetOrRegister*() to get metrics already registered in +// libevm/rpc or register them here otherwise. These replacements ensure the same +// metrics are shared between the two packages. var ( - rpcRequestGauge = metrics.NewRegisteredGauge("rpc/requests", nil) - successfulRequestGauge = metrics.NewRegisteredGauge("rpc/success", nil) - failedRequestGauge = metrics.NewRegisteredGauge("rpc/failure", nil) + rpcRequestGauge = metrics.GetOrRegisterGauge("rpc/requests", nil) + successfulRequestGauge = metrics.GetOrRegisterGauge("rpc/success", nil) + failedRequestGauge = metrics.GetOrRegisterGauge("rpc/failure", nil) // serveTimeHistName is the prefix of the per-request serving time histograms. serveTimeHistName = "rpc/duration" - rpcServingTimer = metrics.NewRegisteredTimer("rpc/duration/all", nil) + rpcServingTimer = metrics.GetOrRegisterTimer("rpc/duration/all", nil) ) // updateServeTimeHistogram tracks the serving time of a remote RPC call. diff --git a/rpc/server.go b/rpc/server.go index 054bd2de92..d41ce1cc32 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -33,7 +33,7 @@ import ( "sync/atomic" "time" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) const MetadataApi = "rpc" diff --git a/rpc/service.go b/rpc/service.go index eecd70e90e..d8fe238844 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -35,7 +35,7 @@ import ( "sync" "unicode" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) var ( diff --git a/rpc/subscription_test.go b/rpc/subscription_test.go index 5e3143c9fe..712413aaf2 100644 --- a/rpc/subscription_test.go +++ b/rpc/subscription_test.go @@ -38,8 +38,11 @@ import ( "testing" "time" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + + // Side effect: registration of libevm extras. + _ "github.com/ava-labs/coreth/plugin/evm/customtypes" ) func TestNewID(t *testing.T) { diff --git a/rpc/types.go b/rpc/types.go index c96e7bc74f..38123bb430 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -34,8 +34,8 @@ import ( "math" "strings" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" ) // API describes the set of methods offered over the RPC interface diff --git a/rpc/types_test.go b/rpc/types_test.go index 779b23296f..d37632d62e 100644 --- a/rpc/types_test.go +++ b/rpc/types_test.go @@ -31,8 +31,8 @@ import ( "reflect" "testing" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/math" ) func TestBlockNumberJSONUnmarshal(t *testing.T) { diff --git a/rpc/websocket.go b/rpc/websocket.go index 1be8364955..6f545477ad 100644 --- a/rpc/websocket.go +++ b/rpc/websocket.go @@ -37,8 +37,8 @@ import ( "sync" "time" + "github.com/ava-labs/libevm/log" mapset "github.com/deckarep/golang-set/v2" - "github.com/ethereum/go-ethereum/log" "github.com/gorilla/websocket" ) diff --git a/scripts/eth-allowed-packages.txt b/scripts/eth-allowed-packages.txt new file mode 100644 index 0000000000..e8d62708db --- /dev/null +++ b/scripts/eth-allowed-packages.txt @@ -0,0 +1,41 @@ +"github.com/ava-labs/libevm/accounts" +"github.com/ava-labs/libevm/accounts/external" +"github.com/ava-labs/libevm/accounts/keystore" +"github.com/ava-labs/libevm/accounts/scwallet" +"github.com/ava-labs/libevm/common" +"github.com/ava-labs/libevm/common/bitutil" +"github.com/ava-labs/libevm/common/compiler" +"github.com/ava-labs/libevm/common/hexutil" +"github.com/ava-labs/libevm/common/lru" +"github.com/ava-labs/libevm/common/math" +"github.com/ava-labs/libevm/common/prque" +"github.com/ava-labs/libevm/core/asm" +"github.com/ava-labs/libevm/core/rawdb" +"github.com/ava-labs/libevm/core/types" +"github.com/ava-labs/libevm/core/vm" +"github.com/ava-labs/libevm/crypto" +"github.com/ava-labs/libevm/crypto/blake2b" +"github.com/ava-labs/libevm/crypto/bls12381" +"github.com/ava-labs/libevm/crypto/bn256" +"github.com/ava-labs/libevm/crypto/kzg4844" +"github.com/ava-labs/libevm/eth/tracers/js" +"github.com/ava-labs/libevm/eth/tracers/logger" +"github.com/ava-labs/libevm/eth/tracers/native" +"github.com/ava-labs/libevm/ethdb" +"github.com/ava-labs/libevm/ethdb/leveldb" +"github.com/ava-labs/libevm/ethdb/memorydb" +"github.com/ava-labs/libevm/ethdb/pebble" +"github.com/ava-labs/libevm/event" +"github.com/ava-labs/libevm/libevm" +"github.com/ava-labs/libevm/libevm/legacy" +"github.com/ava-labs/libevm/libevm/stateconf" +"github.com/ava-labs/libevm/log" +"github.com/ava-labs/libevm/metrics" +"github.com/ava-labs/libevm/rlp" +"github.com/ava-labs/libevm/trie" +"github.com/ava-labs/libevm/trie/testutil" +"github.com/ava-labs/libevm/trie/trienode" +"github.com/ava-labs/libevm/trie/triestate" +"github.com/ava-labs/libevm/trie/utils" +"github.com/ava-labs/libevm/triedb" +"github.com/ava-labs/libevm/triedb/database" \ No newline at end of file diff --git a/scripts/geth-allowed-packages.txt b/scripts/geth-allowed-packages.txt deleted file mode 100644 index e54cbd6481..0000000000 --- a/scripts/geth-allowed-packages.txt +++ /dev/null @@ -1,21 +0,0 @@ -"github.com/ethereum/go-ethereum/common" -"github.com/ethereum/go-ethereum/common/bitutil" -"github.com/ethereum/go-ethereum/common/compiler" -"github.com/ethereum/go-ethereum/common/hexutil" -"github.com/ethereum/go-ethereum/common/lru" -"github.com/ethereum/go-ethereum/common/math" -"github.com/ethereum/go-ethereum/common/prque" -"github.com/ethereum/go-ethereum/core/asm" -"github.com/ethereum/go-ethereum/crypto" -"github.com/ethereum/go-ethereum/crypto/blake2b" -"github.com/ethereum/go-ethereum/crypto/bls12381" -"github.com/ethereum/go-ethereum/crypto/bn256" -"github.com/ethereum/go-ethereum/crypto/kzg4844" -"github.com/ethereum/go-ethereum/ethdb" -"github.com/ethereum/go-ethereum/ethdb/leveldb" -"github.com/ethereum/go-ethereum/ethdb/memorydb" -"github.com/ethereum/go-ethereum/ethdb/pebble" -"github.com/ethereum/go-ethereum/event" -"github.com/ethereum/go-ethereum/log" -"github.com/ethereum/go-ethereum/metrics" -"github.com/ethereum/go-ethereum/rlp" diff --git a/scripts/lint_allowed_eth_imports.sh b/scripts/lint_allowed_eth_imports.sh new file mode 100755 index 0000000000..5e412c7fa7 --- /dev/null +++ b/scripts/lint_allowed_eth_imports.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +# Ensure that there are no eth imports that are not marked as explicitly allowed via ./scripts/eth-allowed-packages.txt +# 1. Recursively search through all go files for any lines that include a direct import from go-ethereum +# 2. Ignore lines that import libevm with a named import starting with "eth" or by _ import. +# 3. Sort the unique results. +# 4. Print out the difference between the search results and the list of specified allowed package imports from libevm. +libevm_regexp='"github.com/ava-labs/libevm/.*"' +extra_imports=$(find . -type f \( -name "*.go" \) ! -path "./core/main_test.go" ! -name "gen_*.go" -print0 | + xargs -0 grep "${libevm_regexp}" | + grep -v 'eth\w\+ "' | + grep -v '_ "' | + grep -o "${libevm_regexp}" | + sort -u | comm -23 - ./scripts/eth-allowed-packages.txt) +if [ -n "${extra_imports}" ]; then + echo "new ethereum imports should be added to ./scripts/eth-allowed-packages.txt to prevent accidental imports:" + echo "${extra_imports}" + exit 1 +fi diff --git a/scripts/lint_allowed_geth_imports.sh b/scripts/lint_allowed_geth_imports.sh deleted file mode 100755 index 6ae45f88eb..0000000000 --- a/scripts/lint_allowed_geth_imports.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -# Ensure that there are no geth imports that are not marked as explicitly allowed via ./scripts/geth-allowed-packages.txt -# 1. Recursively search through all go files for any lines that include a direct import from go-ethereum -# 2. Sort the unique results -# #. Print out the difference between the search results and the list of specified allowed package imports from geth. -extra_imports=$(find . -type f \( -name "*.go" \) ! -path "./core/main_test.go" -exec grep -o -h '"github.com/ethereum/go-ethereum/.*"' {} + | sort -u | comm -23 - ./scripts/geth-allowed-packages.txt) -if [ -n "${extra_imports}" ]; then - echo "new go-ethereum imports should be added to ./scripts/geth-allowed-packages.txt to prevent accidental imports:" - echo "${extra_imports}" - exit 1 -fi diff --git a/scripts/versions.sh b/scripts/versions.sh old mode 100644 new mode 100755 index 4f3746467a..941f442a2b --- a/scripts/versions.sh +++ b/scripts/versions.sh @@ -18,7 +18,7 @@ if [[ -z ${AVALANCHE_VERSION:-} ]]; then # If not, the value is assumed to represent a tag if [[ "${AVALANCHE_VERSION}" =~ ^v.*[0-9]{14}-[0-9a-f]{12}$ ]]; then # Extract module hash from version - MODULE_HASH="$(echo "${AVALANCHE_VERSION}" | cut -d'-' -f3)" + MODULE_HASH="$(echo "${AVALANCHE_VERSION}" | grep -Eo '[0-9a-f]{12}$')" # The first 8 chars of the hash is used as the tag of avalanchego images AVALANCHE_VERSION="${MODULE_HASH::8}" diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go index 9f85e9ce7e..325f5f72a5 100644 --- a/signer/core/apitypes/types.go +++ b/signer/core/apitypes/types.go @@ -32,9 +32,9 @@ import ( "math/big" "strings" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/core/types" ) type ValidationInfo struct { diff --git a/sync/client/client.go b/sync/client/client.go index 0aaa5c00f9..351c83ab16 100644 --- a/sync/client/client.go +++ b/sync/client/client.go @@ -19,16 +19,16 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/version" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/peer" "github.com/ava-labs/coreth/plugin/evm/message" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/trie" ) const ( diff --git a/sync/client/client_test.go b/sync/client/client_test.go index 9902c4e694..39c554a6bb 100644 --- a/sync/client/client_test.go +++ b/sync/client/client_test.go @@ -17,17 +17,17 @@ import ( "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/message" clientstats "github.com/ava-labs/coreth/sync/client/stats" "github.com/ava-labs/coreth/sync/handlers" handlerstats "github.com/ava-labs/coreth/sync/handlers/stats" "github.com/ava-labs/coreth/sync/syncutils" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/triedb" ) func TestGetCode(t *testing.T) { @@ -266,7 +266,7 @@ func TestGetBlocks(t *testing.T) { return responseBytes }, - expectedErr: "failed to unmarshal response: rlp: expected input list for types.extblock", + expectedErr: "failed to unmarshal response: rlp: expected List", }, "incorrect starting point": { request: message.BlockRequest{ @@ -381,7 +381,7 @@ func TestGetBlocks(t *testing.T) { if err == nil { t.Fatalf("Expected error: %s, but found no error", test.expectedErr) } - assert.True(t, strings.Contains(err.Error(), test.expectedErr), "expected error to contain [%s], but found [%s]", test.expectedErr, err) + assert.ErrorContains(t, err, test.expectedErr) return } if err != nil { diff --git a/sync/client/leaf_syncer.go b/sync/client/leaf_syncer.go index 2ca82b7560..db59bb305e 100644 --- a/sync/client/leaf_syncer.go +++ b/sync/client/leaf_syncer.go @@ -11,8 +11,8 @@ import ( "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" "golang.org/x/sync/errgroup" ) diff --git a/sync/client/mock_client.go b/sync/client/mock_client.go index 038bdf73bf..dbb30aab35 100644 --- a/sync/client/mock_client.go +++ b/sync/client/mock_client.go @@ -10,11 +10,11 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/sync/handlers" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" ) var ( diff --git a/sync/handlers/block_request.go b/sync/handlers/block_request.go index 2bbb21b012..1bbad650ad 100644 --- a/sync/handlers/block_request.go +++ b/sync/handlers/block_request.go @@ -14,8 +14,8 @@ import ( "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/sync/handlers/stats" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" ) const ( diff --git a/sync/handlers/block_request_test.go b/sync/handlers/block_request_test.go index 7b0124d8f9..f5f053d7ca 100644 --- a/sync/handlers/block_request_test.go +++ b/sync/handlers/block_request_test.go @@ -12,15 +12,15 @@ import ( "github.com/ava-labs/avalanchego/utils/units" "github.com/ava-labs/coreth/consensus/dummy" "github.com/ava-labs/coreth/core" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/sync/handlers/stats" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/triedb" "github.com/stretchr/testify/assert" ) diff --git a/sync/handlers/code_request.go b/sync/handlers/code_request.go index b756507f75..64dba81aba 100644 --- a/sync/handlers/code_request.go +++ b/sync/handlers/code_request.go @@ -10,12 +10,12 @@ import ( "github.com/ava-labs/avalanchego/codec" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/sync/handlers/stats" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" ) // CodeRequestHandler is a peer.RequestHandler for message.CodeRequest diff --git a/sync/handlers/code_request_test.go b/sync/handlers/code_request_test.go index 1bf5bd5223..944118b3e4 100644 --- a/sync/handlers/code_request_test.go +++ b/sync/handlers/code_request_test.go @@ -11,12 +11,12 @@ import ( "github.com/ava-labs/coreth/params" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/sync/handlers/stats" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb/memorydb" "github.com/stretchr/testify/assert" ) diff --git a/sync/handlers/handler.go b/sync/handlers/handler.go index 71bff519de..221cd8433e 100644 --- a/sync/handlers/handler.go +++ b/sync/handlers/handler.go @@ -5,8 +5,8 @@ package handlers import ( "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) type BlockProvider interface { diff --git a/sync/handlers/leafs_request.go b/sync/handlers/leafs_request.go index 4bb0fcfb61..604e046eb5 100644 --- a/sync/handlers/leafs_request.go +++ b/sync/handlers/leafs_request.go @@ -14,17 +14,17 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/wrappers" "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/sync/handlers/stats" "github.com/ava-labs/coreth/sync/syncutils" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/ethdb/memorydb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/ethdb/memorydb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" ) const ( diff --git a/sync/handlers/leafs_request_test.go b/sync/handlers/leafs_request_test.go index 1c8201fdad..39c2d1addb 100644 --- a/sync/handlers/leafs_request_test.go +++ b/sync/handlers/leafs_request_test.go @@ -10,17 +10,17 @@ import ( "testing" "github.com/ava-labs/avalanchego/ids" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/sync/handlers/stats" "github.com/ava-labs/coreth/sync/syncutils" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" "github.com/stretchr/testify/assert" ) diff --git a/sync/handlers/test_providers.go b/sync/handlers/test_providers.go index 81dafbfd00..f60da2c61f 100644 --- a/sync/handlers/test_providers.go +++ b/sync/handlers/test_providers.go @@ -5,8 +5,8 @@ package handlers import ( "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" ) var ( diff --git a/sync/statesync/code_syncer.go b/sync/statesync/code_syncer.go index 97164b2658..109a299106 100644 --- a/sync/statesync/code_syncer.go +++ b/sync/statesync/code_syncer.go @@ -11,11 +11,12 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/set" - "github.com/ava-labs/coreth/core/rawdb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/plugin/evm/message" statesyncclient "github.com/ava-labs/coreth/sync/client" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" ) const ( @@ -104,16 +105,16 @@ func (c *codeSyncer) start(ctx context.Context) { // Clean out any codeToFetch markers from the database that are no longer needed and // add any outstanding markers to the queue. func (c *codeSyncer) addCodeToFetchFromDBToQueue() error { - it := rawdb.NewCodeToFetchIterator(c.DB) + it := customrawdb.NewCodeToFetchIterator(c.DB) defer it.Release() batch := c.DB.NewBatch() codeHashes := make([]common.Hash, 0) for it.Next() { - codeHash := common.BytesToHash(it.Key()[len(rawdb.CodeToFetchPrefix):]) + codeHash := common.BytesToHash(it.Key()[len(customrawdb.CodeToFetchPrefix):]) // If we already have the codeHash, delete the marker from the database and continue if rawdb.HasCode(c.DB, codeHash) { - rawdb.DeleteCodeToFetch(batch, codeHash) + customrawdb.DeleteCodeToFetch(batch, codeHash) // Write the batch to disk if it has reached the ideal batch size. if batch.ValueSize() > ethdb.IdealBatchSize { if err := batch.Write(); err != nil { @@ -186,7 +187,7 @@ func (c *codeSyncer) fulfillCodeRequest(ctx context.Context, codeHashes []common c.lock.Lock() batch := c.DB.NewBatch() for i, codeHash := range codeHashes { - rawdb.DeleteCodeToFetch(batch, codeHash) + customrawdb.DeleteCodeToFetch(batch, codeHash) c.outstandingCodeHashes.Remove(ids.ID(codeHash)) rawdb.WriteCode(batch, codeHash, codeByteSlices[i]) } @@ -211,7 +212,7 @@ func (c *codeSyncer) addCode(codeHashes []common.Hash) error { if !c.outstandingCodeHashes.Contains(ids.ID(codeHash)) && !rawdb.HasCode(c.DB, codeHash) { selectedCodeHashes = append(selectedCodeHashes, codeHash) c.outstandingCodeHashes.Add(ids.ID(codeHash)) - rawdb.AddCodeToFetch(batch, codeHash) + customrawdb.AddCodeToFetch(batch, codeHash) } } c.lock.Unlock() diff --git a/sync/statesync/code_syncer_test.go b/sync/statesync/code_syncer_test.go index 574290e286..25368d9dfb 100644 --- a/sync/statesync/code_syncer_test.go +++ b/sync/statesync/code_syncer_test.go @@ -9,14 +9,15 @@ import ( "testing" "github.com/ava-labs/avalanchego/utils" - "github.com/ava-labs/coreth/core/rawdb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/plugin/evm/message" statesyncclient "github.com/ava-labs/coreth/sync/client" "github.com/ava-labs/coreth/sync/handlers" handlerstats "github.com/ava-labs/coreth/sync/handlers/stats" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb/memorydb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb/memorydb" "github.com/stretchr/testify/assert" ) @@ -134,7 +135,7 @@ func TestCodeSyncerAddsInProgressCodeHashes(t *testing.T) { codeHash := crypto.Keccak256Hash(codeBytes) testCodeSyncer(t, codeSyncerTest{ setupCodeSyncer: func(c *codeSyncer) { - rawdb.AddCodeToFetch(c.DB, codeHash) + customrawdb.AddCodeToFetch(c.DB, codeHash) }, codeRequestHashes: nil, codeByteSlices: [][]byte{codeBytes}, @@ -155,7 +156,7 @@ func TestCodeSyncerAddsMoreInProgressThanQueueSize(t *testing.T) { testCodeSyncer(t, codeSyncerTest{ setupCodeSyncer: func(c *codeSyncer) { for _, codeHash := range codeHashes { - rawdb.AddCodeToFetch(c.DB, codeHash) + customrawdb.AddCodeToFetch(c.DB, codeHash) } c.codeHashes = make(chan common.Hash, numCodeSlices/2) }, diff --git a/sync/statesync/state_syncer.go b/sync/statesync/state_syncer.go index ec8b138863..d2f3159e27 100644 --- a/sync/statesync/state_syncer.go +++ b/sync/statesync/state_syncer.go @@ -10,9 +10,9 @@ import ( "github.com/ava-labs/coreth/core/state/snapshot" syncclient "github.com/ava-labs/coreth/sync/client" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/triedb" "golang.org/x/sync/errgroup" ) @@ -35,12 +35,12 @@ type StateSyncerConfig struct { // stateSync keeps the state of the entire state sync operation. type stateSync struct { - db ethdb.Database // database we are syncing - root common.Hash // root of the EVM state we are syncing to - trieDB *triedb.Database // trieDB on top of db we are syncing. used to restore any existing tries. - snapshot snapshot.Snapshot // used to access the database we are syncing as a snapshot. - batchSize int // write batches when they reach this size - client syncclient.Client // used to contact peers over the network + db ethdb.Database // database we are syncing + root common.Hash // root of the EVM state we are syncing to + trieDB *triedb.Database // trieDB on top of db we are syncing. used to restore any existing tries. + snapshot snapshot.SnapshotIterable // used to access the database we are syncing as a snapshot. + batchSize int // write batches when they reach this size + client syncclient.Client // used to contact peers over the network segments chan syncclient.LeafSyncTask // channel of tasks to sync syncer *syncclient.CallbackLeafSyncer // performs the sync, looping over each task's range and invoking specified callbacks diff --git a/sync/statesync/sync_helpers.go b/sync/statesync/sync_helpers.go index a6ff02c90d..2d506cf17e 100644 --- a/sync/statesync/sync_helpers.go +++ b/sync/statesync/sync_helpers.go @@ -4,11 +4,11 @@ package statesync import ( - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/trie" ) // writeAccountSnapshot stores the account represented by [acc] to the snapshot at [accHash], using diff --git a/sync/statesync/sync_test.go b/sync/statesync/sync_test.go index 31b2518187..833e0b089e 100644 --- a/sync/statesync/sync_test.go +++ b/sync/statesync/sync_test.go @@ -13,20 +13,20 @@ import ( "testing" "time" - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/plugin/evm/message" statesyncclient "github.com/ava-labs/coreth/sync/client" "github.com/ava-labs/coreth/sync/handlers" handlerstats "github.com/ava-labs/coreth/sync/handlers/stats" "github.com/ava-labs/coreth/sync/syncutils" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/triedb" "github.com/stretchr/testify/assert" ) diff --git a/sync/statesync/test_sync.go b/sync/statesync/test_sync.go index 0a5ec45164..16655e2bb7 100644 --- a/sync/statesync/test_sync.go +++ b/sync/statesync/test_sync.go @@ -8,15 +8,16 @@ import ( "math/rand" "testing" - "github.com/ava-labs/coreth/accounts/keystore" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/sync/syncutils" - "github.com/ava-labs/coreth/triedb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/triedb" "github.com/stretchr/testify/assert" ) @@ -25,7 +26,7 @@ import ( // Also verifies any code referenced by the EVM state is present in [clientTrieDB] and the hash is correct. func assertDBConsistency(t testing.TB, root common.Hash, clientDB ethdb.Database, serverTrieDB, clientTrieDB *triedb.Database) { numSnapshotAccounts := 0 - accountIt := rawdb.IterateAccountSnapshots(clientDB) + accountIt := customrawdb.IterateAccountSnapshots(clientDB) defer accountIt.Release() for accountIt.Next() { if !bytes.HasPrefix(accountIt.Key(), rawdb.SnapshotAccountPrefix) || len(accountIt.Key()) != len(rawdb.SnapshotAccountPrefix)+common.HashLength { @@ -116,7 +117,7 @@ func fillAccountsWithStorage(t *testing.T, serverDB ethdb.Database, serverTrieDB // returns the new trie root and a map of funded keys to StateAccount structs. func FillAccountsWithOverlappingStorage( t *testing.T, trieDB *triedb.Database, root common.Hash, numAccounts int, numOverlappingStorageRoots int, -) (common.Hash, map[*keystore.Key]*types.StateAccount) { +) (common.Hash, map[*utils.Key]*types.StateAccount) { storageRoots := make([]common.Hash, 0, numOverlappingStorageRoots) for i := 0; i < numOverlappingStorageRoots; i++ { storageRoot, _, _ := syncutils.GenerateTrie(t, trieDB, 16, common.HashLength) diff --git a/sync/statesync/trie_queue.go b/sync/statesync/trie_queue.go index 3ec7c87a49..cf01e2ffd3 100644 --- a/sync/statesync/trie_queue.go +++ b/sync/statesync/trie_queue.go @@ -4,9 +4,9 @@ package statesync import ( - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/ethdb" ) // trieQueue persists storage trie roots with their associated @@ -26,21 +26,21 @@ func NewTrieQueue(db ethdb.Database) *trieQueue { // clearIfRootDoesNotMatch clears progress and segment markers if // the persisted root does not match the root we are syncing to. func (t *trieQueue) clearIfRootDoesNotMatch(root common.Hash) error { - persistedRoot, err := rawdb.ReadSyncRoot(t.db) + persistedRoot, err := customrawdb.ReadSyncRoot(t.db) if err != nil { return err } if persistedRoot != (common.Hash{}) && persistedRoot != root { // if not resuming, clear all progress markers - if err := rawdb.ClearAllSyncStorageTries(t.db); err != nil { + if err := customrawdb.ClearAllSyncStorageTries(t.db); err != nil { return err } - if err := rawdb.ClearAllSyncSegments(t.db); err != nil { + if err := customrawdb.ClearAllSyncSegments(t.db); err != nil { return err } } - return rawdb.WriteSyncRoot(t.db, root) + return customrawdb.WriteSyncRoot(t.db, root) } // RegisterStorageTrie is called by the main trie's leaf handling callbacks @@ -48,13 +48,13 @@ func (t *trieQueue) clearIfRootDoesNotMatch(root common.Hash) error { // getNextTrie iterates this prefix to find storage tries and accounts // associated with them. func (t *trieQueue) RegisterStorageTrie(root common.Hash, account common.Hash) error { - return rawdb.WriteSyncStorageTrie(t.db, root, account) + return customrawdb.WriteSyncStorageTrie(t.db, root, account) } // StorageTrieDone is called when a storage trie has completed syncing. // This removes any progress markers for the trie. func (t *trieQueue) StorageTrieDone(root common.Hash) error { - return rawdb.ClearSyncStorageTrie(t.db, root) + return customrawdb.ClearSyncStorageTrie(t.db, root) } // getNextTrie returns the next storage trie to sync, along with a slice @@ -63,7 +63,7 @@ func (t *trieQueue) StorageTrieDone(root common.Hash) error { // Note: if a non-nil root is returned, getNextTrie guarantees that there will be at least // one account hash in the returned slice. func (t *trieQueue) getNextTrie() (common.Hash, []common.Hash, bool, error) { - it := rawdb.NewSyncStorageTriesIterator(t.db, t.nextStorageRoot) + it := customrawdb.NewSyncStorageTriesIterator(t.db, t.nextStorageRoot) defer it.Release() var ( @@ -75,7 +75,7 @@ func (t *trieQueue) getNextTrie() (common.Hash, []common.Hash, bool, error) { // Iterate over the keys to find the next storage trie root and all of the account hashes that contain the same storage root. for it.Next() { // Unpack the state root and account hash from the current key - nextRoot, nextAccount := rawdb.UnpackSyncStorageTrieKey(it.Key()) + nextRoot, nextAccount := customrawdb.UnpackSyncStorageTrieKey(it.Key()) // Set the root for the first pass if root == (common.Hash{}) { root = nextRoot @@ -95,7 +95,7 @@ func (t *trieQueue) getNextTrie() (common.Hash, []common.Hash, bool, error) { } func (t *trieQueue) countTries() (int, error) { - it := rawdb.NewSyncStorageTriesIterator(t.db, nil) + it := customrawdb.NewSyncStorageTriesIterator(t.db, nil) defer it.Release() var ( @@ -104,7 +104,7 @@ func (t *trieQueue) countTries() (int, error) { ) for it.Next() { - nextRoot, _ := rawdb.UnpackSyncStorageTrieKey(it.Key()) + nextRoot, _ := customrawdb.UnpackSyncStorageTrieKey(it.Key()) if root == (common.Hash{}) || root != nextRoot { root = nextRoot tries++ diff --git a/sync/statesync/trie_segments.go b/sync/statesync/trie_segments.go index b992cd868b..0ac9b0b0aa 100644 --- a/sync/statesync/trie_segments.go +++ b/sync/statesync/trie_segments.go @@ -11,14 +11,15 @@ import ( "sync" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/coreth/core/rawdb" + "github.com/ava-labs/coreth/plugin/evm/customrawdb" "github.com/ava-labs/coreth/plugin/evm/message" syncclient "github.com/ava-labs/coreth/sync/client" - "github.com/ava-labs/coreth/trie" "github.com/ava-labs/coreth/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie" ) var ( @@ -86,7 +87,7 @@ func (t *trieToSync) loadSegments() error { // Get an iterator for segments for t.root and see if we find anything. // This lets us check if this trie was previously segmented, in which // case we need to restore the same segments on resume. - it := rawdb.NewSyncSegmentsIterator(t.sync.db, t.root) + it := customrawdb.NewSyncSegmentsIterator(t.sync.db, t.root) defer it.Release() // Track the previously added segment as we loop over persisted values. @@ -99,7 +100,7 @@ func (t *trieToSync) loadSegments() error { // key immediately prior to the segment we found on disk. // This is because we do not persist the beginning of // the first segment. - _, segmentStart := rawdb.UnpackSyncSegmentKey(it.Key()) + _, segmentStart := customrawdb.UnpackSyncSegmentKey(it.Key()) segmentStartPos := binary.BigEndian.Uint16(segmentStart[:wrappers.ShortLen]) t.addSegment(prevSegmentStart, addPadding(segmentStartPos-1, 0xff)) @@ -232,7 +233,7 @@ func (t *trieToSync) segmentFinished(ctx context.Context, idx int) error { } // remove all segments for this root from persistent storage - if err := rawdb.ClearSyncSegments(t.sync.db, t.root); err != nil { + if err := customrawdb.ClearSyncSegments(t.sync.db, t.root); err != nil { return err } return t.task.OnFinish() @@ -301,7 +302,7 @@ func (t *trieToSync) createSegments(numSegments int) error { // create the segments segment := t.addSegment(startBytes, endBytes) - if err := rawdb.WriteSyncSegment(t.sync.db, t.root, segment.start); err != nil { + if err := customrawdb.WriteSyncSegment(t.sync.db, t.root, common.BytesToHash(segment.start)); err != nil { return err } } diff --git a/sync/statesync/trie_sync_stats.go b/sync/statesync/trie_sync_stats.go index 5083b590f9..b0e80041f1 100644 --- a/sync/statesync/trie_sync_stats.go +++ b/sync/statesync/trie_sync_stats.go @@ -10,9 +10,9 @@ import ( utils_math "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/timer" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" ) const ( diff --git a/sync/statesync/trie_sync_tasks.go b/sync/statesync/trie_sync_tasks.go index 0c7cad4239..83adf5e802 100644 --- a/sync/statesync/trie_sync_tasks.go +++ b/sync/statesync/trie_sync_tasks.go @@ -6,14 +6,14 @@ package statesync import ( "fmt" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/sync/syncutils" - "github.com/ava-labs/coreth/trie" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" ) var ( diff --git a/sync/syncutils/iterators.go b/sync/syncutils/iterators.go index 2ae6bfcc80..d83c56c298 100644 --- a/sync/syncutils/iterators.go +++ b/sync/syncutils/iterators.go @@ -5,8 +5,8 @@ package syncutils import ( "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" ) var ( diff --git a/sync/syncutils/test_trie.go b/sync/syncutils/test_trie.go index b66e53e905..587d3c95e3 100644 --- a/sync/syncutils/test_trie.go +++ b/sync/syncutils/test_trie.go @@ -4,22 +4,21 @@ package syncutils import ( - cryptoRand "crypto/rand" "encoding/binary" "math/rand" "testing" "github.com/ava-labs/avalanchego/utils/wrappers" - "github.com/ava-labs/coreth/accounts/keystore" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/triedb" + "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/triedb" "github.com/holiman/uint256" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/rlp" "github.com/stretchr/testify/assert" ) @@ -147,12 +146,12 @@ func CorruptTrie(t *testing.T, diskdb ethdb.Batcher, tr *trie.Trie, n int) { func FillAccounts( t *testing.T, trieDB *triedb.Database, root common.Hash, numAccounts int, onAccount func(*testing.T, int, types.StateAccount) types.StateAccount, -) (common.Hash, map[*keystore.Key]*types.StateAccount) { +) (common.Hash, map[*utils.Key]*types.StateAccount) { var ( minBalance = uint256.NewInt(3000000000000000000) randBalance = uint256.NewInt(1000000000000000000) maxNonce = 10 - accounts = make(map[*keystore.Key]*types.StateAccount, numAccounts) + accounts = make(map[*utils.Key]*types.StateAccount, numAccounts) ) tr, err := trie.NewStateTrie(trie.TrieID(root), trieDB) @@ -176,10 +175,7 @@ func FillAccounts( t.Fatalf("failed to rlp encode account: %v", err) } - key, err := keystore.NewKey(cryptoRand.Reader) - if err != nil { - t.Fatal(err) - } + key := utils.NewKey(t) tr.MustUpdate(key.Address[:], accBytes) accounts[key] = &acc } diff --git a/tests/init.go b/tests/init.go index eb410ee388..5ec587e6d4 100644 --- a/tests/init.go +++ b/tests/init.go @@ -32,6 +32,7 @@ import ( "sort" "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/params/extras" "github.com/ava-labs/coreth/utils" ) @@ -165,186 +166,223 @@ var Forks = map[string]*params.ChainConfig{ PetersburgBlock: big.NewInt(0), IstanbulBlock: big.NewInt(5), }, - "ApricotPhase1": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), + "ApricotPhase1": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), }, - }, - "ApricotPhase2": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + }, }, - }, - "ApricotPhase3": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ), + "ApricotPhase2": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), }, - }, - "ApricotPhase4": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + }, }, - }, - "ApricotPhase5": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), + ), + "ApricotPhase3": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - }, - "Banff": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + }, }, - }, - "Cortina": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), + ), + "ApricotPhase4": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - }, - "Durango": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + }, }, - }, - "Cancun": { - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - CancunTime: utils.NewUint64(0), - NetworkUpgrades: params.NetworkUpgrades{ - ApricotPhase1BlockTimestamp: utils.NewUint64(0), - ApricotPhase2BlockTimestamp: utils.NewUint64(0), - ApricotPhase3BlockTimestamp: utils.NewUint64(0), - ApricotPhase4BlockTimestamp: utils.NewUint64(0), - ApricotPhase5BlockTimestamp: utils.NewUint64(0), - BanffBlockTimestamp: utils.NewUint64(0), - CortinaBlockTimestamp: utils.NewUint64(0), - DurangoBlockTimestamp: utils.NewUint64(0), + ), + "ApricotPhase5": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), }, - }, + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + ApricotPhase5BlockTimestamp: utils.NewUint64(0), + }, + }, + ), + "Banff": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + }, + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + ApricotPhase5BlockTimestamp: utils.NewUint64(0), + BanffBlockTimestamp: utils.NewUint64(0), + }, + }, + ), + "Cortina": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + }, + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + ApricotPhase5BlockTimestamp: utils.NewUint64(0), + BanffBlockTimestamp: utils.NewUint64(0), + CortinaBlockTimestamp: utils.NewUint64(0), + }, + }, + ), + "Durango": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + }, + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + ApricotPhase5BlockTimestamp: utils.NewUint64(0), + BanffBlockTimestamp: utils.NewUint64(0), + CortinaBlockTimestamp: utils.NewUint64(0), + DurangoBlockTimestamp: utils.NewUint64(0), + }, + }, + ), + "Cancun": params.WithExtra( + ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ShanghaiTime: utils.NewUint64(0), + CancunTime: utils.NewUint64(0), + }, + &extras.ChainConfig{ + NetworkUpgrades: extras.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + ApricotPhase3BlockTimestamp: utils.NewUint64(0), + ApricotPhase4BlockTimestamp: utils.NewUint64(0), + ApricotPhase5BlockTimestamp: utils.NewUint64(0), + BanffBlockTimestamp: utils.NewUint64(0), + CortinaBlockTimestamp: utils.NewUint64(0), + DurangoBlockTimestamp: utils.NewUint64(0), + }, + }, + ), } // AvailableForks returns the set of defined fork names diff --git a/tests/rlp_test_util.go b/tests/rlp_test_util.go index 5af235bc5a..b5df73438e 100644 --- a/tests/rlp_test_util.go +++ b/tests/rlp_test_util.go @@ -34,7 +34,7 @@ import ( "math/big" "strings" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/rlp" ) // RLPTest is the JSON structure of a single RLP test. diff --git a/tests/state_test_util.go b/tests/state_test_util.go index dc3dcb1ea4..bc6dab84f0 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -27,15 +27,15 @@ package tests import ( - "github.com/ava-labs/coreth/core/rawdb" "github.com/ava-labs/coreth/core/state" "github.com/ava-labs/coreth/core/state/snapshot" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/triedb" "github.com/ava-labs/coreth/triedb/hashdb" "github.com/ava-labs/coreth/triedb/pathdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/triedb" "github.com/holiman/uint256" ) @@ -50,9 +50,9 @@ type StateTestState struct { func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bool, scheme string) StateTestState { tconf := &triedb.Config{Preimages: true} if scheme == rawdb.HashScheme { - tconf.HashDB = hashdb.Defaults + tconf.DBOverride = hashdb.Defaults.BackendConstructor } else { - tconf.PathDB = pathdb.Defaults + tconf.DBOverride = pathdb.Defaults.BackendConstructor } triedb := triedb.NewDatabase(db, tconf) sdb := state.NewDatabaseWithNodeDB(db, triedb) diff --git a/tools.go b/tools.go index d7c65266dd..e5a287f924 100644 --- a/tools.go +++ b/tools.go @@ -1,8 +1,11 @@ // (c) 2025, Ava Labs, Inc. All rights reserved. // See the file LICENSE for licensing terms. +//go:build tools + package coreth import ( + _ "github.com/fjl/gencodec" _ "golang.org/x/tools/imports" // golang.org/x/tools to satisfy requirement for go.uber.org/mock/mockgen@v0.5 ) diff --git a/trie/committer.go b/trie/committer.go deleted file mode 100644 index 0480a8e115..0000000000 --- a/trie/committer.go +++ /dev/null @@ -1,192 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "fmt" - - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" -) - -// committer is the tool used for the trie Commit operation. The committer will -// capture all dirty nodes during the commit process and keep them cached in -// insertion order. -type committer struct { - nodes *trienode.NodeSet - tracer *tracer - collectLeaf bool -} - -// newCommitter creates a new committer or picks one from the pool. -func newCommitter(nodeset *trienode.NodeSet, tracer *tracer, collectLeaf bool) *committer { - return &committer{ - nodes: nodeset, - tracer: tracer, - collectLeaf: collectLeaf, - } -} - -// Commit collapses a node down into a hash node. -func (c *committer) Commit(n node) hashNode { - return c.commit(nil, n).(hashNode) -} - -// commit collapses a node down into a hash node and returns it. -func (c *committer) commit(path []byte, n node) node { - // if this path is clean, use available cached data - hash, dirty := n.cache() - if hash != nil && !dirty { - return hash - } - // Commit children, then parent, and remove the dirty flag. - switch cn := n.(type) { - case *shortNode: - // Commit child - collapsed := cn.copy() - - // If the child is fullNode, recursively commit, - // otherwise it can only be hashNode or valueNode. - if _, ok := cn.Val.(*fullNode); ok { - collapsed.Val = c.commit(append(path, cn.Key...), cn.Val) - } - // The key needs to be copied, since we're adding it to the - // modified nodeset. - collapsed.Key = hexToCompact(cn.Key) - hashedNode := c.store(path, collapsed) - if hn, ok := hashedNode.(hashNode); ok { - return hn - } - return collapsed - case *fullNode: - hashedKids := c.commitChildren(path, cn) - collapsed := cn.copy() - collapsed.Children = hashedKids - - hashedNode := c.store(path, collapsed) - if hn, ok := hashedNode.(hashNode); ok { - return hn - } - return collapsed - case hashNode: - return cn - default: - // nil, valuenode shouldn't be committed - panic(fmt.Sprintf("%T: invalid node: %v", n, n)) - } -} - -// commitChildren commits the children of the given fullnode -func (c *committer) commitChildren(path []byte, n *fullNode) [17]node { - var children [17]node - for i := 0; i < 16; i++ { - child := n.Children[i] - if child == nil { - continue - } - // If it's the hashed child, save the hash value directly. - // Note: it's impossible that the child in range [0, 15] - // is a valueNode. - if hn, ok := child.(hashNode); ok { - children[i] = hn - continue - } - // Commit the child recursively and store the "hashed" value. - // Note the returned node can be some embedded nodes, so it's - // possible the type is not hashNode. - children[i] = c.commit(append(path, byte(i)), child) - } - // For the 17th child, it's possible the type is valuenode. - if n.Children[16] != nil { - children[16] = n.Children[16] - } - return children -} - -// store hashes the node n and adds it to the modified nodeset. If leaf collection -// is enabled, leaf nodes will be tracked in the modified nodeset as well. -func (c *committer) store(path []byte, n node) node { - // Larger nodes are replaced by their hash and stored in the database. - var hash, _ = n.cache() - - // This was not generated - must be a small node stored in the parent. - // In theory, we should check if the node is leaf here (embedded node - // usually is leaf node). But small value (less than 32bytes) is not - // our target (leaves in account trie only). - if hash == nil { - // The node is embedded in its parent, in other words, this node - // will not be stored in the database independently, mark it as - // deleted only if the node was existent in database before. - _, ok := c.tracer.accessList[string(path)] - if ok { - c.nodes.AddNode(path, trienode.NewDeleted()) - } - return n - } - // Collect the dirty node to nodeset for return. - nhash := common.BytesToHash(hash) - c.nodes.AddNode(path, trienode.New(nhash, nodeToBytes(n))) - - // Collect the corresponding leaf node if it's required. We don't check - // full node since it's impossible to store value in fullNode. The key - // length of leaves should be exactly same. - if c.collectLeaf { - if sn, ok := n.(*shortNode); ok { - if val, ok := sn.Val.(valueNode); ok { - c.nodes.AddLeaf(nhash, val) - } - } - } - return hash -} - -// MerkleResolver the children resolver in merkle-patricia-tree. -type MerkleResolver struct{} - -// ForEach implements childResolver, decodes the provided node and -// traverses the children inside. -func (resolver MerkleResolver) ForEach(node []byte, onChild func(common.Hash)) { - forGatherChildren(mustDecodeNodeUnsafe(nil, node), onChild) -} - -// forGatherChildren traverses the node hierarchy and invokes the callback -// for all the hashnode children. -func forGatherChildren(n node, onChild func(hash common.Hash)) { - switch n := n.(type) { - case *shortNode: - forGatherChildren(n.Val, onChild) - case *fullNode: - for i := 0; i < 16; i++ { - forGatherChildren(n.Children[i], onChild) - } - case hashNode: - onChild(common.BytesToHash(n)) - case valueNode, nil: - default: - panic(fmt.Sprintf("unknown node type: %T", n)) - } -} diff --git a/trie/database_test.go b/trie/database_test.go deleted file mode 100644 index 9eb9bf6f29..0000000000 --- a/trie/database_test.go +++ /dev/null @@ -1,162 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2019 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/triedb/database" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" -) - -// testReader implements database.Reader interface, providing function to -// access trie nodes. -type testReader struct { - db ethdb.Database - scheme string - nodes []*trienode.MergedNodeSet // sorted from new to old -} - -// Node implements database.Reader interface, retrieving trie node with -// all available cached layers. -func (r *testReader) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { - // Check the node presence with the cached layer, from latest to oldest. - for _, nodes := range r.nodes { - if _, ok := nodes.Sets[owner]; !ok { - continue - } - n, ok := nodes.Sets[owner].Nodes[string(path)] - if !ok { - continue - } - if n.IsDeleted() || n.Hash != hash { - return nil, &MissingNodeError{Owner: owner, Path: path, NodeHash: hash} - } - return n.Blob, nil - } - // Check the node presence in database. - return rawdb.ReadTrieNode(r.db, owner, path, hash, r.scheme), nil -} - -// testDb implements database.Database interface, using for testing purpose. -type testDb struct { - disk ethdb.Database - root common.Hash - scheme string - nodes map[common.Hash]*trienode.MergedNodeSet - parents map[common.Hash]common.Hash -} - -func newTestDatabase(diskdb ethdb.Database, scheme string) *testDb { - return &testDb{ - disk: diskdb, - root: types.EmptyRootHash, - scheme: scheme, - nodes: make(map[common.Hash]*trienode.MergedNodeSet), - parents: make(map[common.Hash]common.Hash), - } -} - -func (db *testDb) Reader(stateRoot common.Hash) (database.Reader, error) { - nodes, _ := db.dirties(stateRoot, true) - return &testReader{db: db.disk, scheme: db.scheme, nodes: nodes}, nil -} - -func (db *testDb) Preimage(hash common.Hash) []byte { - return rawdb.ReadPreimage(db.disk, hash) -} - -func (db *testDb) InsertPreimage(preimages map[common.Hash][]byte) { - rawdb.WritePreimages(db.disk, preimages) -} - -func (db *testDb) Scheme() string { return db.scheme } - -func (db *testDb) Update(root common.Hash, parent common.Hash, nodes *trienode.MergedNodeSet) error { - if root == parent { - return nil - } - if _, ok := db.nodes[root]; ok { - return nil - } - db.parents[root] = parent - db.nodes[root] = nodes - return nil -} - -func (db *testDb) dirties(root common.Hash, topToBottom bool) ([]*trienode.MergedNodeSet, []common.Hash) { - var ( - pending []*trienode.MergedNodeSet - roots []common.Hash - ) - for { - if root == db.root { - break - } - nodes, ok := db.nodes[root] - if !ok { - break - } - if topToBottom { - pending = append(pending, nodes) - roots = append(roots, root) - } else { - pending = append([]*trienode.MergedNodeSet{nodes}, pending...) - roots = append([]common.Hash{root}, roots...) - } - root = db.parents[root] - } - return pending, roots -} - -func (db *testDb) Commit(root common.Hash) error { - if root == db.root { - return nil - } - pending, roots := db.dirties(root, false) - for i, nodes := range pending { - for owner, set := range nodes.Sets { - if owner == (common.Hash{}) { - continue - } - set.ForEachWithOrder(func(path string, n *trienode.Node) { - rawdb.WriteTrieNode(db.disk, owner, []byte(path), n.Hash, n.Blob, db.scheme) - }) - } - nodes.Sets[common.Hash{}].ForEachWithOrder(func(path string, n *trienode.Node) { - rawdb.WriteTrieNode(db.disk, common.Hash{}, []byte(path), n.Hash, n.Blob, db.scheme) - }) - db.root = roots[i] - } - for _, root := range roots { - delete(db.nodes, root) - delete(db.parents, root) - } - return nil -} diff --git a/trie/encoding.go b/trie/encoding.go deleted file mode 100644 index aaa131ef1f..0000000000 --- a/trie/encoding.go +++ /dev/null @@ -1,154 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -// Trie keys are dealt with in three distinct encodings: -// -// KEYBYTES encoding contains the actual key and nothing else. This encoding is the -// input to most API functions. -// -// HEX encoding contains one byte for each nibble of the key and an optional trailing -// 'terminator' byte of value 0x10 which indicates whether or not the node at the key -// contains a value. Hex key encoding is used for nodes loaded in memory because it's -// convenient to access. -// -// COMPACT encoding is defined by the Ethereum Yellow Paper (it's called "hex prefix -// encoding" there) and contains the bytes of the key and a flag. The high nibble of the -// first byte contains the flag; the lowest bit encoding the oddness of the length and -// the second-lowest encoding whether the node at the key is a value node. The low nibble -// of the first byte is zero in the case of an even number of nibbles and the first nibble -// in the case of an odd number. All remaining nibbles (now an even number) fit properly -// into the remaining bytes. Compact encoding is used for nodes stored on disk. - -func hexToCompact(hex []byte) []byte { - terminator := byte(0) - if hasTerm(hex) { - terminator = 1 - hex = hex[:len(hex)-1] - } - buf := make([]byte, len(hex)/2+1) - buf[0] = terminator << 5 // the flag byte - if len(hex)&1 == 1 { - buf[0] |= 1 << 4 // odd flag - buf[0] |= hex[0] // first nibble is contained in the first byte - hex = hex[1:] - } - decodeNibbles(hex, buf[1:]) - return buf -} - -// hexToCompactInPlace places the compact key in input buffer, returning the compacted key. -func hexToCompactInPlace(hex []byte) []byte { - var ( - hexLen = len(hex) // length of the hex input - firstByte = byte(0) - ) - // Check if we have a terminator there - if hexLen > 0 && hex[hexLen-1] == 16 { - firstByte = 1 << 5 - hexLen-- // last part was the terminator, ignore that - } - var ( - binLen = hexLen/2 + 1 - ni = 0 // index in hex - bi = 1 // index in bin (compact) - ) - if hexLen&1 == 1 { - firstByte |= 1 << 4 // odd flag - firstByte |= hex[0] // first nibble is contained in the first byte - ni++ - } - for ; ni < hexLen; bi, ni = bi+1, ni+2 { - hex[bi] = hex[ni]<<4 | hex[ni+1] - } - hex[0] = firstByte - return hex[:binLen] -} - -func compactToHex(compact []byte) []byte { - if len(compact) == 0 { - return compact - } - base := keybytesToHex(compact) - // delete terminator flag - if base[0] < 2 { - base = base[:len(base)-1] - } - // apply odd flag - chop := 2 - base[0]&1 - return base[chop:] -} - -func keybytesToHex(str []byte) []byte { - l := len(str)*2 + 1 - var nibbles = make([]byte, l) - for i, b := range str { - nibbles[i*2] = b / 16 - nibbles[i*2+1] = b % 16 - } - nibbles[l-1] = 16 - return nibbles -} - -// hexToKeybytes turns hex nibbles into key bytes. -// This can only be used for keys of even length. -func hexToKeybytes(hex []byte) []byte { - if hasTerm(hex) { - hex = hex[:len(hex)-1] - } - if len(hex)&1 != 0 { - panic("can't convert hex key of odd length") - } - key := make([]byte, len(hex)/2) - decodeNibbles(hex, key) - return key -} - -func decodeNibbles(nibbles []byte, bytes []byte) { - for bi, ni := 0, 0; ni < len(nibbles); bi, ni = bi+1, ni+2 { - bytes[bi] = nibbles[ni]<<4 | nibbles[ni+1] - } -} - -// prefixLen returns the length of the common prefix of a and b. -func prefixLen(a, b []byte) int { - var i, length = 0, len(a) - if len(b) < length { - length = len(b) - } - for ; i < length; i++ { - if a[i] != b[i] { - break - } - } - return i -} - -// hasTerm returns whether a hex key has the terminator flag. -func hasTerm(s []byte) bool { - return len(s) > 0 && s[len(s)-1] == 16 -} diff --git a/trie/encoding_test.go b/trie/encoding_test.go deleted file mode 100644 index e25e4ae600..0000000000 --- a/trie/encoding_test.go +++ /dev/null @@ -1,156 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - crand "crypto/rand" - "encoding/hex" - "math/rand" - "testing" -) - -func TestHexCompact(t *testing.T) { - tests := []struct{ hex, compact []byte }{ - // empty keys, with and without terminator. - {hex: []byte{}, compact: []byte{0x00}}, - {hex: []byte{16}, compact: []byte{0x20}}, - // odd length, no terminator - {hex: []byte{1, 2, 3, 4, 5}, compact: []byte{0x11, 0x23, 0x45}}, - // even length, no terminator - {hex: []byte{0, 1, 2, 3, 4, 5}, compact: []byte{0x00, 0x01, 0x23, 0x45}}, - // odd length, terminator - {hex: []byte{15, 1, 12, 11, 8, 16 /*term*/}, compact: []byte{0x3f, 0x1c, 0xb8}}, - // even length, terminator - {hex: []byte{0, 15, 1, 12, 11, 8, 16 /*term*/}, compact: []byte{0x20, 0x0f, 0x1c, 0xb8}}, - } - for _, test := range tests { - if c := hexToCompact(test.hex); !bytes.Equal(c, test.compact) { - t.Errorf("hexToCompact(%x) -> %x, want %x", test.hex, c, test.compact) - } - if h := compactToHex(test.compact); !bytes.Equal(h, test.hex) { - t.Errorf("compactToHex(%x) -> %x, want %x", test.compact, h, test.hex) - } - } -} - -func TestHexKeybytes(t *testing.T) { - tests := []struct{ key, hexIn, hexOut []byte }{ - {key: []byte{}, hexIn: []byte{16}, hexOut: []byte{16}}, - {key: []byte{}, hexIn: []byte{}, hexOut: []byte{16}}, - { - key: []byte{0x12, 0x34, 0x56}, - hexIn: []byte{1, 2, 3, 4, 5, 6, 16}, - hexOut: []byte{1, 2, 3, 4, 5, 6, 16}, - }, - { - key: []byte{0x12, 0x34, 0x5}, - hexIn: []byte{1, 2, 3, 4, 0, 5, 16}, - hexOut: []byte{1, 2, 3, 4, 0, 5, 16}, - }, - { - key: []byte{0x12, 0x34, 0x56}, - hexIn: []byte{1, 2, 3, 4, 5, 6}, - hexOut: []byte{1, 2, 3, 4, 5, 6, 16}, - }, - } - for _, test := range tests { - if h := keybytesToHex(test.key); !bytes.Equal(h, test.hexOut) { - t.Errorf("keybytesToHex(%x) -> %x, want %x", test.key, h, test.hexOut) - } - if k := hexToKeybytes(test.hexIn); !bytes.Equal(k, test.key) { - t.Errorf("hexToKeybytes(%x) -> %x, want %x", test.hexIn, k, test.key) - } - } -} - -func TestHexToCompactInPlace(t *testing.T) { - for i, key := range []string{ - "00", - "060a040c0f000a090b040803010801010900080d090a0a0d0903000b10", - "10", - } { - hexBytes, _ := hex.DecodeString(key) - exp := hexToCompact(hexBytes) - got := hexToCompactInPlace(hexBytes) - if !bytes.Equal(exp, got) { - t.Fatalf("test %d: encoding err\ninp %v\ngot %x\nexp %x\n", i, key, got, exp) - } - } -} - -func TestHexToCompactInPlaceRandom(t *testing.T) { - for i := 0; i < 10000; i++ { - l := rand.Intn(128) - key := make([]byte, l) - crand.Read(key) - hexBytes := keybytesToHex(key) - hexOrig := []byte(string(hexBytes)) - exp := hexToCompact(hexBytes) - got := hexToCompactInPlace(hexBytes) - - if !bytes.Equal(exp, got) { - t.Fatalf("encoding err \ncpt %x\nhex %x\ngot %x\nexp %x\n", - key, hexOrig, got, exp) - } - } -} - -func BenchmarkHexToCompact(b *testing.B) { - testBytes := []byte{0, 15, 1, 12, 11, 8, 16 /*term*/} - for i := 0; i < b.N; i++ { - hexToCompact(testBytes) - } -} - -func BenchmarkHexToCompactInPlace(b *testing.B) { - testBytes := []byte{0, 15, 1, 12, 11, 8, 16 /*term*/} - for i := 0; i < b.N; i++ { - hexToCompactInPlace(testBytes) - } -} - -func BenchmarkCompactToHex(b *testing.B) { - testBytes := []byte{0, 15, 1, 12, 11, 8, 16 /*term*/} - for i := 0; i < b.N; i++ { - compactToHex(testBytes) - } -} - -func BenchmarkKeybytesToHex(b *testing.B) { - testBytes := []byte{7, 6, 6, 5, 7, 2, 6, 2, 16} - for i := 0; i < b.N; i++ { - keybytesToHex(testBytes) - } -} - -func BenchmarkHexToKeybytes(b *testing.B) { - testBytes := []byte{7, 6, 6, 5, 7, 2, 6, 2, 16} - for i := 0; i < b.N; i++ { - hexToKeybytes(testBytes) - } -} diff --git a/trie/errors.go b/trie/errors.go deleted file mode 100644 index 307a5f8747..0000000000 --- a/trie/errors.go +++ /dev/null @@ -1,62 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "errors" - "fmt" - - "github.com/ethereum/go-ethereum/common" -) - -// ErrCommitted is returned when a already committed trie is requested for usage. -// The potential usages can be `Get`, `Update`, `Delete`, `NodeIterator`, `Prove` -// and so on. -var ErrCommitted = errors.New("trie is already committed") - -// MissingNodeError is returned by the trie functions (Get, Update, Delete) -// in the case where a trie node is not present in the local database. It contains -// information necessary for retrieving the missing node. -type MissingNodeError struct { - Owner common.Hash // owner of the trie if it's 2-layered trie - NodeHash common.Hash // hash of the missing node - Path []byte // hex-encoded path to the missing node - err error // concrete error for missing trie node -} - -// Unwrap returns the concrete error for missing trie node which -// allows us for further analysis outside. -func (err *MissingNodeError) Unwrap() error { - return err.err -} - -func (err *MissingNodeError) Error() string { - if err.Owner == (common.Hash{}) { - return fmt.Sprintf("missing trie node %x (path %x) %v", err.NodeHash, err.Path, err.err) - } - return fmt.Sprintf("missing trie node %x (owner %x) (path %x) %v", err.NodeHash, err.Owner, err.Path, err.err) -} diff --git a/trie/hasher.go b/trie/hasher.go deleted file mode 100644 index d281547e11..0000000000 --- a/trie/hasher.go +++ /dev/null @@ -1,218 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "sync" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -// hasher is a type used for the trie Hash operation. A hasher has some -// internal preallocated temp space -type hasher struct { - sha crypto.KeccakState - tmp []byte - encbuf rlp.EncoderBuffer - parallel bool // Whether to use parallel threads when hashing -} - -// hasherPool holds pureHashers -var hasherPool = sync.Pool{ - New: func() interface{} { - return &hasher{ - tmp: make([]byte, 0, 550), // cap is as large as a full fullNode. - sha: sha3.NewLegacyKeccak256().(crypto.KeccakState), - encbuf: rlp.NewEncoderBuffer(nil), - } - }, -} - -func newHasher(parallel bool) *hasher { - h := hasherPool.Get().(*hasher) - h.parallel = parallel - return h -} - -func returnHasherToPool(h *hasher) { - hasherPool.Put(h) -} - -// hash collapses a node down into a hash node, also returning a copy of the -// original node initialized with the computed hash to replace the original one. -func (h *hasher) hash(n node, force bool) (hashed node, cached node) { - // Return the cached hash if it's available - if hash, _ := n.cache(); hash != nil { - return hash, n - } - // Trie not processed yet, walk the children - switch n := n.(type) { - case *shortNode: - collapsed, cached := h.hashShortNodeChildren(n) - hashed := h.shortnodeToHash(collapsed, force) - // We need to retain the possibly _not_ hashed node, in case it was too - // small to be hashed - if hn, ok := hashed.(hashNode); ok { - cached.flags.hash = hn - } else { - cached.flags.hash = nil - } - return hashed, cached - case *fullNode: - collapsed, cached := h.hashFullNodeChildren(n) - hashed = h.fullnodeToHash(collapsed, force) - if hn, ok := hashed.(hashNode); ok { - cached.flags.hash = hn - } else { - cached.flags.hash = nil - } - return hashed, cached - default: - // Value and hash nodes don't have children, so they're left as were - return n, n - } -} - -// hashShortNodeChildren collapses the short node. The returned collapsed node -// holds a live reference to the Key, and must not be modified. -func (h *hasher) hashShortNodeChildren(n *shortNode) (collapsed, cached *shortNode) { - // Hash the short node's child, caching the newly hashed subtree - collapsed, cached = n.copy(), n.copy() - // Previously, we did copy this one. We don't seem to need to actually - // do that, since we don't overwrite/reuse keys - // cached.Key = common.CopyBytes(n.Key) - collapsed.Key = hexToCompact(n.Key) - // Unless the child is a valuenode or hashnode, hash it - switch n.Val.(type) { - case *fullNode, *shortNode: - collapsed.Val, cached.Val = h.hash(n.Val, false) - } - return collapsed, cached -} - -func (h *hasher) hashFullNodeChildren(n *fullNode) (collapsed *fullNode, cached *fullNode) { - // Hash the full node's children, caching the newly hashed subtrees - cached = n.copy() - collapsed = n.copy() - if h.parallel { - var wg sync.WaitGroup - wg.Add(16) - for i := 0; i < 16; i++ { - go func(i int) { - hasher := newHasher(false) - if child := n.Children[i]; child != nil { - collapsed.Children[i], cached.Children[i] = hasher.hash(child, false) - } else { - collapsed.Children[i] = nilValueNode - } - returnHasherToPool(hasher) - wg.Done() - }(i) - } - wg.Wait() - } else { - for i := 0; i < 16; i++ { - if child := n.Children[i]; child != nil { - collapsed.Children[i], cached.Children[i] = h.hash(child, false) - } else { - collapsed.Children[i] = nilValueNode - } - } - } - return collapsed, cached -} - -// shortnodeToHash creates a hashNode from a shortNode. The supplied shortnode -// should have hex-type Key, which will be converted (without modification) -// into compact form for RLP encoding. -// If the rlp data is smaller than 32 bytes, `nil` is returned. -func (h *hasher) shortnodeToHash(n *shortNode, force bool) node { - n.encode(h.encbuf) - enc := h.encodedBytes() - - if len(enc) < 32 && !force { - return n // Nodes smaller than 32 bytes are stored inside their parent - } - return h.hashData(enc) -} - -// fullnodeToHash is used to create a hashNode from a fullNode, (which -// may contain nil values) -func (h *hasher) fullnodeToHash(n *fullNode, force bool) node { - n.encode(h.encbuf) - enc := h.encodedBytes() - - if len(enc) < 32 && !force { - return n // Nodes smaller than 32 bytes are stored inside their parent - } - return h.hashData(enc) -} - -// encodedBytes returns the result of the last encoding operation on h.encbuf. -// This also resets the encoder buffer. -// -// All node encoding must be done like this: -// -// node.encode(h.encbuf) -// enc := h.encodedBytes() -// -// This convention exists because node.encode can only be inlined/escape-analyzed when -// called on a concrete receiver type. -func (h *hasher) encodedBytes() []byte { - h.tmp = h.encbuf.AppendToBytes(h.tmp[:0]) - h.encbuf.Reset(nil) - return h.tmp -} - -// hashData hashes the provided data -func (h *hasher) hashData(data []byte) hashNode { - n := make(hashNode, 32) - h.sha.Reset() - h.sha.Write(data) - h.sha.Read(n) - return n -} - -// proofHash is used to construct trie proofs, and returns the 'collapsed' -// node (for later RLP encoding) as well as the hashed node -- unless the -// node is smaller than 32 bytes, in which case it will be returned as is. -// This method does not do anything on value- or hash-nodes. -func (h *hasher) proofHash(original node) (collapsed, hashed node) { - switch n := original.(type) { - case *shortNode: - sn, _ := h.hashShortNodeChildren(n) - return sn, h.shortnodeToHash(sn, false) - case *fullNode: - fn, _ := h.hashFullNodeChildren(n) - return fn, h.fullnodeToHash(fn, false) - default: - // Value and hash nodes don't have children, so they're left as were - return n, n - } -} diff --git a/trie/iterator.go b/trie/iterator.go deleted file mode 100644 index d590b66b24..0000000000 --- a/trie/iterator.go +++ /dev/null @@ -1,801 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "container/heap" - "errors" - - "github.com/ava-labs/coreth/core/types" - "github.com/ethereum/go-ethereum/common" -) - -// NodeResolver is used for looking up trie nodes before reaching into the real -// persistent layer. This is not mandatory, rather is an optimization for cases -// where trie nodes can be recovered from some external mechanism without reading -// from disk. In those cases, this resolver allows short circuiting accesses and -// returning them from memory. -type NodeResolver func(owner common.Hash, path []byte, hash common.Hash) []byte - -// Iterator is a key-value trie iterator that traverses a Trie. -type Iterator struct { - nodeIt NodeIterator - - Key []byte // Current data key on which the iterator is positioned on - Value []byte // Current data value on which the iterator is positioned on - Err error -} - -// NewIterator creates a new key-value iterator from a node iterator. -// Note that the value returned by the iterator is raw. If the content is encoded -// (e.g. storage value is RLP-encoded), it's caller's duty to decode it. -func NewIterator(it NodeIterator) *Iterator { - return &Iterator{ - nodeIt: it, - } -} - -// Next moves the iterator forward one key-value entry. -func (it *Iterator) Next() bool { - for it.nodeIt.Next(true) { - if it.nodeIt.Leaf() { - it.Key = it.nodeIt.LeafKey() - it.Value = it.nodeIt.LeafBlob() - return true - } - } - it.Key = nil - it.Value = nil - it.Err = it.nodeIt.Error() - return false -} - -// Prove generates the Merkle proof for the leaf node the iterator is currently -// positioned on. -func (it *Iterator) Prove() [][]byte { - return it.nodeIt.LeafProof() -} - -// NodeIterator is an iterator to traverse the trie pre-order. -type NodeIterator interface { - // Next moves the iterator to the next node. If the parameter is false, any child - // nodes will be skipped. - Next(bool) bool - - // Error returns the error status of the iterator. - Error() error - - // Hash returns the hash of the current node. - Hash() common.Hash - - // Parent returns the hash of the parent of the current node. The hash may be the one - // grandparent if the immediate parent is an internal node with no hash. - Parent() common.Hash - - // Path returns the hex-encoded path to the current node. - // Callers must not retain references to the return value after calling Next. - // For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. - Path() []byte - - // NodeBlob returns the rlp-encoded value of the current iterated node. - // If the node is an embedded node in its parent, nil is returned then. - NodeBlob() []byte - - // Leaf returns true iff the current node is a leaf node. - Leaf() bool - - // LeafKey returns the key of the leaf. The method panics if the iterator is not - // positioned at a leaf. Callers must not retain references to the value after - // calling Next. - LeafKey() []byte - - // LeafBlob returns the content of the leaf. The method panics if the iterator - // is not positioned at a leaf. Callers must not retain references to the value - // after calling Next. - LeafBlob() []byte - - // LeafProof returns the Merkle proof of the leaf. The method panics if the - // iterator is not positioned at a leaf. Callers must not retain references - // to the value after calling Next. - LeafProof() [][]byte - - // AddResolver sets a node resolver to use for looking up trie nodes before - // reaching into the real persistent layer. - // - // This is not required for normal operation, rather is an optimization for - // cases where trie nodes can be recovered from some external mechanism without - // reading from disk. In those cases, this resolver allows short circuiting - // accesses and returning them from memory. - // - // Before adding a similar mechanism to any other place in Geth, consider - // making trie.Database an interface and wrapping at that level. It's a huge - // refactor, but it could be worth it if another occurrence arises. - AddResolver(NodeResolver) -} - -// nodeIteratorState represents the iteration state at one particular node of the -// trie, which can be resumed at a later invocation. -type nodeIteratorState struct { - hash common.Hash // Hash of the node being iterated (nil if not standalone) - node node // Trie node being iterated - parent common.Hash // Hash of the first full ancestor node (nil if current is the root) - index int // Child to be processed next - pathlen int // Length of the path to this node -} - -type nodeIterator struct { - trie *Trie // Trie being iterated - stack []*nodeIteratorState // Hierarchy of trie nodes persisting the iteration state - path []byte // Path to the current node - err error // Failure set in case of an internal error in the iterator - - resolver NodeResolver // optional node resolver for avoiding disk hits - pool []*nodeIteratorState // local pool for iteratorstates -} - -// errIteratorEnd is stored in nodeIterator.err when iteration is done. -var errIteratorEnd = errors.New("end of iteration") - -// seekError is stored in nodeIterator.err if the initial seek has failed. -type seekError struct { - key []byte - err error -} - -func (e seekError) Error() string { - return "seek error: " + e.err.Error() -} - -func newNodeIterator(trie *Trie, start []byte) NodeIterator { - if trie.Hash() == types.EmptyRootHash { - return &nodeIterator{ - trie: trie, - err: errIteratorEnd, - } - } - it := &nodeIterator{trie: trie} - it.err = it.seek(start) - return it -} - -func (it *nodeIterator) putInPool(item *nodeIteratorState) { - if len(it.pool) < 40 { - item.node = nil - it.pool = append(it.pool, item) - } -} - -func (it *nodeIterator) getFromPool() *nodeIteratorState { - idx := len(it.pool) - 1 - if idx < 0 { - return new(nodeIteratorState) - } - el := it.pool[idx] - it.pool[idx] = nil - it.pool = it.pool[:idx] - return el -} - -func (it *nodeIterator) AddResolver(resolver NodeResolver) { - it.resolver = resolver -} - -func (it *nodeIterator) Hash() common.Hash { - if len(it.stack) == 0 { - return common.Hash{} - } - return it.stack[len(it.stack)-1].hash -} - -func (it *nodeIterator) Parent() common.Hash { - if len(it.stack) == 0 { - return common.Hash{} - } - return it.stack[len(it.stack)-1].parent -} - -func (it *nodeIterator) Leaf() bool { - return hasTerm(it.path) -} - -func (it *nodeIterator) LeafKey() []byte { - if len(it.stack) > 0 { - if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { - return hexToKeybytes(it.path) - } - } - panic("not at leaf") -} - -func (it *nodeIterator) LeafBlob() []byte { - if len(it.stack) > 0 { - if node, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { - return node - } - } - panic("not at leaf") -} - -func (it *nodeIterator) LeafProof() [][]byte { - if len(it.stack) > 0 { - if _, ok := it.stack[len(it.stack)-1].node.(valueNode); ok { - hasher := newHasher(false) - defer returnHasherToPool(hasher) - proofs := make([][]byte, 0, len(it.stack)) - - for i, item := range it.stack[:len(it.stack)-1] { - // Gather nodes that end up as hash nodes (or the root) - node, hashed := hasher.proofHash(item.node) - if _, ok := hashed.(hashNode); ok || i == 0 { - proofs = append(proofs, nodeToBytes(node)) - } - } - return proofs - } - } - panic("not at leaf") -} - -func (it *nodeIterator) Path() []byte { - return it.path -} - -func (it *nodeIterator) NodeBlob() []byte { - if it.Hash() == (common.Hash{}) { - return nil // skip the non-standalone node - } - blob, err := it.resolveBlob(it.Hash().Bytes(), it.Path()) - if err != nil { - it.err = err - return nil - } - return blob -} - -func (it *nodeIterator) Error() error { - if it.err == errIteratorEnd { - return nil - } - if seek, ok := it.err.(seekError); ok { - return seek.err - } - return it.err -} - -// Next moves the iterator to the next node, returning whether there are any -// further nodes. In case of an internal error this method returns false and -// sets the Error field to the encountered failure. If `descend` is false, -// skips iterating over any subnodes of the current node. -func (it *nodeIterator) Next(descend bool) bool { - if it.err == errIteratorEnd { - return false - } - if seek, ok := it.err.(seekError); ok { - if it.err = it.seek(seek.key); it.err != nil { - return false - } - } - // Otherwise step forward with the iterator and report any errors. - state, parentIndex, path, err := it.peek(descend) - it.err = err - if it.err != nil { - return false - } - it.push(state, parentIndex, path) - return true -} - -func (it *nodeIterator) seek(prefix []byte) error { - // The path we're looking for is the hex encoded key without terminator. - key := keybytesToHex(prefix) - key = key[:len(key)-1] - // Move forward until we're just before the closest match to key. - for { - state, parentIndex, path, err := it.peekSeek(key) - if err == errIteratorEnd { - return errIteratorEnd - } else if err != nil { - return seekError{prefix, err} - } else if bytes.Compare(path, key) >= 0 { - return nil - } - it.push(state, parentIndex, path) - } -} - -// init initializes the iterator. -func (it *nodeIterator) init() (*nodeIteratorState, error) { - root := it.trie.Hash() - state := &nodeIteratorState{node: it.trie.root, index: -1} - if root != types.EmptyRootHash { - state.hash = root - } - return state, state.resolve(it, nil) -} - -// peek creates the next state of the iterator. -func (it *nodeIterator) peek(descend bool) (*nodeIteratorState, *int, []byte, error) { - // Initialize the iterator if we've just started. - if len(it.stack) == 0 { - state, err := it.init() - return state, nil, nil, err - } - if !descend { - // If we're skipping children, pop the current node first - it.pop() - } - - // Continue iteration to the next child - for len(it.stack) > 0 { - parent := it.stack[len(it.stack)-1] - ancestor := parent.hash - if (ancestor == common.Hash{}) { - ancestor = parent.parent - } - state, path, ok := it.nextChild(parent, ancestor) - if ok { - if err := state.resolve(it, path); err != nil { - return parent, &parent.index, path, err - } - return state, &parent.index, path, nil - } - // No more child nodes, move back up. - it.pop() - } - return nil, nil, nil, errIteratorEnd -} - -// peekSeek is like peek, but it also tries to skip resolving hashes by skipping -// over the siblings that do not lead towards the desired seek position. -func (it *nodeIterator) peekSeek(seekKey []byte) (*nodeIteratorState, *int, []byte, error) { - // Initialize the iterator if we've just started. - if len(it.stack) == 0 { - state, err := it.init() - return state, nil, nil, err - } - if !bytes.HasPrefix(seekKey, it.path) { - // If we're skipping children, pop the current node first - it.pop() - } - - // Continue iteration to the next child - for len(it.stack) > 0 { - parent := it.stack[len(it.stack)-1] - ancestor := parent.hash - if (ancestor == common.Hash{}) { - ancestor = parent.parent - } - state, path, ok := it.nextChildAt(parent, ancestor, seekKey) - if ok { - if err := state.resolve(it, path); err != nil { - return parent, &parent.index, path, err - } - return state, &parent.index, path, nil - } - // No more child nodes, move back up. - it.pop() - } - return nil, nil, nil, errIteratorEnd -} - -func (it *nodeIterator) resolveHash(hash hashNode, path []byte) (node, error) { - if it.resolver != nil { - if blob := it.resolver(it.trie.owner, path, common.BytesToHash(hash)); len(blob) > 0 { - if resolved, err := decodeNode(hash, blob); err == nil { - return resolved, nil - } - } - } - // Retrieve the specified node from the underlying node reader. - // it.trie.resolveAndTrack is not used since in that function the - // loaded blob will be tracked, while it's not required here since - // all loaded nodes won't be linked to trie at all and track nodes - // may lead to out-of-memory issue. - blob, err := it.trie.reader.node(path, common.BytesToHash(hash)) - if err != nil { - return nil, err - } - // The raw-blob format nodes are loaded either from the - // clean cache or the database, they are all in their own - // copy and safe to use unsafe decoder. - return mustDecodeNodeUnsafe(hash, blob), nil -} - -func (it *nodeIterator) resolveBlob(hash hashNode, path []byte) ([]byte, error) { - if it.resolver != nil { - if blob := it.resolver(it.trie.owner, path, common.BytesToHash(hash)); len(blob) > 0 { - return blob, nil - } - } - // Retrieve the specified node from the underlying node reader. - // it.trie.resolveAndTrack is not used since in that function the - // loaded blob will be tracked, while it's not required here since - // all loaded nodes won't be linked to trie at all and track nodes - // may lead to out-of-memory issue. - return it.trie.reader.node(path, common.BytesToHash(hash)) -} - -func (st *nodeIteratorState) resolve(it *nodeIterator, path []byte) error { - if hash, ok := st.node.(hashNode); ok { - resolved, err := it.resolveHash(hash, path) - if err != nil { - return err - } - st.node = resolved - st.hash = common.BytesToHash(hash) - } - return nil -} - -func (it *nodeIterator) findChild(n *fullNode, index int, ancestor common.Hash) (node, *nodeIteratorState, []byte, int) { - var ( - path = it.path - child node - state *nodeIteratorState - childPath []byte - ) - for ; index < len(n.Children); index++ { - if n.Children[index] != nil { - child = n.Children[index] - hash, _ := child.cache() - state = it.getFromPool() - state.hash = common.BytesToHash(hash) - state.node = child - state.parent = ancestor - state.index = -1 - state.pathlen = len(path) - childPath = append(childPath, path...) - childPath = append(childPath, byte(index)) - return child, state, childPath, index - } - } - return nil, nil, nil, 0 -} - -func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { - switch node := parent.node.(type) { - case *fullNode: - // Full node, move to the first non-nil child. - if child, state, path, index := it.findChild(node, parent.index+1, ancestor); child != nil { - parent.index = index - 1 - return state, path, true - } - case *shortNode: - // Short node, return the pointer singleton child - if parent.index < 0 { - hash, _ := node.Val.cache() - state := it.getFromPool() - state.hash = common.BytesToHash(hash) - state.node = node.Val - state.parent = ancestor - state.index = -1 - state.pathlen = len(it.path) - path := append(it.path, node.Key...) - return state, path, true - } - } - return parent, it.path, false -} - -// nextChildAt is similar to nextChild, except that it targets a child as close to the -// target key as possible, thus skipping siblings. -func (it *nodeIterator) nextChildAt(parent *nodeIteratorState, ancestor common.Hash, key []byte) (*nodeIteratorState, []byte, bool) { - switch n := parent.node.(type) { - case *fullNode: - // Full node, move to the first non-nil child before the desired key position - child, state, path, index := it.findChild(n, parent.index+1, ancestor) - if child == nil { - // No more children in this fullnode - return parent, it.path, false - } - // If the child we found is already past the seek position, just return it. - if bytes.Compare(path, key) >= 0 { - parent.index = index - 1 - return state, path, true - } - // The child is before the seek position. Try advancing - for { - nextChild, nextState, nextPath, nextIndex := it.findChild(n, index+1, ancestor) - // If we run out of children, or skipped past the target, return the - // previous one - if nextChild == nil || bytes.Compare(nextPath, key) >= 0 { - parent.index = index - 1 - return state, path, true - } - // We found a better child closer to the target - state, path, index = nextState, nextPath, nextIndex - } - case *shortNode: - // Short node, return the pointer singleton child - if parent.index < 0 { - hash, _ := n.Val.cache() - state := it.getFromPool() - state.hash = common.BytesToHash(hash) - state.node = n.Val - state.parent = ancestor - state.index = -1 - state.pathlen = len(it.path) - path := append(it.path, n.Key...) - return state, path, true - } - } - return parent, it.path, false -} - -func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path []byte) { - it.path = path - it.stack = append(it.stack, state) - if parentIndex != nil { - *parentIndex++ - } -} - -func (it *nodeIterator) pop() { - last := it.stack[len(it.stack)-1] - it.path = it.path[:last.pathlen] - it.stack[len(it.stack)-1] = nil - it.stack = it.stack[:len(it.stack)-1] - // last is now unused - it.putInPool(last) -} - -func compareNodes(a, b NodeIterator) int { - if cmp := bytes.Compare(a.Path(), b.Path()); cmp != 0 { - return cmp - } - if a.Leaf() && !b.Leaf() { - return -1 - } else if b.Leaf() && !a.Leaf() { - return 1 - } - if cmp := bytes.Compare(a.Hash().Bytes(), b.Hash().Bytes()); cmp != 0 { - return cmp - } - if a.Leaf() && b.Leaf() { - return bytes.Compare(a.LeafBlob(), b.LeafBlob()) - } - return 0 -} - -type differenceIterator struct { - a, b NodeIterator // Nodes returned are those in b - a. - eof bool // Indicates a has run out of elements - count int // Number of nodes scanned on either trie -} - -// NewDifferenceIterator constructs a NodeIterator that iterates over elements in b that -// are not in a. Returns the iterator, and a pointer to an integer recording the number -// of nodes seen. -func NewDifferenceIterator(a, b NodeIterator) (NodeIterator, *int) { - a.Next(true) - it := &differenceIterator{ - a: a, - b: b, - } - return it, &it.count -} - -func (it *differenceIterator) Hash() common.Hash { - return it.b.Hash() -} - -func (it *differenceIterator) Parent() common.Hash { - return it.b.Parent() -} - -func (it *differenceIterator) Leaf() bool { - return it.b.Leaf() -} - -func (it *differenceIterator) LeafKey() []byte { - return it.b.LeafKey() -} - -func (it *differenceIterator) LeafBlob() []byte { - return it.b.LeafBlob() -} - -func (it *differenceIterator) LeafProof() [][]byte { - return it.b.LeafProof() -} - -func (it *differenceIterator) Path() []byte { - return it.b.Path() -} - -func (it *differenceIterator) NodeBlob() []byte { - return it.b.NodeBlob() -} - -func (it *differenceIterator) AddResolver(resolver NodeResolver) { - panic("not implemented") -} - -func (it *differenceIterator) Next(bool) bool { - // Invariants: - // - We always advance at least one element in b. - // - At the start of this function, a's path is lexically greater than b's. - if !it.b.Next(true) { - return false - } - it.count++ - - if it.eof { - // a has reached eof, so we just return all elements from b - return true - } - - for { - switch compareNodes(it.a, it.b) { - case -1: - // b jumped past a; advance a - if !it.a.Next(true) { - it.eof = true - return true - } - it.count++ - case 1: - // b is before a - return true - case 0: - // a and b are identical; skip this whole subtree if the nodes have hashes - hasHash := it.a.Hash() == common.Hash{} - if !it.b.Next(hasHash) { - return false - } - it.count++ - if !it.a.Next(hasHash) { - it.eof = true - return true - } - it.count++ - } - } -} - -func (it *differenceIterator) Error() error { - if err := it.a.Error(); err != nil { - return err - } - return it.b.Error() -} - -type nodeIteratorHeap []NodeIterator - -func (h nodeIteratorHeap) Len() int { return len(h) } -func (h nodeIteratorHeap) Less(i, j int) bool { return compareNodes(h[i], h[j]) < 0 } -func (h nodeIteratorHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } -func (h *nodeIteratorHeap) Push(x interface{}) { *h = append(*h, x.(NodeIterator)) } -func (h *nodeIteratorHeap) Pop() interface{} { - n := len(*h) - x := (*h)[n-1] - *h = (*h)[0 : n-1] - return x -} - -type unionIterator struct { - items *nodeIteratorHeap // Nodes returned are the union of the ones in these iterators - count int // Number of nodes scanned across all tries -} - -// NewUnionIterator constructs a NodeIterator that iterates over elements in the union -// of the provided NodeIterators. Returns the iterator, and a pointer to an integer -// recording the number of nodes visited. -func NewUnionIterator(iters []NodeIterator) (NodeIterator, *int) { - h := make(nodeIteratorHeap, len(iters)) - copy(h, iters) - heap.Init(&h) - - ui := &unionIterator{items: &h} - return ui, &ui.count -} - -func (it *unionIterator) Hash() common.Hash { - return (*it.items)[0].Hash() -} - -func (it *unionIterator) Parent() common.Hash { - return (*it.items)[0].Parent() -} - -func (it *unionIterator) Leaf() bool { - return (*it.items)[0].Leaf() -} - -func (it *unionIterator) LeafKey() []byte { - return (*it.items)[0].LeafKey() -} - -func (it *unionIterator) LeafBlob() []byte { - return (*it.items)[0].LeafBlob() -} - -func (it *unionIterator) LeafProof() [][]byte { - return (*it.items)[0].LeafProof() -} - -func (it *unionIterator) Path() []byte { - return (*it.items)[0].Path() -} - -func (it *unionIterator) NodeBlob() []byte { - return (*it.items)[0].NodeBlob() -} - -func (it *unionIterator) AddResolver(resolver NodeResolver) { - panic("not implemented") -} - -// Next returns the next node in the union of tries being iterated over. -// -// It does this by maintaining a heap of iterators, sorted by the iteration -// order of their next elements, with one entry for each source trie. Each -// time Next() is called, it takes the least element from the heap to return, -// advancing any other iterators that also point to that same element. These -// iterators are called with descend=false, since we know that any nodes under -// these nodes will also be duplicates, found in the currently selected iterator. -// Whenever an iterator is advanced, it is pushed back into the heap if it still -// has elements remaining. -// -// In the case that descend=false - eg, we're asked to ignore all subnodes of the -// current node - we also advance any iterators in the heap that have the current -// path as a prefix. -func (it *unionIterator) Next(descend bool) bool { - if len(*it.items) == 0 { - return false - } - - // Get the next key from the union - least := heap.Pop(it.items).(NodeIterator) - - // Skip over other nodes as long as they're identical, or, if we're not descending, as - // long as they have the same prefix as the current node. - for len(*it.items) > 0 && ((!descend && bytes.HasPrefix((*it.items)[0].Path(), least.Path())) || compareNodes(least, (*it.items)[0]) == 0) { - skipped := heap.Pop(it.items).(NodeIterator) - // Skip the whole subtree if the nodes have hashes; otherwise just skip this node - if skipped.Next(skipped.Hash() == common.Hash{}) { - it.count++ - // If there are more elements, push the iterator back on the heap - heap.Push(it.items, skipped) - } - } - if least.Next(descend) { - it.count++ - heap.Push(it.items, least) - } - return len(*it.items) > 0 -} - -func (it *unionIterator) Error() error { - for i := 0; i < len(*it.items); i++ { - if err := (*it.items)[i].Error(); err != nil { - return err - } - } - return nil -} diff --git a/trie/iterator_test.go b/trie/iterator_test.go deleted file mode 100644 index 966f689c2a..0000000000 --- a/trie/iterator_test.go +++ /dev/null @@ -1,641 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "fmt" - "math/rand" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -func TestEmptyIterator(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - iter := trie.MustNodeIterator(nil) - - seen := make(map[string]struct{}) - for iter.Next(true) { - seen[string(iter.Path())] = struct{}{} - } - if len(seen) != 0 { - t.Fatal("Unexpected trie node iterated") - } -} - -func TestIterator(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie := NewEmpty(db) - vals := []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - {"shaman", "horse"}, - {"doge", "coin"}, - {"dog", "puppy"}, - {"somethingveryoddindeedthis is", "myothernodedata"}, - } - all := make(map[string]string) - for _, val := range vals { - all[val.k] = val.v - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - - trie, _ = New(TrieID(root), db) - found := make(map[string]string) - it := NewIterator(trie.MustNodeIterator(nil)) - for it.Next() { - found[string(it.Key)] = string(it.Value) - } - - for k, v := range all { - if found[k] != v { - t.Errorf("iterator value mismatch for %s: got %q want %q", k, found[k], v) - } - } -} - -type kv struct { - k, v []byte - t bool -} - -func (k *kv) cmp(other *kv) int { - return bytes.Compare(k.k, other.k) -} - -func TestIteratorLargeData(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - vals := make(map[string]*kv) - - for i := byte(0); i < 255; i++ { - value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} - value2 := &kv{common.LeftPadBytes([]byte{10, i}, 32), []byte{i}, false} - trie.MustUpdate(value.k, value.v) - trie.MustUpdate(value2.k, value2.v) - vals[string(value.k)] = value - vals[string(value2.k)] = value2 - } - - it := NewIterator(trie.MustNodeIterator(nil)) - for it.Next() { - vals[string(it.Key)].t = true - } - - var untouched []*kv - for _, value := range vals { - if !value.t { - untouched = append(untouched, value) - } - } - - if len(untouched) > 0 { - t.Errorf("Missed %d nodes", len(untouched)) - for _, value := range untouched { - t.Error(value) - } - } -} - -type iterationElement struct { - hash common.Hash - path []byte - blob []byte -} - -// Tests that the node iterator indeed walks over the entire database contents. -func TestNodeIteratorCoverage(t *testing.T) { - testNodeIteratorCoverage(t, rawdb.HashScheme) - testNodeIteratorCoverage(t, rawdb.PathScheme) -} - -func testNodeIteratorCoverage(t *testing.T, scheme string) { - // Create some arbitrary test trie to iterate - db, nodeDb, trie, _ := makeTestTrie(scheme) - - // Gather all the node hashes found by the iterator - var elements = make(map[common.Hash]iterationElement) - for it := trie.MustNodeIterator(nil); it.Next(true); { - if it.Hash() != (common.Hash{}) { - elements[it.Hash()] = iterationElement{ - hash: it.Hash(), - path: common.CopyBytes(it.Path()), - blob: common.CopyBytes(it.NodeBlob()), - } - } - } - // Cross check the hashes and the database itself - reader, err := nodeDb.Reader(trie.Hash()) - if err != nil { - t.Fatalf("state is not available %x", trie.Hash()) - } - for _, element := range elements { - if blob, err := reader.Node(common.Hash{}, element.path, element.hash); err != nil { - t.Errorf("failed to retrieve reported node %x: %v", element.hash, err) - } else if !bytes.Equal(blob, element.blob) { - t.Errorf("node blob is different, want %v got %v", element.blob, blob) - } - } - var ( - count int - it = db.NewIterator(nil, nil) - ) - for it.Next() { - res, _, _ := isTrieNode(nodeDb.Scheme(), it.Key(), it.Value()) - if !res { - continue - } - count += 1 - if elem, ok := elements[crypto.Keccak256Hash(it.Value())]; !ok { - t.Error("state entry not reported") - } else if !bytes.Equal(it.Value(), elem.blob) { - t.Errorf("node blob is different, want %v got %v", elem.blob, it.Value()) - } - } - it.Release() - if count != len(elements) { - t.Errorf("state entry is mismatched %d %d", count, len(elements)) - } -} - -type kvs struct{ k, v string } - -var testdata1 = []kvs{ - {"barb", "ba"}, - {"bard", "bc"}, - {"bars", "bb"}, - {"bar", "b"}, - {"fab", "z"}, - {"food", "ab"}, - {"foos", "aa"}, - {"foo", "a"}, -} - -var testdata2 = []kvs{ - {"aardvark", "c"}, - {"bar", "b"}, - {"barb", "bd"}, - {"bars", "be"}, - {"fab", "z"}, - {"foo", "a"}, - {"foos", "aa"}, - {"food", "ab"}, - {"jars", "d"}, -} - -func TestIteratorSeek(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - for _, val := range testdata1 { - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - - // Seek to the middle. - it := NewIterator(trie.MustNodeIterator([]byte("fab"))) - if err := checkIteratorOrder(testdata1[4:], it); err != nil { - t.Fatal(err) - } - - // Seek to a non-existent key. - it = NewIterator(trie.MustNodeIterator([]byte("barc"))) - if err := checkIteratorOrder(testdata1[1:], it); err != nil { - t.Fatal(err) - } - - // Seek beyond the end. - it = NewIterator(trie.MustNodeIterator([]byte("z"))) - if err := checkIteratorOrder(nil, it); err != nil { - t.Fatal(err) - } -} - -func checkIteratorOrder(want []kvs, it *Iterator) error { - for it.Next() { - if len(want) == 0 { - return fmt.Errorf("didn't expect any more values, got key %q", it.Key) - } - if !bytes.Equal(it.Key, []byte(want[0].k)) { - return fmt.Errorf("wrong key: got %q, want %q", it.Key, want[0].k) - } - want = want[1:] - } - if len(want) > 0 { - return fmt.Errorf("iterator ended early, want key %q", want[0]) - } - return nil -} - -func TestDifferenceIterator(t *testing.T) { - dba := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - triea := NewEmpty(dba) - for _, val := range testdata1 { - triea.MustUpdate([]byte(val.k), []byte(val.v)) - } - rootA, nodesA, _ := triea.Commit(false) - dba.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)) - triea, _ = New(TrieID(rootA), dba) - - dbb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trieb := NewEmpty(dbb) - for _, val := range testdata2 { - trieb.MustUpdate([]byte(val.k), []byte(val.v)) - } - rootB, nodesB, _ := trieb.Commit(false) - dbb.Update(rootB, types.EmptyRootHash, trienode.NewWithNodeSet(nodesB)) - trieb, _ = New(TrieID(rootB), dbb) - - found := make(map[string]string) - di, _ := NewDifferenceIterator(triea.MustNodeIterator(nil), trieb.MustNodeIterator(nil)) - it := NewIterator(di) - for it.Next() { - found[string(it.Key)] = string(it.Value) - } - - all := []struct{ k, v string }{ - {"aardvark", "c"}, - {"barb", "bd"}, - {"bars", "be"}, - {"jars", "d"}, - } - for _, item := range all { - if found[item.k] != item.v { - t.Errorf("iterator value mismatch for %s: got %v want %v", item.k, found[item.k], item.v) - } - } - if len(found) != len(all) { - t.Errorf("iterator count mismatch: got %d values, want %d", len(found), len(all)) - } -} - -func TestUnionIterator(t *testing.T) { - dba := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - triea := NewEmpty(dba) - for _, val := range testdata1 { - triea.MustUpdate([]byte(val.k), []byte(val.v)) - } - rootA, nodesA, _ := triea.Commit(false) - dba.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)) - triea, _ = New(TrieID(rootA), dba) - - dbb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trieb := NewEmpty(dbb) - for _, val := range testdata2 { - trieb.MustUpdate([]byte(val.k), []byte(val.v)) - } - rootB, nodesB, _ := trieb.Commit(false) - dbb.Update(rootB, types.EmptyRootHash, trienode.NewWithNodeSet(nodesB)) - trieb, _ = New(TrieID(rootB), dbb) - - di, _ := NewUnionIterator([]NodeIterator{triea.MustNodeIterator(nil), trieb.MustNodeIterator(nil)}) - it := NewIterator(di) - - all := []struct{ k, v string }{ - {"aardvark", "c"}, - {"barb", "ba"}, - {"barb", "bd"}, - {"bard", "bc"}, - {"bars", "bb"}, - {"bars", "be"}, - {"bar", "b"}, - {"fab", "z"}, - {"food", "ab"}, - {"foos", "aa"}, - {"foo", "a"}, - {"jars", "d"}, - } - - for i, kv := range all { - if !it.Next() { - t.Errorf("Iterator ends prematurely at element %d", i) - } - if kv.k != string(it.Key) { - t.Errorf("iterator value mismatch for element %d: got key %s want %s", i, it.Key, kv.k) - } - if kv.v != string(it.Value) { - t.Errorf("iterator value mismatch for element %d: got value %s want %s", i, it.Value, kv.v) - } - } - if it.Next() { - t.Errorf("Iterator returned extra values.") - } -} - -func TestIteratorNoDups(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - tr := NewEmpty(db) - for _, val := range testdata1 { - tr.MustUpdate([]byte(val.k), []byte(val.v)) - } - checkIteratorNoDups(t, tr.MustNodeIterator(nil), nil) -} - -// This test checks that nodeIterator.Next can be retried after inserting missing trie nodes. -func TestIteratorContinueAfterError(t *testing.T) { - testIteratorContinueAfterError(t, false, rawdb.HashScheme) - testIteratorContinueAfterError(t, true, rawdb.HashScheme) - testIteratorContinueAfterError(t, false, rawdb.PathScheme) - testIteratorContinueAfterError(t, true, rawdb.PathScheme) -} - -func testIteratorContinueAfterError(t *testing.T, memonly bool, scheme string) { - diskdb := rawdb.NewMemoryDatabase() - tdb := newTestDatabase(diskdb, scheme) - - tr := NewEmpty(tdb) - for _, val := range testdata1 { - tr.MustUpdate([]byte(val.k), []byte(val.v)) - } - root, nodes, _ := tr.Commit(false) - tdb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - if !memonly { - tdb.Commit(root) - } - tr, _ = New(TrieID(root), tdb) - wantNodeCount := checkIteratorNoDups(t, tr.MustNodeIterator(nil), nil) - - var ( - paths [][]byte - hashes []common.Hash - ) - if memonly { - for path, n := range nodes.Nodes { - paths = append(paths, []byte(path)) - hashes = append(hashes, n.Hash) - } - } else { - it := diskdb.NewIterator(nil, nil) - for it.Next() { - ok, path, hash := isTrieNode(tdb.Scheme(), it.Key(), it.Value()) - if !ok { - continue - } - paths = append(paths, path) - hashes = append(hashes, hash) - } - it.Release() - } - for i := 0; i < 20; i++ { - // Create trie that will load all nodes from DB. - tr, _ := New(TrieID(tr.Hash()), tdb) - - // Remove a random node from the database. It can't be the root node - // because that one is already loaded. - var ( - rval []byte - rpath []byte - rhash common.Hash - ) - for { - if memonly { - rpath = paths[rand.Intn(len(paths))] - n := nodes.Nodes[string(rpath)] - if n == nil { - continue - } - rhash = n.Hash - } else { - index := rand.Intn(len(paths)) - rpath = paths[index] - rhash = hashes[index] - } - if rhash != tr.Hash() { - break - } - } - if memonly { - tr.reader.banned = map[string]struct{}{string(rpath): {}} - } else { - rval = rawdb.ReadTrieNode(diskdb, common.Hash{}, rpath, rhash, tdb.Scheme()) - rawdb.DeleteTrieNode(diskdb, common.Hash{}, rpath, rhash, tdb.Scheme()) - } - // Iterate until the error is hit. - seen := make(map[string]bool) - it := tr.MustNodeIterator(nil) - checkIteratorNoDups(t, it, seen) - missing, ok := it.Error().(*MissingNodeError) - if !ok || missing.NodeHash != rhash { - t.Fatal("didn't hit missing node, got", it.Error()) - } - - // Add the node back and continue iteration. - if memonly { - delete(tr.reader.banned, string(rpath)) - } else { - rawdb.WriteTrieNode(diskdb, common.Hash{}, rpath, rhash, rval, tdb.Scheme()) - } - checkIteratorNoDups(t, it, seen) - if it.Error() != nil { - t.Fatal("unexpected error", it.Error()) - } - if len(seen) != wantNodeCount { - t.Fatal("wrong node iteration count, got", len(seen), "want", wantNodeCount) - } - } -} - -// Similar to the test above, this one checks that failure to create nodeIterator at a -// certain key prefix behaves correctly when Next is called. The expectation is that Next -// should retry seeking before returning true for the first time. -func TestIteratorContinueAfterSeekError(t *testing.T) { - testIteratorContinueAfterSeekError(t, false, rawdb.HashScheme) - testIteratorContinueAfterSeekError(t, true, rawdb.HashScheme) - testIteratorContinueAfterSeekError(t, false, rawdb.PathScheme) - testIteratorContinueAfterSeekError(t, true, rawdb.PathScheme) -} - -func testIteratorContinueAfterSeekError(t *testing.T, memonly bool, scheme string) { - // Commit test trie to db, then remove the node containing "bars". - var ( - barNodePath []byte - barNodeHash = common.HexToHash("05041990364eb72fcb1127652ce40d8bab765f2bfe53225b1170d276cc101c2e") - ) - diskdb := rawdb.NewMemoryDatabase() - triedb := newTestDatabase(diskdb, scheme) - ctr := NewEmpty(triedb) - for _, val := range testdata1 { - ctr.MustUpdate([]byte(val.k), []byte(val.v)) - } - root, nodes, _ := ctr.Commit(false) - for path, n := range nodes.Nodes { - if n.Hash == barNodeHash { - barNodePath = []byte(path) - break - } - } - triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - if !memonly { - triedb.Commit(root) - } - var ( - barNodeBlob []byte - ) - tr, _ := New(TrieID(root), triedb) - if memonly { - tr.reader.banned = map[string]struct{}{string(barNodePath): {}} - } else { - barNodeBlob = rawdb.ReadTrieNode(diskdb, common.Hash{}, barNodePath, barNodeHash, triedb.Scheme()) - rawdb.DeleteTrieNode(diskdb, common.Hash{}, barNodePath, barNodeHash, triedb.Scheme()) - } - // Create a new iterator that seeks to "bars". Seeking can't proceed because - // the node is missing. - it := tr.MustNodeIterator([]byte("bars")) - missing, ok := it.Error().(*MissingNodeError) - if !ok { - t.Fatal("want MissingNodeError, got", it.Error()) - } else if missing.NodeHash != barNodeHash { - t.Fatal("wrong node missing") - } - // Reinsert the missing node. - if memonly { - delete(tr.reader.banned, string(barNodePath)) - } else { - rawdb.WriteTrieNode(diskdb, common.Hash{}, barNodePath, barNodeHash, barNodeBlob, triedb.Scheme()) - } - // Check that iteration produces the right set of values. - if err := checkIteratorOrder(testdata1[2:], NewIterator(it)); err != nil { - t.Fatal(err) - } -} - -func checkIteratorNoDups(t *testing.T, it NodeIterator, seen map[string]bool) int { - if seen == nil { - seen = make(map[string]bool) - } - for it.Next(true) { - if seen[string(it.Path())] { - t.Fatalf("iterator visited node path %x twice", it.Path()) - } - seen[string(it.Path())] = true - } - return len(seen) -} - -func TestIteratorNodeBlob(t *testing.T) { - testIteratorNodeBlob(t, rawdb.HashScheme) - testIteratorNodeBlob(t, rawdb.PathScheme) -} - -func testIteratorNodeBlob(t *testing.T, scheme string) { - var ( - db = rawdb.NewMemoryDatabase() - triedb = newTestDatabase(db, scheme) - trie = NewEmpty(triedb) - ) - vals := []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - {"shaman", "horse"}, - {"doge", "coin"}, - {"dog", "puppy"}, - {"somethingveryoddindeedthis is", "myothernodedata"}, - } - all := make(map[string]string) - for _, val := range vals { - all[val.k] = val.v - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - root, nodes, _ := trie.Commit(false) - triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - triedb.Commit(root) - - var found = make(map[common.Hash][]byte) - trie, _ = New(TrieID(root), triedb) - it := trie.MustNodeIterator(nil) - for it.Next(true) { - if it.Hash() == (common.Hash{}) { - continue - } - found[it.Hash()] = it.NodeBlob() - } - - dbIter := db.NewIterator(nil, nil) - defer dbIter.Release() - - var count int - for dbIter.Next() { - ok, _, _ := isTrieNode(triedb.Scheme(), dbIter.Key(), dbIter.Value()) - if !ok { - continue - } - got, present := found[crypto.Keccak256Hash(dbIter.Value())] - if !present { - t.Fatal("Miss trie node") - } - if !bytes.Equal(got, dbIter.Value()) { - t.Fatalf("Unexpected trie node want %v got %v", dbIter.Value(), got) - } - count += 1 - } - if count != len(found) { - t.Fatal("Find extra trie node via iterator") - } -} - -// isTrieNode is a helper function which reports if the provided -// database entry belongs to a trie node or not. Note in tests -// only single layer trie is used, namely storage trie is not -// considered at all. -func isTrieNode(scheme string, key, val []byte) (bool, []byte, common.Hash) { - var ( - path []byte - hash common.Hash - ) - if scheme == rawdb.HashScheme { - ok := rawdb.IsLegacyTrieNode(key, val) - if !ok { - return false, nil, common.Hash{} - } - hash = common.BytesToHash(key) - } else { - ok, remain := rawdb.ResolveAccountTrieNodeKey(key) - if !ok { - return false, nil, common.Hash{} - } - path = common.CopyBytes(remain) - hash = crypto.Keccak256Hash(val) - } - return true, path, hash -} - -func BenchmarkIterator(b *testing.B) { - diskDb, srcDb, tr, _ := makeTestTrie(rawdb.HashScheme) - root := tr.Hash() - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - if err := checkTrieConsistency(diskDb, srcDb.Scheme(), root, false); err != nil { - b.Fatal(err) - } - } -} diff --git a/trie/node.go b/trie/node.go deleted file mode 100644 index 8a8bc3ad1a..0000000000 --- a/trie/node.go +++ /dev/null @@ -1,264 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "fmt" - "io" - "strings" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" -) - -var indices = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "[17]"} - -type node interface { - cache() (hashNode, bool) - encode(w rlp.EncoderBuffer) - fstring(string) string -} - -type ( - fullNode struct { - Children [17]node // Actual trie node data to encode/decode (needs custom encoder) - flags nodeFlag - } - shortNode struct { - Key []byte - Val node - flags nodeFlag - } - hashNode []byte - valueNode []byte -) - -// nilValueNode is used when collapsing internal trie nodes for hashing, since -// unset children need to serialize correctly. -var nilValueNode = valueNode(nil) - -// EncodeRLP encodes a full node into the consensus RLP format. -func (n *fullNode) EncodeRLP(w io.Writer) error { - eb := rlp.NewEncoderBuffer(w) - n.encode(eb) - return eb.Flush() -} - -func (n *fullNode) copy() *fullNode { copy := *n; return © } -func (n *shortNode) copy() *shortNode { copy := *n; return © } - -// nodeFlag contains caching-related metadata about a node. -type nodeFlag struct { - hash hashNode // cached hash of the node (may be nil) - dirty bool // whether the node has changes that must be written to the database -} - -func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } -func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty } -func (n hashNode) cache() (hashNode, bool) { return nil, true } -func (n valueNode) cache() (hashNode, bool) { return nil, true } - -// Pretty printing. -func (n *fullNode) String() string { return n.fstring("") } -func (n *shortNode) String() string { return n.fstring("") } -func (n hashNode) String() string { return n.fstring("") } -func (n valueNode) String() string { return n.fstring("") } - -func (n *fullNode) fstring(ind string) string { - resp := fmt.Sprintf("[\n%s ", ind) - for i, node := range &n.Children { - if node == nil { - resp += fmt.Sprintf("%s: ", indices[i]) - } else { - resp += fmt.Sprintf("%s: %v", indices[i], node.fstring(ind+" ")) - } - } - return resp + fmt.Sprintf("\n%s] ", ind) -} -func (n *shortNode) fstring(ind string) string { - return fmt.Sprintf("{%x: %v} ", n.Key, n.Val.fstring(ind+" ")) -} -func (n hashNode) fstring(ind string) string { - return fmt.Sprintf("<%x> ", []byte(n)) -} -func (n valueNode) fstring(ind string) string { - return fmt.Sprintf("%x ", []byte(n)) -} - -// rawNode is a simple binary blob used to differentiate between collapsed trie -// nodes and already encoded RLP binary blobs (while at the same time store them -// in the same cache fields). -type rawNode []byte - -func (n rawNode) cache() (hashNode, bool) { panic("this should never end up in a live trie") } -func (n rawNode) fstring(ind string) string { panic("this should never end up in a live trie") } - -func (n rawNode) EncodeRLP(w io.Writer) error { - _, err := w.Write(n) - return err -} - -// mustDecodeNode is a wrapper of decodeNode and panic if any error is encountered. -func mustDecodeNode(hash, buf []byte) node { - n, err := decodeNode(hash, buf) - if err != nil { - panic(fmt.Sprintf("node %x: %v", hash, err)) - } - return n -} - -// mustDecodeNodeUnsafe is a wrapper of decodeNodeUnsafe and panic if any error is -// encountered. -func mustDecodeNodeUnsafe(hash, buf []byte) node { - n, err := decodeNodeUnsafe(hash, buf) - if err != nil { - panic(fmt.Sprintf("node %x: %v", hash, err)) - } - return n -} - -// decodeNode parses the RLP encoding of a trie node. It will deep-copy the passed -// byte slice for decoding, so it's safe to modify the byte slice afterwards. The- -// decode performance of this function is not optimal, but it is suitable for most -// scenarios with low performance requirements and hard to determine whether the -// byte slice be modified or not. -func decodeNode(hash, buf []byte) (node, error) { - return decodeNodeUnsafe(hash, common.CopyBytes(buf)) -} - -// decodeNodeUnsafe parses the RLP encoding of a trie node. The passed byte slice -// will be directly referenced by node without bytes deep copy, so the input MUST -// not be changed after. -func decodeNodeUnsafe(hash, buf []byte) (node, error) { - if len(buf) == 0 { - return nil, io.ErrUnexpectedEOF - } - elems, _, err := rlp.SplitList(buf) - if err != nil { - return nil, fmt.Errorf("decode error: %v", err) - } - switch c, _ := rlp.CountValues(elems); c { - case 2: - n, err := decodeShort(hash, elems) - return n, wrapError(err, "short") - case 17: - n, err := decodeFull(hash, elems) - return n, wrapError(err, "full") - default: - return nil, fmt.Errorf("invalid number of list elements: %v", c) - } -} - -func decodeShort(hash, elems []byte) (node, error) { - kbuf, rest, err := rlp.SplitString(elems) - if err != nil { - return nil, err - } - flag := nodeFlag{hash: hash} - key := compactToHex(kbuf) - if hasTerm(key) { - // value node - val, _, err := rlp.SplitString(rest) - if err != nil { - return nil, fmt.Errorf("invalid value node: %v", err) - } - return &shortNode{key, valueNode(val), flag}, nil - } - r, _, err := decodeRef(rest) - if err != nil { - return nil, wrapError(err, "val") - } - return &shortNode{key, r, flag}, nil -} - -func decodeFull(hash, elems []byte) (*fullNode, error) { - n := &fullNode{flags: nodeFlag{hash: hash}} - for i := 0; i < 16; i++ { - cld, rest, err := decodeRef(elems) - if err != nil { - return n, wrapError(err, fmt.Sprintf("[%d]", i)) - } - n.Children[i], elems = cld, rest - } - val, _, err := rlp.SplitString(elems) - if err != nil { - return n, err - } - if len(val) > 0 { - n.Children[16] = valueNode(val) - } - return n, nil -} - -const hashLen = len(common.Hash{}) - -func decodeRef(buf []byte) (node, []byte, error) { - kind, val, rest, err := rlp.Split(buf) - if err != nil { - return nil, buf, err - } - switch { - case kind == rlp.List: - // 'embedded' node reference. The encoding must be smaller - // than a hash in order to be valid. - if size := len(buf) - len(rest); size > hashLen { - err := fmt.Errorf("oversized embedded node (size is %d bytes, want size < %d)", size, hashLen) - return nil, buf, err - } - n, err := decodeNode(nil, buf) - return n, rest, err - case kind == rlp.String && len(val) == 0: - // empty node - return nil, rest, nil - case kind == rlp.String && len(val) == 32: - return hashNode(val), rest, nil - default: - return nil, nil, fmt.Errorf("invalid RLP string size %d (want 0 or 32)", len(val)) - } -} - -// wraps a decoding error with information about the path to the -// invalid child node (for debugging encoding issues). -type decodeError struct { - what error - stack []string -} - -func wrapError(err error, ctx string) error { - if err == nil { - return nil - } - if decErr, ok := err.(*decodeError); ok { - decErr.stack = append(decErr.stack, ctx) - return decErr - } - return &decodeError{err, []string{ctx}} -} - -func (err *decodeError) Error() string { - return fmt.Sprintf("%v (decode path: %s)", err.what, strings.Join(err.stack, "<-")) -} diff --git a/trie/node_enc.go b/trie/node_enc.go deleted file mode 100644 index dc053e1070..0000000000 --- a/trie/node_enc.go +++ /dev/null @@ -1,74 +0,0 @@ -// (c) 2022, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "github.com/ethereum/go-ethereum/rlp" -) - -func nodeToBytes(n node) []byte { - w := rlp.NewEncoderBuffer(nil) - n.encode(w) - result := w.ToBytes() - w.Flush() - return result -} - -func (n *fullNode) encode(w rlp.EncoderBuffer) { - offset := w.List() - for _, c := range n.Children { - if c != nil { - c.encode(w) - } else { - w.Write(rlp.EmptyString) - } - } - w.ListEnd(offset) -} - -func (n *shortNode) encode(w rlp.EncoderBuffer) { - offset := w.List() - w.WriteBytes(n.Key) - if n.Val != nil { - n.Val.encode(w) - } else { - w.Write(rlp.EmptyString) - } - w.ListEnd(offset) -} - -func (n hashNode) encode(w rlp.EncoderBuffer) { - w.WriteBytes(n) -} - -func (n valueNode) encode(w rlp.EncoderBuffer) { - w.WriteBytes(n) -} - -func (n rawNode) encode(w rlp.EncoderBuffer) { - w.Write(n) -} diff --git a/trie/node_test.go b/trie/node_test.go deleted file mode 100644 index 4671b798de..0000000000 --- a/trie/node_test.go +++ /dev/null @@ -1,225 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "testing" - - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" -) - -func newTestFullNode(v []byte) []interface{} { - fullNodeData := []interface{}{} - for i := 0; i < 16; i++ { - k := bytes.Repeat([]byte{byte(i + 1)}, 32) - fullNodeData = append(fullNodeData, k) - } - fullNodeData = append(fullNodeData, v) - return fullNodeData -} - -func TestDecodeNestedNode(t *testing.T) { - fullNodeData := newTestFullNode([]byte("fullnode")) - - data := [][]byte{} - for i := 0; i < 16; i++ { - data = append(data, nil) - } - data = append(data, []byte("subnode")) - fullNodeData[15] = data - - buf := bytes.NewBuffer([]byte{}) - rlp.Encode(buf, fullNodeData) - - if _, err := decodeNode([]byte("testdecode"), buf.Bytes()); err != nil { - t.Fatalf("decode nested full node err: %v", err) - } -} - -func TestDecodeFullNodeWrongSizeChild(t *testing.T) { - fullNodeData := newTestFullNode([]byte("wrongsizechild")) - fullNodeData[0] = []byte("00") - buf := bytes.NewBuffer([]byte{}) - rlp.Encode(buf, fullNodeData) - - _, err := decodeNode([]byte("testdecode"), buf.Bytes()) - if _, ok := err.(*decodeError); !ok { - t.Fatalf("decodeNode returned wrong err: %v", err) - } -} - -func TestDecodeFullNodeWrongNestedFullNode(t *testing.T) { - fullNodeData := newTestFullNode([]byte("fullnode")) - - data := [][]byte{} - for i := 0; i < 16; i++ { - data = append(data, []byte("123456")) - } - data = append(data, []byte("subnode")) - fullNodeData[15] = data - - buf := bytes.NewBuffer([]byte{}) - rlp.Encode(buf, fullNodeData) - - _, err := decodeNode([]byte("testdecode"), buf.Bytes()) - if _, ok := err.(*decodeError); !ok { - t.Fatalf("decodeNode returned wrong err: %v", err) - } -} - -func TestDecodeFullNode(t *testing.T) { - fullNodeData := newTestFullNode([]byte("decodefullnode")) - buf := bytes.NewBuffer([]byte{}) - rlp.Encode(buf, fullNodeData) - - _, err := decodeNode([]byte("testdecode"), buf.Bytes()) - if err != nil { - t.Fatalf("decode full node err: %v", err) - } -} - -// goos: darwin -// goarch: arm64 -// pkg: github.com/ava-labs/coreth/trie -// BenchmarkEncodeShortNode -// BenchmarkEncodeShortNode-8 16878850 70.81 ns/op 48 B/op 1 allocs/op -func BenchmarkEncodeShortNode(b *testing.B) { - node := &shortNode{ - Key: []byte{0x1, 0x2}, - Val: hashNode(randBytes(32)), - } - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - nodeToBytes(node) - } -} - -// goos: darwin -// goarch: arm64 -// pkg: github.com/ava-labs/coreth/trie -// BenchmarkEncodeFullNode -// BenchmarkEncodeFullNode-8 4323273 284.4 ns/op 576 B/op 1 allocs/op -func BenchmarkEncodeFullNode(b *testing.B) { - node := &fullNode{} - for i := 0; i < 16; i++ { - node.Children[i] = hashNode(randBytes(32)) - } - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - nodeToBytes(node) - } -} - -// goos: darwin -// goarch: arm64 -// pkg: github.com/ava-labs/coreth/trie -// BenchmarkDecodeShortNode -// BenchmarkDecodeShortNode-8 7925638 151.0 ns/op 157 B/op 4 allocs/op -func BenchmarkDecodeShortNode(b *testing.B) { - node := &shortNode{ - Key: []byte{0x1, 0x2}, - Val: hashNode(randBytes(32)), - } - blob := nodeToBytes(node) - hash := crypto.Keccak256(blob) - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - mustDecodeNode(hash, blob) - } -} - -// goos: darwin -// goarch: arm64 -// pkg: github.com/ava-labs/coreth/trie -// BenchmarkDecodeShortNodeUnsafe -// BenchmarkDecodeShortNodeUnsafe-8 9027476 128.6 ns/op 109 B/op 3 allocs/op -func BenchmarkDecodeShortNodeUnsafe(b *testing.B) { - node := &shortNode{ - Key: []byte{0x1, 0x2}, - Val: hashNode(randBytes(32)), - } - blob := nodeToBytes(node) - hash := crypto.Keccak256(blob) - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - mustDecodeNodeUnsafe(hash, blob) - } -} - -// goos: darwin -// goarch: arm64 -// pkg: github.com/ava-labs/coreth/trie -// BenchmarkDecodeFullNode -// BenchmarkDecodeFullNode-8 1597462 761.9 ns/op 1280 B/op 18 allocs/op -func BenchmarkDecodeFullNode(b *testing.B) { - node := &fullNode{} - for i := 0; i < 16; i++ { - node.Children[i] = hashNode(randBytes(32)) - } - blob := nodeToBytes(node) - hash := crypto.Keccak256(blob) - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - mustDecodeNode(hash, blob) - } -} - -// goos: darwin -// goarch: arm64 -// pkg: github.com/ava-labs/coreth/trie -// BenchmarkDecodeFullNodeUnsafe -// BenchmarkDecodeFullNodeUnsafe-8 1789070 687.1 ns/op 704 B/op 17 allocs/op -func BenchmarkDecodeFullNodeUnsafe(b *testing.B) { - node := &fullNode{} - for i := 0; i < 16; i++ { - node.Children[i] = hashNode(randBytes(32)) - } - blob := nodeToBytes(node) - hash := crypto.Keccak256(blob) - - b.ResetTimer() - b.ReportAllocs() - - for i := 0; i < b.N; i++ { - mustDecodeNodeUnsafe(hash, blob) - } -} diff --git a/trie/proof.go b/trie/proof.go deleted file mode 100644 index 4bedbf0bc6..0000000000 --- a/trie/proof.go +++ /dev/null @@ -1,626 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "errors" - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" -) - -// Prove constructs a merkle proof for key. The result contains all encoded nodes -// on the path to the value at key. The value itself is also included in the last -// node and can be retrieved by verifying the proof. -// -// If the trie does not contain a value for key, the returned proof contains all -// nodes of the longest existing prefix of the key (at least the root node), ending -// with the node that proves the absence of the key. -func (t *Trie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { - // Short circuit if the trie is already committed and not usable. - if t.committed { - return ErrCommitted - } - // Collect all nodes on the path to key. - var ( - prefix []byte - nodes []node - tn = t.root - ) - key = keybytesToHex(key) - for len(key) > 0 && tn != nil { - switch n := tn.(type) { - case *shortNode: - if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { - // The trie doesn't contain the key. - tn = nil - } else { - tn = n.Val - prefix = append(prefix, n.Key...) - key = key[len(n.Key):] - } - nodes = append(nodes, n) - case *fullNode: - tn = n.Children[key[0]] - prefix = append(prefix, key[0]) - key = key[1:] - nodes = append(nodes, n) - case hashNode: - // Retrieve the specified node from the underlying node reader. - // trie.resolveAndTrack is not used since in that function the - // loaded blob will be tracked, while it's not required here since - // all loaded nodes won't be linked to trie at all and track nodes - // may lead to out-of-memory issue. - blob, err := t.reader.node(prefix, common.BytesToHash(n)) - if err != nil { - log.Error("Unhandled trie error in Trie.Prove", "err", err) - return err - } - // The raw-blob format nodes are loaded either from the - // clean cache or the database, they are all in their own - // copy and safe to use unsafe decoder. - tn = mustDecodeNodeUnsafe(n, blob) - default: - panic(fmt.Sprintf("%T: invalid node: %v", tn, tn)) - } - } - hasher := newHasher(false) - defer returnHasherToPool(hasher) - - for i, n := range nodes { - var hn node - n, hn = hasher.proofHash(n) - if hash, ok := hn.(hashNode); ok || i == 0 { - // If the node's database encoding is a hash (or is the - // root node), it becomes a proof element. - enc := nodeToBytes(n) - if !ok { - hash = hasher.hashData(enc) - } - proofDb.Put(hash, enc) - } - } - return nil -} - -// Prove constructs a merkle proof for key. The result contains all encoded nodes -// on the path to the value at key. The value itself is also included in the last -// node and can be retrieved by verifying the proof. -// -// If the trie does not contain a value for key, the returned proof contains all -// nodes of the longest existing prefix of the key (at least the root node), ending -// with the node that proves the absence of the key. -func (t *StateTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { - return t.trie.Prove(key, proofDb) -} - -// VerifyProof checks merkle proofs. The given proof must contain the value for -// key in a trie with the given root hash. VerifyProof returns an error if the -// proof contains invalid trie nodes or the wrong value. -func VerifyProof(rootHash common.Hash, key []byte, proofDb ethdb.KeyValueReader) (value []byte, err error) { - key = keybytesToHex(key) - wantHash := rootHash - for i := 0; ; i++ { - buf, _ := proofDb.Get(wantHash[:]) - if buf == nil { - return nil, fmt.Errorf("proof node %d (hash %064x) missing", i, wantHash) - } - n, err := decodeNode(wantHash[:], buf) - if err != nil { - return nil, fmt.Errorf("bad proof node %d: %v", i, err) - } - keyrest, cld := get(n, key, true) - switch cld := cld.(type) { - case nil: - // The trie doesn't contain the key. - return nil, nil - case hashNode: - key = keyrest - copy(wantHash[:], cld) - case valueNode: - return cld, nil - } - } -} - -// proofToPath converts a merkle proof to trie node path. The main purpose of -// this function is recovering a node path from the merkle proof stream. All -// necessary nodes will be resolved and leave the remaining as hashnode. -// -// The given edge proof is allowed to be an existent or non-existent proof. -func proofToPath(rootHash common.Hash, root node, key []byte, proofDb ethdb.KeyValueReader, allowNonExistent bool) (node, []byte, error) { - // resolveNode retrieves and resolves trie node from merkle proof stream - resolveNode := func(hash common.Hash) (node, error) { - buf, _ := proofDb.Get(hash[:]) - if buf == nil { - return nil, fmt.Errorf("proof node (hash %064x) missing", hash) - } - n, err := decodeNode(hash[:], buf) - if err != nil { - return nil, fmt.Errorf("bad proof node %v", err) - } - return n, err - } - // If the root node is empty, resolve it first. - // Root node must be included in the proof. - if root == nil { - n, err := resolveNode(rootHash) - if err != nil { - return nil, nil, err - } - root = n - } - var ( - err error - child, parent node - keyrest []byte - valnode []byte - ) - key, parent = keybytesToHex(key), root - for { - keyrest, child = get(parent, key, false) - switch cld := child.(type) { - case nil: - // The trie doesn't contain the key. It's possible - // the proof is a non-existing proof, but at least - // we can prove all resolved nodes are correct, it's - // enough for us to prove range. - if allowNonExistent { - return root, nil, nil - } - return nil, nil, errors.New("the node is not contained in trie") - case *shortNode: - key, parent = keyrest, child // Already resolved - continue - case *fullNode: - key, parent = keyrest, child // Already resolved - continue - case hashNode: - child, err = resolveNode(common.BytesToHash(cld)) - if err != nil { - return nil, nil, err - } - case valueNode: - valnode = cld - } - // Link the parent and child. - switch pnode := parent.(type) { - case *shortNode: - pnode.Val = child - case *fullNode: - pnode.Children[key[0]] = child - default: - panic(fmt.Sprintf("%T: invalid node: %v", pnode, pnode)) - } - if len(valnode) > 0 { - return root, valnode, nil // The whole path is resolved - } - key, parent = keyrest, child - } -} - -// unsetInternal removes all internal node references(hashnode, embedded node). -// It should be called after a trie is constructed with two edge paths. Also -// the given boundary keys must be the one used to construct the edge paths. -// -// It's the key step for range proof. All visited nodes should be marked dirty -// since the node content might be modified. Besides it can happen that some -// fullnodes only have one child which is disallowed. But if the proof is valid, -// the missing children will be filled, otherwise it will be thrown anyway. -// -// Note we have the assumption here the given boundary keys are different -// and right is larger than left. -func unsetInternal(n node, left []byte, right []byte) (bool, error) { - left, right = keybytesToHex(left), keybytesToHex(right) - - // Step down to the fork point. There are two scenarios can happen: - // - the fork point is a shortnode: either the key of left proof or - // right proof doesn't match with shortnode's key. - // - the fork point is a fullnode: both two edge proofs are allowed - // to point to a non-existent key. - var ( - pos = 0 - parent node - - // fork indicator, 0 means no fork, -1 means proof is less, 1 means proof is greater - shortForkLeft, shortForkRight int - ) -findFork: - for { - switch rn := (n).(type) { - case *shortNode: - rn.flags = nodeFlag{dirty: true} - - // If either the key of left proof or right proof doesn't match with - // shortnode, stop here and the forkpoint is the shortnode. - if len(left)-pos < len(rn.Key) { - shortForkLeft = bytes.Compare(left[pos:], rn.Key) - } else { - shortForkLeft = bytes.Compare(left[pos:pos+len(rn.Key)], rn.Key) - } - if len(right)-pos < len(rn.Key) { - shortForkRight = bytes.Compare(right[pos:], rn.Key) - } else { - shortForkRight = bytes.Compare(right[pos:pos+len(rn.Key)], rn.Key) - } - if shortForkLeft != 0 || shortForkRight != 0 { - break findFork - } - parent = n - n, pos = rn.Val, pos+len(rn.Key) - case *fullNode: - rn.flags = nodeFlag{dirty: true} - - // If either the node pointed by left proof or right proof is nil, - // stop here and the forkpoint is the fullnode. - leftnode, rightnode := rn.Children[left[pos]], rn.Children[right[pos]] - if leftnode == nil || rightnode == nil || leftnode != rightnode { - break findFork - } - parent = n - n, pos = rn.Children[left[pos]], pos+1 - default: - panic(fmt.Sprintf("%T: invalid node: %v", n, n)) - } - } - switch rn := n.(type) { - case *shortNode: - // There can have these five scenarios: - // - both proofs are less than the trie path => no valid range - // - both proofs are greater than the trie path => no valid range - // - left proof is less and right proof is greater => valid range, unset the shortnode entirely - // - left proof points to the shortnode, but right proof is greater - // - right proof points to the shortnode, but left proof is less - if shortForkLeft == -1 && shortForkRight == -1 { - return false, errors.New("empty range") - } - if shortForkLeft == 1 && shortForkRight == 1 { - return false, errors.New("empty range") - } - if shortForkLeft != 0 && shortForkRight != 0 { - // The fork point is root node, unset the entire trie - if parent == nil { - return true, nil - } - parent.(*fullNode).Children[left[pos-1]] = nil - return false, nil - } - // Only one proof points to non-existent key. - if shortForkRight != 0 { - if _, ok := rn.Val.(valueNode); ok { - // The fork point is root node, unset the entire trie - if parent == nil { - return true, nil - } - parent.(*fullNode).Children[left[pos-1]] = nil - return false, nil - } - return false, unset(rn, rn.Val, left[pos:], len(rn.Key), false) - } - if shortForkLeft != 0 { - if _, ok := rn.Val.(valueNode); ok { - // The fork point is root node, unset the entire trie - if parent == nil { - return true, nil - } - parent.(*fullNode).Children[right[pos-1]] = nil - return false, nil - } - return false, unset(rn, rn.Val, right[pos:], len(rn.Key), true) - } - return false, nil - case *fullNode: - // unset all internal nodes in the forkpoint - for i := left[pos] + 1; i < right[pos]; i++ { - rn.Children[i] = nil - } - if err := unset(rn, rn.Children[left[pos]], left[pos:], 1, false); err != nil { - return false, err - } - if err := unset(rn, rn.Children[right[pos]], right[pos:], 1, true); err != nil { - return false, err - } - return false, nil - default: - panic(fmt.Sprintf("%T: invalid node: %v", n, n)) - } -} - -// unset removes all internal node references either the left most or right most. -// It can meet these scenarios: -// -// - The given path is existent in the trie, unset the associated nodes with the -// specific direction -// - The given path is non-existent in the trie -// - the fork point is a fullnode, the corresponding child pointed by path -// is nil, return -// - the fork point is a shortnode, the shortnode is included in the range, -// keep the entire branch and return. -// - the fork point is a shortnode, the shortnode is excluded in the range, -// unset the entire branch. -func unset(parent node, child node, key []byte, pos int, removeLeft bool) error { - switch cld := child.(type) { - case *fullNode: - if removeLeft { - for i := 0; i < int(key[pos]); i++ { - cld.Children[i] = nil - } - cld.flags = nodeFlag{dirty: true} - } else { - for i := key[pos] + 1; i < 16; i++ { - cld.Children[i] = nil - } - cld.flags = nodeFlag{dirty: true} - } - return unset(cld, cld.Children[key[pos]], key, pos+1, removeLeft) - case *shortNode: - if len(key[pos:]) < len(cld.Key) || !bytes.Equal(cld.Key, key[pos:pos+len(cld.Key)]) { - // Find the fork point, it's an non-existent branch. - if removeLeft { - if bytes.Compare(cld.Key, key[pos:]) < 0 { - // The key of fork shortnode is less than the path - // (it belongs to the range), unset the entire - // branch. The parent must be a fullnode. - fn := parent.(*fullNode) - fn.Children[key[pos-1]] = nil - } - //else { - // The key of fork shortnode is greater than the - // path(it doesn't belong to the range), keep - // it with the cached hash available. - //} - } else { - if bytes.Compare(cld.Key, key[pos:]) > 0 { - // The key of fork shortnode is greater than the - // path(it belongs to the range), unset the entries - // branch. The parent must be a fullnode. - fn := parent.(*fullNode) - fn.Children[key[pos-1]] = nil - } - //else { - // The key of fork shortnode is less than the - // path(it doesn't belong to the range), keep - // it with the cached hash available. - //} - } - return nil - } - if _, ok := cld.Val.(valueNode); ok { - fn := parent.(*fullNode) - fn.Children[key[pos-1]] = nil - return nil - } - cld.flags = nodeFlag{dirty: true} - return unset(cld, cld.Val, key, pos+len(cld.Key), removeLeft) - case nil: - // If the node is nil, then it's a child of the fork point - // fullnode(it's a non-existent branch). - return nil - default: - panic("it shouldn't happen") // hashNode, valueNode - } -} - -// hasRightElement returns the indicator whether there exists more elements -// on the right side of the given path. The given path can point to an existent -// key or a non-existent one. This function has the assumption that the whole -// path should already be resolved. -func hasRightElement(node node, key []byte) bool { - pos, key := 0, keybytesToHex(key) - for node != nil { - switch rn := node.(type) { - case *fullNode: - for i := key[pos] + 1; i < 16; i++ { - if rn.Children[i] != nil { - return true - } - } - node, pos = rn.Children[key[pos]], pos+1 - case *shortNode: - if len(key)-pos < len(rn.Key) || !bytes.Equal(rn.Key, key[pos:pos+len(rn.Key)]) { - return bytes.Compare(rn.Key, key[pos:]) > 0 - } - node, pos = rn.Val, pos+len(rn.Key) - case valueNode: - return false // We have resolved the whole path - default: - panic(fmt.Sprintf("%T: invalid node: %v", node, node)) // hashnode - } - } - return false -} - -// VerifyRangeProof checks whether the given leaf nodes and edge proof -// can prove the given trie leaves range is matched with the specific root. -// Besides, the range should be consecutive (no gap inside) and monotonic -// increasing. -// -// Note the given proof actually contains two edge proofs. Both of them can -// be non-existent proofs. For example the first proof is for a non-existent -// key 0x03, the last proof is for a non-existent key 0x10. The given batch -// leaves are [0x04, 0x05, .. 0x09]. It's still feasible to prove the given -// batch is valid. -// -// The firstKey is paired with firstProof, not necessarily the same as keys[0] -// (unless firstProof is an existent proof). Similarly, lastKey and lastProof -// are paired. -// -// Expect the normal case, this function can also be used to verify the following -// range proofs: -// -// - All elements proof. In this case the proof can be nil, but the range should -// be all the leaves in the trie. -// -// - One element proof. In this case no matter the edge proof is a non-existent -// proof or not, we can always verify the correctness of the proof. -// -// - Zero element proof. In this case a single non-existent proof is enough to prove. -// Besides, if there are still some other leaves available on the right side, then -// an error will be returned. -// -// Except returning the error to indicate the proof is valid or not, the function will -// also return a flag to indicate whether there exists more accounts/slots in the trie. -// -// Note: This method does not verify that the proof is of minimal form. If the input -// proofs are 'bloated' with neighbour leaves or random data, aside from the 'useful' -// data, then the proof will still be accepted. -func VerifyRangeProof(rootHash common.Hash, firstKey []byte, keys [][]byte, values [][]byte, proof ethdb.KeyValueReader) (bool, error) { - if len(keys) != len(values) { - return false, fmt.Errorf("inconsistent proof data, keys: %d, values: %d", len(keys), len(values)) - } - // Ensure the received batch is monotonic increasing and contains no deletions - for i := 0; i < len(keys)-1; i++ { - if bytes.Compare(keys[i], keys[i+1]) >= 0 { - return false, errors.New("range is not monotonically increasing") - } - } - for _, value := range values { - if len(value) == 0 { - return false, errors.New("range contains deletion") - } - } - // Special case, there is no edge proof at all. The given range is expected - // to be the whole leaf-set in the trie. - if proof == nil { - tr := NewStackTrie(nil) - for index, key := range keys { - tr.Update(key, values[index]) - } - if have, want := tr.Hash(), rootHash; have != want { - return false, fmt.Errorf("invalid proof, want hash %x, got %x", want, have) - } - return false, nil // No more elements - } - // Special case, there is a provided edge proof but zero key/value - // pairs, ensure there are no more accounts / slots in the trie. - if len(keys) == 0 { - root, val, err := proofToPath(rootHash, nil, firstKey, proof, true) - if err != nil { - return false, err - } - if val != nil || hasRightElement(root, firstKey) { - return false, errors.New("more entries available") - } - return false, nil - } - var lastKey = keys[len(keys)-1] - // Special case, there is only one element and two edge keys are same. - // In this case, we can't construct two edge paths. So handle it here. - if len(keys) == 1 && bytes.Equal(firstKey, lastKey) { - root, val, err := proofToPath(rootHash, nil, firstKey, proof, false) - if err != nil { - return false, err - } - if !bytes.Equal(firstKey, keys[0]) { - return false, errors.New("correct proof but invalid key") - } - if !bytes.Equal(val, values[0]) { - return false, errors.New("correct proof but invalid data") - } - return hasRightElement(root, firstKey), nil - } - // Ok, in all other cases, we require two edge paths available. - // First check the validity of edge keys. - if bytes.Compare(firstKey, lastKey) >= 0 { - return false, errors.New("invalid edge keys") - } - // todo(rjl493456442) different length edge keys should be supported - if len(firstKey) != len(lastKey) { - return false, fmt.Errorf("inconsistent edge keys (%d != %d)", len(firstKey), len(lastKey)) - } - // Convert the edge proofs to edge trie paths. Then we can - // have the same tree architecture with the original one. - // For the first edge proof, non-existent proof is allowed. - root, _, err := proofToPath(rootHash, nil, firstKey, proof, true) - if err != nil { - return false, err - } - // Pass the root node here, the second path will be merged - // with the first one. For the last edge proof, non-existent - // proof is also allowed. - root, _, err = proofToPath(rootHash, root, lastKey, proof, true) - if err != nil { - return false, err - } - // Remove all internal references. All the removed parts should - // be re-filled(or re-constructed) by the given leaves range. - empty, err := unsetInternal(root, firstKey, lastKey) - if err != nil { - return false, err - } - // Rebuild the trie with the leaf stream, the shape of trie - // should be same with the original one. - tr := &Trie{root: root, reader: newEmptyReader(), tracer: newTracer()} - if empty { - tr.root = nil - } - for index, key := range keys { - tr.Update(key, values[index]) - } - if tr.Hash() != rootHash { - return false, fmt.Errorf("invalid proof, want hash %x, got %x", rootHash, tr.Hash()) - } - return hasRightElement(tr.root, keys[len(keys)-1]), nil -} - -// get returns the child of the given node. Return nil if the -// node with specified key doesn't exist at all. -// -// There is an additional flag `skipResolved`. If it's set then -// all resolved nodes won't be returned. -func get(tn node, key []byte, skipResolved bool) ([]byte, node) { - for { - switch n := tn.(type) { - case *shortNode: - if len(key) < len(n.Key) || !bytes.Equal(n.Key, key[:len(n.Key)]) { - return nil, nil - } - tn = n.Val - key = key[len(n.Key):] - if !skipResolved { - return key, tn - } - case *fullNode: - tn = n.Children[key[0]] - key = key[1:] - if !skipResolved { - return key, tn - } - case hashNode: - return key, n - case nil: - return key, nil - case valueNode: - return nil, n - default: - panic(fmt.Sprintf("%T: invalid node: %v", tn, tn)) - } - } -} diff --git a/trie/proof_test.go b/trie/proof_test.go deleted file mode 100644 index 3fb0ba363d..0000000000 --- a/trie/proof_test.go +++ /dev/null @@ -1,1012 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - crand "crypto/rand" - "encoding/binary" - "fmt" - mrand "math/rand" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb/memorydb" - "golang.org/x/exp/slices" -) - -// Prng is a pseudo random number generator seeded by strong randomness. -// The randomness is printed on startup in order to make failures reproducible. -var prng = initRnd() - -func initRnd() *mrand.Rand { - var seed [8]byte - crand.Read(seed[:]) - rnd := mrand.New(mrand.NewSource(int64(binary.LittleEndian.Uint64(seed[:])))) - fmt.Printf("Seed: %x\n", seed) - return rnd -} - -func randBytes(n int) []byte { - r := make([]byte, n) - prng.Read(r) - return r -} - -// makeProvers creates Merkle trie provers based on different implementations to -// test all variations. -func makeProvers(trie *Trie) []func(key []byte) *memorydb.Database { - var provers []func(key []byte) *memorydb.Database - - // Create a direct trie based Merkle prover - provers = append(provers, func(key []byte) *memorydb.Database { - proof := memorydb.New() - trie.Prove(key, proof) - return proof - }) - // Create a leaf iterator based Merkle prover - provers = append(provers, func(key []byte) *memorydb.Database { - proof := memorydb.New() - if it := NewIterator(trie.MustNodeIterator(key)); it.Next() && bytes.Equal(key, it.Key) { - for _, p := range it.Prove() { - proof.Put(crypto.Keccak256(p), p) - } - } - return proof - }) - return provers -} - -func TestProof(t *testing.T) { - trie, vals := randomTrie(500) - root := trie.Hash() - for i, prover := range makeProvers(trie) { - for _, kv := range vals { - proof := prover(kv.k) - if proof == nil { - t.Fatalf("prover %d: missing key %x while constructing proof", i, kv.k) - } - val, err := VerifyProof(root, kv.k, proof) - if err != nil { - t.Fatalf("prover %d: failed to verify proof for key %x: %v\nraw proof: %x", i, kv.k, err, proof) - } - if !bytes.Equal(val, kv.v) { - t.Fatalf("prover %d: verified value mismatch for key %x: have %x, want %x", i, kv.k, val, kv.v) - } - } - } -} - -func TestOneElementProof(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - updateString(trie, "k", "v") - for i, prover := range makeProvers(trie) { - proof := prover([]byte("k")) - if proof == nil { - t.Fatalf("prover %d: nil proof", i) - } - if proof.Len() != 1 { - t.Errorf("prover %d: proof should have one element", i) - } - val, err := VerifyProof(trie.Hash(), []byte("k"), proof) - if err != nil { - t.Fatalf("prover %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) - } - if !bytes.Equal(val, []byte("v")) { - t.Fatalf("prover %d: verified value mismatch: have %x, want 'k'", i, val) - } - } -} - -func TestBadProof(t *testing.T) { - trie, vals := randomTrie(800) - root := trie.Hash() - for i, prover := range makeProvers(trie) { - for _, kv := range vals { - proof := prover(kv.k) - if proof == nil { - t.Fatalf("prover %d: nil proof", i) - } - it := proof.NewIterator(nil, nil) - for i, d := 0, mrand.Intn(proof.Len()); i <= d; i++ { - it.Next() - } - key := it.Key() - val, _ := proof.Get(key) - proof.Delete(key) - it.Release() - - mutateByte(val) - proof.Put(crypto.Keccak256(val), val) - - if _, err := VerifyProof(root, kv.k, proof); err == nil { - t.Fatalf("prover %d: expected proof to fail for key %x", i, kv.k) - } - } - } -} - -// Tests that missing keys can also be proven. The test explicitly uses a single -// entry trie and checks for missing keys both before and after the single entry. -func TestMissingKeyProof(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - updateString(trie, "k", "v") - - for i, key := range []string{"a", "j", "l", "z"} { - proof := memorydb.New() - trie.Prove([]byte(key), proof) - - if proof.Len() != 1 { - t.Errorf("test %d: proof should have one element", i) - } - val, err := VerifyProof(trie.Hash(), []byte(key), proof) - if err != nil { - t.Fatalf("test %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) - } - if val != nil { - t.Fatalf("test %d: verified value mismatch: have %x, want nil", i, val) - } - } -} - -// TestRangeProof tests normal range proof with both edge proofs -// as the existent proof. The test cases are generated randomly. -func TestRangeProof(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - for i := 0; i < 500; i++ { - start := mrand.Intn(len(entries)) - end := mrand.Intn(len(entries)-start) + start + 1 - - proof := memorydb.New() - if err := trie.Prove(entries[start].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[end-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - var keys [][]byte - var vals [][]byte - for i := start; i < end; i++ { - keys = append(keys, entries[i].k) - vals = append(vals, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof) - if err != nil { - t.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) - } - } -} - -// TestRangeProof tests normal range proof with two non-existent proofs. -// The test cases are generated randomly. -func TestRangeProofWithNonExistentProof(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - for i := 0; i < 500; i++ { - start := mrand.Intn(len(entries)) - end := mrand.Intn(len(entries)-start) + start + 1 - proof := memorydb.New() - - // Short circuit if the decreased key is same with the previous key - first := decreaseKey(common.CopyBytes(entries[start].k)) - if start != 0 && bytes.Equal(first, entries[start-1].k) { - continue - } - // Short circuit if the decreased key is underflow - if bytes.Compare(first, entries[start].k) > 0 { - continue - } - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[end-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - var keys [][]byte - var vals [][]byte - for i := start; i < end; i++ { - keys = append(keys, entries[i].k) - vals = append(vals, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), first, keys, vals, proof) - if err != nil { - t.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) - } - } -} - -// TestRangeProofWithInvalidNonExistentProof tests such scenarios: -// - There exists a gap between the first element and the left edge proof -func TestRangeProofWithInvalidNonExistentProof(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - // Case 1 - start, end := 100, 200 - first := decreaseKey(common.CopyBytes(entries[start].k)) - - proof := memorydb.New() - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[end-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - start = 105 // Gap created - k := make([][]byte, 0) - v := make([][]byte, 0) - for i := start; i < end; i++ { - k = append(k, entries[i].k) - v = append(v, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), first, k, v, proof) - if err == nil { - t.Fatalf("Expected to detect the error, got nil") - } -} - -// TestOneElementRangeProof tests the proof with only one -// element. The first edge proof can be existent one or -// non-existent one. -func TestOneElementRangeProof(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - // One element with existent edge proof, both edge proofs - // point to the SAME key. - start := 1000 - proof := memorydb.New() - if err := trie.Prove(entries[start].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - _, err := VerifyRangeProof(trie.Hash(), entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - - // One element with left non-existent edge proof - start = 1000 - first := decreaseKey(common.CopyBytes(entries[start].k)) - proof = memorydb.New() - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[start].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - _, err = VerifyRangeProof(trie.Hash(), first, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - - // One element with right non-existent edge proof - start = 1000 - last := increaseKey(common.CopyBytes(entries[start].k)) - proof = memorydb.New() - if err := trie.Prove(entries[start].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(last, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - _, err = VerifyRangeProof(trie.Hash(), entries[start].k, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - - // One element with two non-existent edge proofs - start = 1000 - first, last = decreaseKey(common.CopyBytes(entries[start].k)), increaseKey(common.CopyBytes(entries[start].k)) - proof = memorydb.New() - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(last, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - _, err = VerifyRangeProof(trie.Hash(), first, [][]byte{entries[start].k}, [][]byte{entries[start].v}, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - - // Test the mini trie with only a single element. - tinyTrie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - entry := &kv{randBytes(32), randBytes(20), false} - tinyTrie.MustUpdate(entry.k, entry.v) - - first = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() - last = entry.k - proof = memorydb.New() - if err := tinyTrie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := tinyTrie.Prove(last, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - _, err = VerifyRangeProof(tinyTrie.Hash(), first, [][]byte{entry.k}, [][]byte{entry.v}, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } -} - -// TestAllElementsProof tests the range proof with all elements. -// The edge proofs can be nil. -func TestAllElementsProof(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - var k [][]byte - var v [][]byte - for i := 0; i < len(entries); i++ { - k = append(k, entries[i].k) - v = append(v, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), nil, k, v, nil) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - - // With edge proofs, it should still work. - proof := memorydb.New() - if err := trie.Prove(entries[0].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[len(entries)-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - _, err = VerifyRangeProof(trie.Hash(), k[0], k, v, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - - // Even with non-existent edge proofs, it should still work. - proof = memorydb.New() - first := common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000").Bytes() - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[len(entries)-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - _, err = VerifyRangeProof(trie.Hash(), first, k, v, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } -} - -// TestSingleSideRangeProof tests the range starts from zero. -func TestSingleSideRangeProof(t *testing.T) { - for i := 0; i < 64; i++ { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - var entries []*kv - for i := 0; i < 4096; i++ { - value := &kv{randBytes(32), randBytes(20), false} - trie.MustUpdate(value.k, value.v) - entries = append(entries, value) - } - slices.SortFunc(entries, (*kv).cmp) - - var cases = []int{0, 1, 50, 100, 1000, 2000, len(entries) - 1} - for _, pos := range cases { - proof := memorydb.New() - if err := trie.Prove(common.Hash{}.Bytes(), proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[pos].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - k := make([][]byte, 0) - v := make([][]byte, 0) - for i := 0; i <= pos; i++ { - k = append(k, entries[i].k) - v = append(v, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), common.Hash{}.Bytes(), k, v, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - } - } -} - -// TestBadRangeProof tests a few cases which the proof is wrong. -// The prover is expected to detect the error. -func TestBadRangeProof(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - for i := 0; i < 500; i++ { - start := mrand.Intn(len(entries)) - end := mrand.Intn(len(entries)-start) + start + 1 - proof := memorydb.New() - if err := trie.Prove(entries[start].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[end-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - var keys [][]byte - var vals [][]byte - for i := start; i < end; i++ { - keys = append(keys, entries[i].k) - vals = append(vals, entries[i].v) - } - var first = keys[0] - testcase := mrand.Intn(6) - var index int - switch testcase { - case 0: - // Modified key - index = mrand.Intn(end - start) - keys[index] = randBytes(32) // In theory it can't be same - case 1: - // Modified val - index = mrand.Intn(end - start) - vals[index] = randBytes(20) // In theory it can't be same - case 2: - // Gapped entry slice - index = mrand.Intn(end - start) - if (index == 0 && start < 100) || (index == end-start-1) { - continue - } - keys = append(keys[:index], keys[index+1:]...) - vals = append(vals[:index], vals[index+1:]...) - case 3: - // Out of order - index1 := mrand.Intn(end - start) - index2 := mrand.Intn(end - start) - if index1 == index2 { - continue - } - keys[index1], keys[index2] = keys[index2], keys[index1] - vals[index1], vals[index2] = vals[index2], vals[index1] - case 4: - // Set random key to nil, do nothing - index = mrand.Intn(end - start) - keys[index] = nil - case 5: - // Set random value to nil, deletion - index = mrand.Intn(end - start) - vals[index] = nil - } - _, err := VerifyRangeProof(trie.Hash(), first, keys, vals, proof) - if err == nil { - t.Fatalf("%d Case %d index %d range: (%d->%d) expect error, got nil", i, testcase, index, start, end-1) - } - } -} - -// TestGappedRangeProof focuses on the small trie with embedded nodes. -// If the gapped node is embedded in the trie, it should be detected too. -func TestGappedRangeProof(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - var entries []*kv // Sorted entries - for i := byte(0); i < 10; i++ { - value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} - trie.MustUpdate(value.k, value.v) - entries = append(entries, value) - } - first, last := 2, 8 - proof := memorydb.New() - if err := trie.Prove(entries[first].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[last-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - var keys [][]byte - var vals [][]byte - for i := first; i < last; i++ { - if i == (first+last)/2 { - continue - } - keys = append(keys, entries[i].k) - vals = append(vals, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof) - if err == nil { - t.Fatal("expect error, got nil") - } -} - -// TestSameSideProofs tests the element is not in the range covered by proofs -func TestSameSideProofs(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - pos := 1000 - first := common.CopyBytes(entries[0].k) - - proof := memorydb.New() - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[2000].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - _, err := VerifyRangeProof(trie.Hash(), first, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) - if err == nil { - t.Fatalf("Expected error, got nil") - } - - first = increaseKey(common.CopyBytes(entries[pos].k)) - last := increaseKey(common.CopyBytes(entries[pos].k)) - last = increaseKey(last) - - proof = memorydb.New() - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(last, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - _, err = VerifyRangeProof(trie.Hash(), first, [][]byte{entries[pos].k}, [][]byte{entries[pos].v}, proof) - if err == nil { - t.Fatalf("Expected error, got nil") - } -} - -func TestHasRightElement(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - var entries []*kv - for i := 0; i < 4096; i++ { - value := &kv{randBytes(32), randBytes(20), false} - trie.MustUpdate(value.k, value.v) - entries = append(entries, value) - } - slices.SortFunc(entries, (*kv).cmp) - - var cases = []struct { - start int - end int - hasMore bool - }{ - {-1, 1, true}, // single element with non-existent left proof - {0, 1, true}, // single element with existent left proof - {0, 10, true}, - {50, 100, true}, - {50, len(entries), false}, // No more element expected - {len(entries) - 1, len(entries), false}, // Single last element with two existent proofs(point to same key) - {0, len(entries), false}, // The whole set with existent left proof - {-1, len(entries), false}, // The whole set with non-existent left proof - } - for _, c := range cases { - var ( - firstKey []byte - start = c.start - end = c.end - proof = memorydb.New() - ) - if c.start == -1 { - firstKey, start = common.Hash{}.Bytes(), 0 - if err := trie.Prove(firstKey, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - } else { - firstKey = entries[c.start].k - if err := trie.Prove(entries[c.start].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - } - if err := trie.Prove(entries[c.end-1].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - k := make([][]byte, 0) - v := make([][]byte, 0) - for i := start; i < end; i++ { - k = append(k, entries[i].k) - v = append(v, entries[i].v) - } - hasMore, err := VerifyRangeProof(trie.Hash(), firstKey, k, v, proof) - if err != nil { - t.Fatalf("Expected no error, got %v", err) - } - if hasMore != c.hasMore { - t.Fatalf("Wrong hasMore indicator, want %t, got %t", c.hasMore, hasMore) - } - } -} - -// TestEmptyRangeProof tests the range proof with "no" element. -// The first edge proof must be a non-existent proof. -func TestEmptyRangeProof(t *testing.T) { - trie, vals := randomTrie(4096) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - var cases = []struct { - pos int - err bool - }{ - {len(entries) - 1, false}, - {500, true}, - } - for _, c := range cases { - proof := memorydb.New() - first := increaseKey(common.CopyBytes(entries[c.pos].k)) - if err := trie.Prove(first, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - _, err := VerifyRangeProof(trie.Hash(), first, nil, nil, proof) - if c.err && err == nil { - t.Fatalf("Expected error, got nil") - } - if !c.err && err != nil { - t.Fatalf("Expected no error, got %v", err) - } - } -} - -// TestBloatedProof tests a malicious proof, where the proof is more or less the -// whole trie. Previously we didn't accept such packets, but the new APIs do, so -// lets leave this test as a bit weird, but present. -func TestBloatedProof(t *testing.T) { - // Use a small trie - trie, kvs := nonRandomTrie(100) - var entries []*kv - for _, kv := range kvs { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - var keys [][]byte - var vals [][]byte - - proof := memorydb.New() - // In the 'malicious' case, we add proofs for every single item - // (but only one key/value pair used as leaf) - for i, entry := range entries { - trie.Prove(entry.k, proof) - if i == 50 { - keys = append(keys, entry.k) - vals = append(vals, entry.v) - } - } - // For reference, we use the same function, but _only_ prove the first - // and last element - want := memorydb.New() - trie.Prove(keys[0], want) - trie.Prove(keys[len(keys)-1], want) - - if _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof); err != nil { - t.Fatalf("expected bloated proof to succeed, got %v", err) - } -} - -// TestEmptyValueRangeProof tests normal range proof with both edge proofs -// as the existent proof, but with an extra empty value included, which is a -// noop technically, but practically should be rejected. -func TestEmptyValueRangeProof(t *testing.T) { - trie, values := randomTrie(512) - var entries []*kv - for _, kv := range values { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - // Create a new entry with a slightly modified key - mid := len(entries) / 2 - key := common.CopyBytes(entries[mid-1].k) - for n := len(key) - 1; n >= 0; n-- { - if key[n] < 0xff { - key[n]++ - break - } - } - noop := &kv{key, []byte{}, false} - entries = append(append(append([]*kv{}, entries[:mid]...), noop), entries[mid:]...) - - start, end := 1, len(entries)-1 - - proof := memorydb.New() - if err := trie.Prove(entries[start].k, proof); err != nil { - t.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[end-1].k, proof); err != nil { - t.Fatalf("Failed to prove the last node %v", err) - } - var keys [][]byte - var vals [][]byte - for i := start; i < end; i++ { - keys = append(keys, entries[i].k) - vals = append(vals, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, vals, proof) - if err == nil { - t.Fatalf("Expected failure on noop entry") - } -} - -// TestAllElementsEmptyValueRangeProof tests the range proof with all elements, -// but with an extra empty value included, which is a noop technically, but -// practically should be rejected. -func TestAllElementsEmptyValueRangeProof(t *testing.T) { - trie, values := randomTrie(512) - var entries []*kv - for _, kv := range values { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - // Create a new entry with a slightly modified key - mid := len(entries) / 2 - key := common.CopyBytes(entries[mid-1].k) - for n := len(key) - 1; n >= 0; n-- { - if key[n] < 0xff { - key[n]++ - break - } - } - noop := &kv{key, []byte{}, false} - entries = append(append(append([]*kv{}, entries[:mid]...), noop), entries[mid:]...) - - var keys [][]byte - var vals [][]byte - for i := 0; i < len(entries); i++ { - keys = append(keys, entries[i].k) - vals = append(vals, entries[i].v) - } - _, err := VerifyRangeProof(trie.Hash(), nil, keys, vals, nil) - if err == nil { - t.Fatalf("Expected failure on noop entry") - } -} - -// mutateByte changes one byte in b. -func mutateByte(b []byte) { - for r := mrand.Intn(len(b)); ; { - new := byte(mrand.Intn(255)) - if new != b[r] { - b[r] = new - break - } - } -} - -func increaseKey(key []byte) []byte { - for i := len(key) - 1; i >= 0; i-- { - key[i]++ - if key[i] != 0x0 { - break - } - } - return key -} - -func decreaseKey(key []byte) []byte { - for i := len(key) - 1; i >= 0; i-- { - key[i]-- - if key[i] != 0xff { - break - } - } - return key -} - -func BenchmarkProve(b *testing.B) { - trie, vals := randomTrie(100) - var keys []string - for k := range vals { - keys = append(keys, k) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - kv := vals[keys[i%len(keys)]] - proofs := memorydb.New() - if trie.Prove(kv.k, proofs); proofs.Len() == 0 { - b.Fatalf("zero length proof for %x", kv.k) - } - } -} - -func BenchmarkVerifyProof(b *testing.B) { - trie, vals := randomTrie(100) - root := trie.Hash() - var keys []string - var proofs []*memorydb.Database - for k := range vals { - keys = append(keys, k) - proof := memorydb.New() - trie.Prove([]byte(k), proof) - proofs = append(proofs, proof) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - im := i % len(keys) - if _, err := VerifyProof(root, []byte(keys[im]), proofs[im]); err != nil { - b.Fatalf("key %x: %v", keys[im], err) - } - } -} - -func BenchmarkVerifyRangeProof10(b *testing.B) { benchmarkVerifyRangeProof(b, 10) } -func BenchmarkVerifyRangeProof100(b *testing.B) { benchmarkVerifyRangeProof(b, 100) } -func BenchmarkVerifyRangeProof1000(b *testing.B) { benchmarkVerifyRangeProof(b, 1000) } -func BenchmarkVerifyRangeProof5000(b *testing.B) { benchmarkVerifyRangeProof(b, 5000) } - -func benchmarkVerifyRangeProof(b *testing.B, size int) { - trie, vals := randomTrie(8192) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - start := 2 - end := start + size - proof := memorydb.New() - if err := trie.Prove(entries[start].k, proof); err != nil { - b.Fatalf("Failed to prove the first node %v", err) - } - if err := trie.Prove(entries[end-1].k, proof); err != nil { - b.Fatalf("Failed to prove the last node %v", err) - } - var keys [][]byte - var values [][]byte - for i := start; i < end; i++ { - keys = append(keys, entries[i].k) - values = append(values, entries[i].v) - } - - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, values, proof) - if err != nil { - b.Fatalf("Case %d(%d->%d) expect no error, got %v", i, start, end-1, err) - } - } -} - -func BenchmarkVerifyRangeNoProof10(b *testing.B) { benchmarkVerifyRangeNoProof(b, 100) } -func BenchmarkVerifyRangeNoProof500(b *testing.B) { benchmarkVerifyRangeNoProof(b, 500) } -func BenchmarkVerifyRangeNoProof1000(b *testing.B) { benchmarkVerifyRangeNoProof(b, 1000) } - -func benchmarkVerifyRangeNoProof(b *testing.B, size int) { - trie, vals := randomTrie(size) - var entries []*kv - for _, kv := range vals { - entries = append(entries, kv) - } - slices.SortFunc(entries, (*kv).cmp) - - var keys [][]byte - var values [][]byte - for _, entry := range entries { - keys = append(keys, entry.k) - values = append(values, entry.v) - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, err := VerifyRangeProof(trie.Hash(), keys[0], keys, values, nil) - if err != nil { - b.Fatalf("Expected no error, got %v", err) - } - } -} - -func randomTrie(n int) (*Trie, map[string]*kv) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - vals := make(map[string]*kv) - for i := byte(0); i < 100; i++ { - value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} - value2 := &kv{common.LeftPadBytes([]byte{i + 10}, 32), []byte{i}, false} - trie.MustUpdate(value.k, value.v) - trie.MustUpdate(value2.k, value2.v) - vals[string(value.k)] = value - vals[string(value2.k)] = value2 - } - for i := 0; i < n; i++ { - value := &kv{randBytes(32), randBytes(20), false} - trie.MustUpdate(value.k, value.v) - vals[string(value.k)] = value - } - return trie, vals -} - -func nonRandomTrie(n int) (*Trie, map[string]*kv) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - vals := make(map[string]*kv) - max := uint64(0xffffffffffffffff) - for i := uint64(0); i < uint64(n); i++ { - value := make([]byte, 32) - key := make([]byte, 32) - binary.LittleEndian.PutUint64(key, i) - binary.LittleEndian.PutUint64(value, i-max) - //value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} - elem := &kv{key, value, false} - trie.MustUpdate(elem.k, elem.v) - vals[string(elem.k)] = elem - } - return trie, vals -} - -func TestRangeProofKeysWithSharedPrefix(t *testing.T) { - keys := [][]byte{ - common.Hex2Bytes("aa10000000000000000000000000000000000000000000000000000000000000"), - common.Hex2Bytes("aa20000000000000000000000000000000000000000000000000000000000000"), - } - vals := [][]byte{ - common.Hex2Bytes("02"), - common.Hex2Bytes("03"), - } - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - for i, key := range keys { - trie.MustUpdate(key, vals[i]) - } - root := trie.Hash() - proof := memorydb.New() - start := common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") - if err := trie.Prove(start, proof); err != nil { - t.Fatalf("failed to prove start: %v", err) - } - if err := trie.Prove(keys[len(keys)-1], proof); err != nil { - t.Fatalf("failed to prove end: %v", err) - } - - more, err := VerifyRangeProof(root, start, keys, vals, proof) - if err != nil { - t.Fatalf("failed to verify range proof: %v", err) - } - if more != false { - t.Error("expected more to be false") - } -} diff --git a/trie/secure_trie.go b/trie/secure_trie.go deleted file mode 100644 index f47c49bf8b..0000000000 --- a/trie/secure_trie.go +++ /dev/null @@ -1,296 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/triedb/database" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" -) - -// SecureTrie is the old name of StateTrie. -// Deprecated: use StateTrie. -type SecureTrie = StateTrie - -// NewSecure creates a new StateTrie. -// Deprecated: use NewStateTrie. -func NewSecure(stateRoot common.Hash, owner common.Hash, root common.Hash, db database.Database) (*SecureTrie, error) { - id := &ID{ - StateRoot: stateRoot, - Owner: owner, - Root: root, - } - return NewStateTrie(id, db) -} - -// StateTrie wraps a trie with key hashing. In a stateTrie trie, all -// access operations hash the key using keccak256. This prevents -// calling code from creating long chains of nodes that -// increase the access time. -// -// Contrary to a regular trie, a StateTrie can only be created with -// New and must have an attached database. The database also stores -// the preimage of each key if preimage recording is enabled. -// -// StateTrie is not safe for concurrent use. -type StateTrie struct { - trie Trie - db database.Database - hashKeyBuf [common.HashLength]byte - secKeyCache map[string][]byte - secKeyCacheOwner *StateTrie // Pointer to self, replace the key cache on mismatch -} - -// NewStateTrie creates a trie with an existing root node from a backing database. -// -// If root is the zero hash or the sha3 hash of an empty string, the -// trie is initially empty. Otherwise, New will panic if db is nil -// and returns MissingNodeError if the root node cannot be found. -func NewStateTrie(id *ID, db database.Database) (*StateTrie, error) { - if db == nil { - panic("trie.NewStateTrie called without a database") - } - trie, err := New(id, db) - if err != nil { - return nil, err - } - return &StateTrie{trie: *trie, db: db}, nil -} - -// MustGet returns the value for key stored in the trie. -// The value bytes must not be modified by the caller. -// -// This function will omit any encountered error but just -// print out an error message. -func (t *StateTrie) MustGet(key []byte) []byte { - return t.trie.MustGet(t.hashKey(key)) -} - -// GetStorage attempts to retrieve a storage slot with provided account address -// and slot key. The value bytes must not be modified by the caller. -// If the specified storage slot is not in the trie, nil will be returned. -// If a trie node is not found in the database, a MissingNodeError is returned. -func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) { - enc, err := t.trie.Get(t.hashKey(key)) - if err != nil || len(enc) == 0 { - return nil, err - } - _, content, _, err := rlp.Split(enc) - return content, err -} - -// GetAccount attempts to retrieve an account with provided account address. -// If the specified account is not in the trie, nil will be returned. -// If a trie node is not found in the database, a MissingNodeError is returned. -func (t *StateTrie) GetAccount(address common.Address) (*types.StateAccount, error) { - res, err := t.trie.Get(t.hashKey(address.Bytes())) - if res == nil || err != nil { - return nil, err - } - ret := new(types.StateAccount) - err = rlp.DecodeBytes(res, ret) - return ret, err -} - -// GetAccountByHash does the same thing as GetAccount, however it expects an -// account hash that is the hash of address. This constitutes an abstraction -// leak, since the client code needs to know the key format. -func (t *StateTrie) GetAccountByHash(addrHash common.Hash) (*types.StateAccount, error) { - res, err := t.trie.Get(addrHash.Bytes()) - if res == nil || err != nil { - return nil, err - } - ret := new(types.StateAccount) - err = rlp.DecodeBytes(res, ret) - return ret, err -} - -// GetNode attempts to retrieve a trie node by compact-encoded path. It is not -// possible to use keybyte-encoding as the path might contain odd nibbles. -// If the specified trie node is not in the trie, nil will be returned. -// If a trie node is not found in the database, a MissingNodeError is returned. -func (t *StateTrie) GetNode(path []byte) ([]byte, int, error) { - return t.trie.GetNode(path) -} - -// MustUpdate associates key with value in the trie. Subsequent calls to -// Get will return value. If value has length zero, any existing value -// is deleted from the trie and calls to Get will return nil. -// -// The value bytes must not be modified by the caller while they are -// stored in the trie. -// -// This function will omit any encountered error but just print out an -// error message. -func (t *StateTrie) MustUpdate(key, value []byte) { - hk := t.hashKey(key) - t.trie.MustUpdate(hk, value) - t.getSecKeyCache()[string(hk)] = common.CopyBytes(key) -} - -// UpdateStorage associates key with value in the trie. Subsequent calls to -// Get will return value. If value has length zero, any existing value -// is deleted from the trie and calls to Get will return nil. -// -// The value bytes must not be modified by the caller while they are -// stored in the trie. -// -// If a node is not found in the database, a MissingNodeError is returned. -func (t *StateTrie) UpdateStorage(_ common.Address, key, value []byte) error { - hk := t.hashKey(key) - v, _ := rlp.EncodeToBytes(value) - err := t.trie.Update(hk, v) - if err != nil { - return err - } - t.getSecKeyCache()[string(hk)] = common.CopyBytes(key) - return nil -} - -// UpdateAccount will abstract the write of an account to the secure trie. -func (t *StateTrie) UpdateAccount(address common.Address, acc *types.StateAccount) error { - hk := t.hashKey(address.Bytes()) - data, err := rlp.EncodeToBytes(acc) - if err != nil { - return err - } - if err := t.trie.Update(hk, data); err != nil { - return err - } - t.getSecKeyCache()[string(hk)] = address.Bytes() - return nil -} - -func (t *StateTrie) UpdateContractCode(_ common.Address, _ common.Hash, _ []byte) error { - return nil -} - -// MustDelete removes any existing value for key from the trie. This function -// will omit any encountered error but just print out an error message. -func (t *StateTrie) MustDelete(key []byte) { - hk := t.hashKey(key) - delete(t.getSecKeyCache(), string(hk)) - t.trie.MustDelete(hk) -} - -// DeleteStorage removes any existing storage slot from the trie. -// If the specified trie node is not in the trie, nothing will be changed. -// If a node is not found in the database, a MissingNodeError is returned. -func (t *StateTrie) DeleteStorage(_ common.Address, key []byte) error { - hk := t.hashKey(key) - delete(t.getSecKeyCache(), string(hk)) - return t.trie.Delete(hk) -} - -// DeleteAccount abstracts an account deletion from the trie. -func (t *StateTrie) DeleteAccount(address common.Address) error { - hk := t.hashKey(address.Bytes()) - delete(t.getSecKeyCache(), string(hk)) - return t.trie.Delete(hk) -} - -// GetKey returns the sha3 preimage of a hashed key that was -// previously used to store a value. -func (t *StateTrie) GetKey(shaKey []byte) []byte { - if key, ok := t.getSecKeyCache()[string(shaKey)]; ok { - return key - } - return t.db.Preimage(common.BytesToHash(shaKey)) -} - -// Commit collects all dirty nodes in the trie and replaces them with the -// corresponding node hash. All collected nodes (including dirty leaves if -// collectLeaf is true) will be encapsulated into a nodeset for return. -// The returned nodeset can be nil if the trie is clean (nothing to commit). -// All cached preimages will be also flushed if preimages recording is enabled. -// Once the trie is committed, it's not usable anymore. A new trie must -// be created with new root and updated trie database for following usage -func (t *StateTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { - // Write all the pre-images to the actual disk database - if len(t.getSecKeyCache()) > 0 { - preimages := make(map[common.Hash][]byte) - for hk, key := range t.secKeyCache { - preimages[common.BytesToHash([]byte(hk))] = key - } - t.db.InsertPreimage(preimages) - t.secKeyCache = make(map[string][]byte) - } - // Commit the trie and return its modified nodeset. - return t.trie.Commit(collectLeaf) -} - -// Hash returns the root hash of StateTrie. It does not write to the -// database and can be used even if the trie doesn't have one. -func (t *StateTrie) Hash() common.Hash { - return t.trie.Hash() -} - -// Copy returns a copy of StateTrie. -func (t *StateTrie) Copy() *StateTrie { - return &StateTrie{ - trie: *t.trie.Copy(), - db: t.db, - secKeyCache: t.secKeyCache, - } -} - -// NodeIterator returns an iterator that returns nodes of the underlying trie. -// Iteration starts at the key after the given start key. -func (t *StateTrie) NodeIterator(start []byte) (NodeIterator, error) { - return t.trie.NodeIterator(start) -} - -// MustNodeIterator is a wrapper of NodeIterator and will omit any encountered -// error but just print out an error message. -func (t *StateTrie) MustNodeIterator(start []byte) NodeIterator { - return t.trie.MustNodeIterator(start) -} - -// hashKey returns the hash of key as an ephemeral buffer. -// The caller must not hold onto the return value because it will become -// invalid on the next call to hashKey or secKey. -func (t *StateTrie) hashKey(key []byte) []byte { - h := newHasher(false) - h.sha.Reset() - h.sha.Write(key) - h.sha.Read(t.hashKeyBuf[:]) - returnHasherToPool(h) - return t.hashKeyBuf[:] -} - -// getSecKeyCache returns the current secure key cache, creating a new one if -// ownership changed (i.e. the current secure trie is a copy of another owning -// the actual cache). -func (t *StateTrie) getSecKeyCache() map[string][]byte { - if t != t.secKeyCacheOwner { - t.secKeyCacheOwner = t - t.secKeyCache = make(map[string][]byte) - } - return t.secKeyCache -} diff --git a/trie/secure_trie_test.go b/trie/secure_trie_test.go deleted file mode 100644 index 440910b89b..0000000000 --- a/trie/secure_trie_test.go +++ /dev/null @@ -1,159 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "fmt" - "runtime" - "sync" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -func newEmptySecure() *StateTrie { - trie, _ := NewStateTrie(TrieID(types.EmptyRootHash), newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - return trie -} - -// makeTestStateTrie creates a large enough secure trie for testing. -func makeTestStateTrie() (*testDb, *StateTrie, map[string][]byte) { - // Create an empty trie - triedb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie, _ := NewStateTrie(TrieID(types.EmptyRootHash), triedb) - - // Fill it with some arbitrary data - content := make(map[string][]byte) - for i := byte(0); i < 255; i++ { - // Map the same data under multiple keys - key, val := common.LeftPadBytes([]byte{1, i}, 32), []byte{i} - content[string(key)] = val - trie.MustUpdate(key, val) - - key, val = common.LeftPadBytes([]byte{2, i}, 32), []byte{i} - content[string(key)] = val - trie.MustUpdate(key, val) - - // Add some other data to inflate the trie - for j := byte(3); j < 13; j++ { - key, val = common.LeftPadBytes([]byte{j, i}, 32), []byte{j, i} - content[string(key)] = val - trie.MustUpdate(key, val) - } - } - root, nodes, _ := trie.Commit(false) - if err := triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)); err != nil { - panic(fmt.Errorf("failed to commit db %v", err)) - } - // Re-create the trie based on the new state - trie, _ = NewStateTrie(TrieID(root), triedb) - return triedb, trie, content -} - -func TestSecureDelete(t *testing.T) { - trie := newEmptySecure() - vals := []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - {"shaman", "horse"}, - {"doge", "coin"}, - {"ether", ""}, - {"dog", "puppy"}, - {"shaman", ""}, - } - for _, val := range vals { - if val.v != "" { - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } else { - trie.MustDelete([]byte(val.k)) - } - } - hash := trie.Hash() - exp := common.HexToHash("29b235a58c3c25ab83010c327d5932bcf05324b7d6b1185e650798034783ca9d") - if hash != exp { - t.Errorf("expected %x got %x", exp, hash) - } -} - -func TestSecureGetKey(t *testing.T) { - trie := newEmptySecure() - trie.MustUpdate([]byte("foo"), []byte("bar")) - - key := []byte("foo") - value := []byte("bar") - seckey := crypto.Keccak256(key) - - if !bytes.Equal(trie.MustGet(key), value) { - t.Errorf("Get did not return bar") - } - if k := trie.GetKey(seckey); !bytes.Equal(k, key) { - t.Errorf("GetKey returned %q, want %q", k, key) - } -} - -func TestStateTrieConcurrency(t *testing.T) { - // Create an initial trie and copy if for concurrent access - _, trie, _ := makeTestStateTrie() - - threads := runtime.NumCPU() - tries := make([]*StateTrie, threads) - for i := 0; i < threads; i++ { - tries[i] = trie.Copy() - } - // Start a batch of goroutines interacting with the trie - pend := new(sync.WaitGroup) - pend.Add(threads) - for i := 0; i < threads; i++ { - go func(index int) { - defer pend.Done() - - for j := byte(0); j < 255; j++ { - // Map the same data under multiple keys - key, val := common.LeftPadBytes([]byte{byte(index), 1, j}, 32), []byte{j} - tries[index].MustUpdate(key, val) - - key, val = common.LeftPadBytes([]byte{byte(index), 2, j}, 32), []byte{j} - tries[index].MustUpdate(key, val) - - // Add some other data to inflate the trie - for k := byte(3); k < 13; k++ { - key, val = common.LeftPadBytes([]byte{byte(index), k, j}, 32), []byte{k, j} - tries[index].MustUpdate(key, val) - } - } - tries[index].Commit(false) - }(i) - } - // Wait for all threads to finish - pend.Wait() -} diff --git a/trie/stacktrie.go b/trie/stacktrie.go deleted file mode 100644 index 7321c4bff9..0000000000 --- a/trie/stacktrie.go +++ /dev/null @@ -1,489 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "errors" - "sync" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" -) - -var ( - stPool = sync.Pool{New: func() any { return new(stNode) }} - _ = types.TrieHasher((*StackTrie)(nil)) -) - -// StackTrieOptions contains the configured options for manipulating the stackTrie. -type StackTrieOptions struct { - Writer func(path []byte, hash common.Hash, blob []byte) // The function to commit the dirty nodes - Cleaner func(path []byte) // The function to clean up dangling nodes - - SkipLeftBoundary bool // Flag whether the nodes on the left boundary are skipped for committing - SkipRightBoundary bool // Flag whether the nodes on the right boundary are skipped for committing - boundaryGauge metrics.Gauge // Gauge to track how many boundary nodes are met -} - -// NewStackTrieOptions initializes an empty options for stackTrie. -func NewStackTrieOptions() *StackTrieOptions { return &StackTrieOptions{} } - -// WithWriter configures trie node writer within the options. -func (o *StackTrieOptions) WithWriter(writer func(path []byte, hash common.Hash, blob []byte)) *StackTrieOptions { - o.Writer = writer - return o -} - -// WithCleaner configures the cleaner in the option for removing dangling nodes. -func (o *StackTrieOptions) WithCleaner(cleaner func(path []byte)) *StackTrieOptions { - o.Cleaner = cleaner - return o -} - -// WithSkipBoundary configures whether the left and right boundary nodes are -// filtered for committing, along with a gauge metrics to track how many -// boundary nodes are met. -func (o *StackTrieOptions) WithSkipBoundary(skipLeft, skipRight bool, gauge metrics.Gauge) *StackTrieOptions { - o.SkipLeftBoundary = skipLeft - o.SkipRightBoundary = skipRight - o.boundaryGauge = gauge - return o -} - -// StackTrie is a trie implementation that expects keys to be inserted -// in order. Once it determines that a subtree will no longer be inserted -// into, it will hash it and free up the memory it uses. -type StackTrie struct { - options *StackTrieOptions - root *stNode - h *hasher - - first []byte // The (hex-encoded without terminator) key of first inserted entry, tracked as left boundary. - last []byte // The (hex-encoded without terminator) key of last inserted entry, tracked as right boundary. -} - -// NewStackTrie allocates and initializes an empty trie. -func NewStackTrie(options *StackTrieOptions) *StackTrie { - if options == nil { - options = NewStackTrieOptions() - } - return &StackTrie{ - options: options, - root: stPool.Get().(*stNode), - h: newHasher(false), - } -} - -// Update inserts a (key, value) pair into the stack trie. -func (t *StackTrie) Update(key, value []byte) error { - if len(value) == 0 { - return errors.New("trying to insert empty (deletion)") - } - k := keybytesToHex(key) - k = k[:len(k)-1] // chop the termination flag - if bytes.Compare(t.last, k) >= 0 { - return errors.New("non-ascending key order") - } - // track the first and last inserted entries. - if t.first == nil { - t.first = append([]byte{}, k...) - } - if t.last == nil { - t.last = append([]byte{}, k...) // allocate key slice - } else { - t.last = append(t.last[:0], k...) // reuse key slice - } - t.insert(t.root, k, value, nil) - return nil -} - -// MustUpdate is a wrapper of Update and will omit any encountered error but -// just print out an error message. -func (t *StackTrie) MustUpdate(key, value []byte) { - if err := t.Update(key, value); err != nil { - log.Error("Unhandled trie error in StackTrie.Update", "err", err) - } -} - -// Reset resets the stack trie object to empty state. -func (t *StackTrie) Reset() { - t.options = NewStackTrieOptions() - t.root = stPool.Get().(*stNode) - t.first = nil - t.last = nil -} - -// stNode represents a node within a StackTrie -type stNode struct { - typ uint8 // node type (as in branch, ext, leaf) - key []byte // key chunk covered by this (leaf|ext) node - val []byte // value contained by this node if it's a leaf - children [16]*stNode // list of children (for branch and exts) -} - -// newLeaf constructs a leaf node with provided node key and value. The key -// will be deep-copied in the function and safe to modify afterwards, but -// value is not. -func newLeaf(key, val []byte) *stNode { - st := stPool.Get().(*stNode) - st.typ = leafNode - st.key = append(st.key, key...) - st.val = val - return st -} - -// newExt constructs an extension node with provided node key and child. The -// key will be deep-copied in the function and safe to modify afterwards. -func newExt(key []byte, child *stNode) *stNode { - st := stPool.Get().(*stNode) - st.typ = extNode - st.key = append(st.key, key...) - st.children[0] = child - return st -} - -// List all values that stNode#nodeType can hold -const ( - emptyNode = iota - branchNode - extNode - leafNode - hashedNode -) - -func (n *stNode) reset() *stNode { - n.key = n.key[:0] - n.val = nil - for i := range n.children { - n.children[i] = nil - } - n.typ = emptyNode - return n -} - -// Helper function that, given a full key, determines the index -// at which the chunk pointed by st.keyOffset is different from -// the same chunk in the full key. -func (n *stNode) getDiffIndex(key []byte) int { - for idx, nibble := range n.key { - if nibble != key[idx] { - return idx - } - } - return len(n.key) -} - -// Helper function to that inserts a (key, value) pair into -// the trie. -func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { - switch st.typ { - case branchNode: /* Branch */ - idx := int(key[0]) - - // Unresolve elder siblings - for i := idx - 1; i >= 0; i-- { - if st.children[i] != nil { - if st.children[i].typ != hashedNode { - t.hash(st.children[i], append(path, byte(i))) - } - break - } - } - - // Add new child - if st.children[idx] == nil { - st.children[idx] = newLeaf(key[1:], value) - } else { - t.insert(st.children[idx], key[1:], value, append(path, key[0])) - } - - case extNode: /* Ext */ - // Compare both key chunks and see where they differ - diffidx := st.getDiffIndex(key) - - // Check if chunks are identical. If so, recurse into - // the child node. Otherwise, the key has to be split - // into 1) an optional common prefix, 2) the fullnode - // representing the two differing path, and 3) a leaf - // for each of the differentiated subtrees. - if diffidx == len(st.key) { - // Ext key and key segment are identical, recurse into - // the child node. - t.insert(st.children[0], key[diffidx:], value, append(path, key[:diffidx]...)) - return - } - // Save the original part. Depending if the break is - // at the extension's last byte or not, create an - // intermediate extension or use the extension's child - // node directly. - var n *stNode - if diffidx < len(st.key)-1 { - // Break on the non-last byte, insert an intermediate - // extension. The path prefix of the newly-inserted - // extension should also contain the different byte. - n = newExt(st.key[diffidx+1:], st.children[0]) - t.hash(n, append(path, st.key[:diffidx+1]...)) - } else { - // Break on the last byte, no need to insert - // an extension node: reuse the current node. - // The path prefix of the original part should - // still be same. - n = st.children[0] - t.hash(n, append(path, st.key...)) - } - var p *stNode - if diffidx == 0 { - // the break is on the first byte, so - // the current node is converted into - // a branch node. - st.children[0] = nil - p = st - st.typ = branchNode - } else { - // the common prefix is at least one byte - // long, insert a new intermediate branch - // node. - st.children[0] = stPool.Get().(*stNode) - st.children[0].typ = branchNode - p = st.children[0] - } - // Create a leaf for the inserted part - o := newLeaf(key[diffidx+1:], value) - - // Insert both child leaves where they belong: - origIdx := st.key[diffidx] - newIdx := key[diffidx] - p.children[origIdx] = n - p.children[newIdx] = o - st.key = st.key[:diffidx] - - case leafNode: /* Leaf */ - // Compare both key chunks and see where they differ - diffidx := st.getDiffIndex(key) - - // Overwriting a key isn't supported, which means that - // the current leaf is expected to be split into 1) an - // optional extension for the common prefix of these 2 - // keys, 2) a fullnode selecting the path on which the - // keys differ, and 3) one leaf for the differentiated - // component of each key. - if diffidx >= len(st.key) { - panic("Trying to insert into existing key") - } - - // Check if the split occurs at the first nibble of the - // chunk. In that case, no prefix extnode is necessary. - // Otherwise, create that - var p *stNode - if diffidx == 0 { - // Convert current leaf into a branch - st.typ = branchNode - p = st - st.children[0] = nil - } else { - // Convert current node into an ext, - // and insert a child branch node. - st.typ = extNode - st.children[0] = stPool.Get().(*stNode) - st.children[0].typ = branchNode - p = st.children[0] - } - - // Create the two child leaves: one containing the original - // value and another containing the new value. The child leaf - // is hashed directly in order to free up some memory. - origIdx := st.key[diffidx] - p.children[origIdx] = newLeaf(st.key[diffidx+1:], st.val) - t.hash(p.children[origIdx], append(path, st.key[:diffidx+1]...)) - - newIdx := key[diffidx] - p.children[newIdx] = newLeaf(key[diffidx+1:], value) - - // Finally, cut off the key part that has been passed - // over to the children. - st.key = st.key[:diffidx] - st.val = nil - - case emptyNode: /* Empty */ - st.typ = leafNode - st.key = key - st.val = value - - case hashedNode: - panic("trying to insert into hash") - - default: - panic("invalid type") - } -} - -// hash converts st into a 'hashedNode', if possible. Possible outcomes: -// -// 1. The rlp-encoded value was >= 32 bytes: -// - Then the 32-byte `hash` will be accessible in `st.val`. -// - And the 'st.type' will be 'hashedNode' -// -// 2. The rlp-encoded value was < 32 bytes -// - Then the <32 byte rlp-encoded value will be accessible in 'st.val'. -// - And the 'st.type' will be 'hashedNode' AGAIN -// -// This method also sets 'st.type' to hashedNode, and clears 'st.key'. -func (t *StackTrie) hash(st *stNode, path []byte) { - var ( - blob []byte // RLP-encoded node blob - internal [][]byte // List of node paths covered by the extension node - ) - switch st.typ { - case hashedNode: - return - - case emptyNode: - st.val = types.EmptyRootHash.Bytes() - st.key = st.key[:0] - st.typ = hashedNode - return - - case branchNode: - var nodes fullNode - for i, child := range st.children { - if child == nil { - nodes.Children[i] = nilValueNode - continue - } - t.hash(child, append(path, byte(i))) - - if len(child.val) < 32 { - nodes.Children[i] = rawNode(child.val) - } else { - nodes.Children[i] = hashNode(child.val) - } - st.children[i] = nil - stPool.Put(child.reset()) // Release child back to pool. - } - nodes.encode(t.h.encbuf) - blob = t.h.encodedBytes() - - case extNode: - // recursively hash and commit child as the first step - t.hash(st.children[0], append(path, st.key...)) - - // Collect the path of internal nodes between shortNode and its **in disk** - // child. This is essential in the case of path mode scheme to avoid leaving - // danging nodes within the range of this internal path on disk, which would - // break the guarantee for state healing. - if len(st.children[0].val) >= 32 && t.options.Cleaner != nil { - for i := 1; i < len(st.key); i++ { - internal = append(internal, append(path, st.key[:i]...)) - } - } - // encode the extension node - n := shortNode{Key: hexToCompactInPlace(st.key)} - if len(st.children[0].val) < 32 { - n.Val = rawNode(st.children[0].val) - } else { - n.Val = hashNode(st.children[0].val) - } - n.encode(t.h.encbuf) - blob = t.h.encodedBytes() - - stPool.Put(st.children[0].reset()) // Release child back to pool. - st.children[0] = nil - - case leafNode: - st.key = append(st.key, byte(16)) - n := shortNode{Key: hexToCompactInPlace(st.key), Val: valueNode(st.val)} - - n.encode(t.h.encbuf) - blob = t.h.encodedBytes() - - default: - panic("invalid node type") - } - - st.typ = hashedNode - st.key = st.key[:0] - - // Skip committing the non-root node if the size is smaller than 32 bytes. - if len(blob) < 32 && len(path) > 0 { - st.val = common.CopyBytes(blob) - return - } - // Write the hash to the 'val'. We allocate a new val here to not mutate - // input values. - st.val = t.h.hashData(blob) - - // Short circuit if the stack trie is not configured for writing. - if t.options.Writer == nil { - return - } - // Skip committing if the node is on the left boundary and stackTrie is - // configured to filter the boundary. - if t.options.SkipLeftBoundary && bytes.HasPrefix(t.first, path) { - if t.options.boundaryGauge != nil { - t.options.boundaryGauge.Inc(1) - } - return - } - // Skip committing if the node is on the right boundary and stackTrie is - // configured to filter the boundary. - if t.options.SkipRightBoundary && bytes.HasPrefix(t.last, path) { - if t.options.boundaryGauge != nil { - t.options.boundaryGauge.Inc(1) - } - return - } - // Clean up the internal dangling nodes covered by the extension node. - // This should be done before writing the node to adhere to the committing - // order from bottom to top. - for _, path := range internal { - t.options.Cleaner(path) - } - t.options.Writer(path, common.BytesToHash(st.val), blob) -} - -// Hash will firstly hash the entire trie if it's still not hashed and then commit -// all nodes to the associated database. Actually most of the trie nodes have been -// committed already. The main purpose here is to commit the nodes on right boundary. -// -// For stack trie, Hash and Commit are functionally identical. -func (t *StackTrie) Hash() common.Hash { - n := t.root - t.hash(n, nil) - return common.BytesToHash(n.val) -} - -// Commit will firstly hash the entire trie if it's still not hashed and then commit -// all nodes to the associated database. Actually most of the trie nodes have been -// committed already. The main purpose here is to commit the nodes on right boundary. -// -// For stack trie, Hash and Commit are functionally identical. -func (t *StackTrie) Commit() common.Hash { - return t.Hash() -} diff --git a/trie/stacktrie_fuzzer_test.go b/trie/stacktrie_fuzzer_test.go deleted file mode 100644 index ec5006df8f..0000000000 --- a/trie/stacktrie_fuzzer_test.go +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "encoding/binary" - "fmt" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "golang.org/x/crypto/sha3" - "golang.org/x/exp/slices" -) - -func FuzzStackTrie(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - fuzz(data, false) - }) -} - -func fuzz(data []byte, debugging bool) { - // This spongeDb is used to check the sequence of disk-db-writes - var ( - input = bytes.NewReader(data) - spongeA = &spongeDb{sponge: sha3.NewLegacyKeccak256()} - dbA = newTestDatabase(rawdb.NewDatabase(spongeA), rawdb.HashScheme) - trieA = NewEmpty(dbA) - spongeB = &spongeDb{sponge: sha3.NewLegacyKeccak256()} - dbB = newTestDatabase(rawdb.NewDatabase(spongeB), rawdb.HashScheme) - - options = NewStackTrieOptions().WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(spongeB, common.Hash{}, path, hash, blob, dbB.Scheme()) - }) - trieB = NewStackTrie(options) - vals []*kv - maxElements = 10000 - // operate on unique keys only - keys = make(map[string]struct{}) - ) - // Fill the trie with elements - for i := 0; input.Len() > 0 && i < maxElements; i++ { - k := make([]byte, 32) - input.Read(k) - var a uint16 - binary.Read(input, binary.LittleEndian, &a) - a = 1 + a%100 - v := make([]byte, a) - input.Read(v) - if input.Len() == 0 { - // If it was exhausted while reading, the value may be all zeroes, - // thus 'deletion' which is not supported on stacktrie - break - } - if _, present := keys[string(k)]; present { - // This key is a duplicate, ignore it - continue - } - keys[string(k)] = struct{}{} - vals = append(vals, &kv{k: k, v: v}) - trieA.MustUpdate(k, v) - } - if len(vals) == 0 { - return - } - // Flush trie -> database - rootA, nodes, err := trieA.Commit(false) - if err != nil { - panic(err) - } - if nodes != nil { - dbA.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - } - // Flush memdb -> disk (sponge) - dbA.Commit(rootA) - - // Stacktrie requires sorted insertion - slices.SortFunc(vals, (*kv).cmp) - - for _, kv := range vals { - if debugging { - fmt.Printf("{\"%#x\" , \"%#x\"} // stacktrie.Update\n", kv.k, kv.v) - } - trieB.MustUpdate(kv.k, kv.v) - } - rootB := trieB.Hash() - trieB.Commit() - if rootA != rootB { - panic(fmt.Sprintf("roots differ: (trie) %x != %x (stacktrie)", rootA, rootB)) - } - sumA := spongeA.sponge.Sum(nil) - sumB := spongeB.sponge.Sum(nil) - if !bytes.Equal(sumA, sumB) { - panic(fmt.Sprintf("sequence differ: (trie) %x != %x (stacktrie)", sumA, sumB)) - } - - // Ensure all the nodes are persisted correctly - var ( - nodeset = make(map[string][]byte) // path -> blob - optionsC = NewStackTrieOptions().WithWriter(func(path []byte, hash common.Hash, blob []byte) { - if crypto.Keccak256Hash(blob) != hash { - panic("invalid node blob") - } - nodeset[string(path)] = common.CopyBytes(blob) - }) - trieC = NewStackTrie(optionsC) - checked int - ) - for _, kv := range vals { - trieC.MustUpdate(kv.k, kv.v) - } - rootC := trieC.Commit() - if rootA != rootC { - panic(fmt.Sprintf("roots differ: (trie) %x != %x (stacktrie)", rootA, rootC)) - } - trieA, _ = New(TrieID(rootA), dbA) - iterA := trieA.MustNodeIterator(nil) - for iterA.Next(true) { - if iterA.Hash() == (common.Hash{}) { - if _, present := nodeset[string(iterA.Path())]; present { - panic("unexpected tiny node") - } - continue - } - nodeBlob, present := nodeset[string(iterA.Path())] - if !present { - panic("missing node") - } - if !bytes.Equal(nodeBlob, iterA.NodeBlob()) { - panic("node blob is not matched") - } - checked += 1 - } - if checked != len(nodeset) { - panic("node number is not matched") - } -} diff --git a/trie/stacktrie_test.go b/trie/stacktrie_test.go deleted file mode 100644 index b68f6e1b2c..0000000000 --- a/trie/stacktrie_test.go +++ /dev/null @@ -1,497 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2020 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "math/big" - "math/rand" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/trie/testutil" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/stretchr/testify/assert" - "golang.org/x/exp/slices" -) - -func TestStackTrieInsertAndHash(t *testing.T) { - type KeyValueHash struct { - K string // Hex string for key. - V string // Value, directly converted to bytes. - H string // Expected root hash after insert of (K, V) to an existing trie. - } - tests := [][]KeyValueHash{ - { // {0:0, 7:0, f:0} - {"00", "v_______________________0___0", "5cb26357b95bb9af08475be00243ceb68ade0b66b5cd816b0c18a18c612d2d21"}, - {"70", "v_______________________0___1", "8ff64309574f7a437a7ad1628e690eb7663cfde10676f8a904a8c8291dbc1603"}, - {"f0", "v_______________________0___2", "9e3a01bd8d43efb8e9d4b5506648150b8e3ed1caea596f84ee28e01a72635470"}, - }, - { // {1:0cc, e:{1:fc, e:fc}} - {"10cc", "v_______________________1___0", "233e9b257843f3dfdb1cce6676cdaf9e595ac96ee1b55031434d852bc7ac9185"}, - {"e1fc", "v_______________________1___1", "39c5e908ae83d0c78520c7c7bda0b3782daf594700e44546e93def8f049cca95"}, - {"eefc", "v_______________________1___2", "d789567559fd76fe5b7d9cc42f3750f942502ac1c7f2a466e2f690ec4b6c2a7c"}, - }, - { // {b:{a:ac, b:ac}, d:acc} - {"baac", "v_______________________2___0", "8be1c86ba7ec4c61e14c1a9b75055e0464c2633ae66a055a24e75450156a5d42"}, - {"bbac", "v_______________________2___1", "8495159b9895a7d88d973171d737c0aace6fe6ac02a4769fff1bc43bcccce4cc"}, - {"dacc", "v_______________________2___2", "9bcfc5b220a27328deb9dc6ee2e3d46c9ebc9c69e78acda1fa2c7040602c63ca"}, - }, - { // {0:0cccc, 2:456{0:0, 2:2} - {"00cccc", "v_______________________3___0", "e57dc2785b99ce9205080cb41b32ebea7ac3e158952b44c87d186e6d190a6530"}, - {"245600", "v_______________________3___1", "0335354adbd360a45c1871a842452287721b64b4234dfe08760b243523c998db"}, - {"245622", "v_______________________3___2", "9e6832db0dca2b5cf81c0e0727bfde6afc39d5de33e5720bccacc183c162104e"}, - }, - { // {1:4567{1:1c, 3:3c}, 3:0cccccc} - {"1456711c", "v_______________________4___0", "f2389e78d98fed99f3e63d6d1623c1d4d9e8c91cb1d585de81fbc7c0e60d3529"}, - {"1456733c", "v_______________________4___1", "101189b3fab852be97a0120c03d95eefcf984d3ed639f2328527de6def55a9c0"}, - {"30cccccc", "v_______________________4___2", "3780ce111f98d15751dfde1eb21080efc7d3914b429e5c84c64db637c55405b3"}, - }, - { // 8800{1:f, 2:e, 3:d} - {"88001f", "v_______________________5___0", "e817db50d84f341d443c6f6593cafda093fc85e773a762421d47daa6ac993bd5"}, - {"88002e", "v_______________________5___1", "d6e3e6047bdc110edd296a4d63c030aec451bee9d8075bc5a198eee8cda34f68"}, - {"88003d", "v_______________________5___2", "b6bdf8298c703342188e5f7f84921a402042d0e5fb059969dd53a6b6b1fb989e"}, - }, - { // 0{1:fc, 2:ec, 4:dc} - {"01fc", "v_______________________6___0", "693268f2ca80d32b015f61cd2c4dba5a47a6b52a14c34f8e6945fad684e7a0d5"}, - {"02ec", "v_______________________6___1", "e24ddd44469310c2b785a2044618874bf486d2f7822603a9b8dce58d6524d5de"}, - {"04dc", "v_______________________6___2", "33fc259629187bbe54b92f82f0cd8083b91a12e41a9456b84fc155321e334db7"}, - }, - { // f{0:fccc, f:ff{0:f, f:f}} - {"f0fccc", "v_______________________7___0", "b0966b5aa469a3e292bc5fcfa6c396ae7a657255eef552ea7e12f996de795b90"}, - {"ffff0f", "v_______________________7___1", "3b1ca154ec2a3d96d8d77bddef0abfe40a53a64eb03cecf78da9ec43799fa3d0"}, - {"ffffff", "v_______________________7___2", "e75463041f1be8252781be0ace579a44ea4387bf5b2739f4607af676f7719678"}, - }, - { // ff{0:f{0:f, f:f}, f:fcc} - {"ff0f0f", "v_______________________8___0", "0928af9b14718ec8262ab89df430f1e5fbf66fac0fed037aff2b6767ae8c8684"}, - {"ff0fff", "v_______________________8___1", "d870f4d3ce26b0bf86912810a1960693630c20a48ba56be0ad04bc3e9ddb01e6"}, - {"ffffcc", "v_______________________8___2", "4239f10dd9d9915ecf2e047d6a576bdc1733ed77a30830f1bf29deaf7d8e966f"}, - }, - { - {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, - {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, - {"123f", "x___________________________2", "1164d7299964e74ac40d761f9189b2a3987fae959800d0f7e29d3aaf3eae9e15"}, - }, - { - {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, - {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, - {"124a", "x___________________________2", "661a96a669869d76b7231380da0649d013301425fbea9d5c5fae6405aa31cfce"}, - }, - { - {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, - {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, - {"13aa", "x___________________________2", "6590120e1fd3ffd1a90e8de5bb10750b61079bb0776cca4414dd79a24e4d4356"}, - }, - { - {"123d", "x___________________________0", "fc453d88b6f128a77c448669710497380fa4588abbea9f78f4c20c80daa797d0"}, - {"123e", "x___________________________1", "5af48f2d8a9a015c1ff7fa8b8c7f6b676233bd320e8fb57fd7933622badd2cec"}, - {"2aaa", "x___________________________2", "f869b40e0c55eace1918332ef91563616fbf0755e2b946119679f7ef8e44b514"}, - }, - { - {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, - {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, - {"1234fa", "x___________________________2", "4f4e368ab367090d5bc3dbf25f7729f8bd60df84de309b4633a6b69ab66142c0"}, - }, - { - {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, - {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, - {"1235aa", "x___________________________2", "21840121d11a91ac8bbad9a5d06af902a5c8d56a47b85600ba813814b7bfcb9b"}, - }, - { - {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, - {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, - {"124aaa", "x___________________________2", "ea4040ddf6ae3fbd1524bdec19c0ab1581015996262006632027fa5cf21e441e"}, - }, - { - {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, - {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, - {"13aaaa", "x___________________________2", "e4beb66c67e44f2dd8ba36036e45a44ff68f8d52942472b1911a45f886a34507"}, - }, - { - {"1234da", "x___________________________0", "1c4b4462e9f56a80ca0f5d77c0d632c41b0102290930343cf1791e971a045a79"}, - {"1234ea", "x___________________________1", "2f502917f3ba7d328c21c8b45ee0f160652e68450332c166d4ad02d1afe31862"}, - {"2aaaaa", "x___________________________2", "5f5989b820ff5d76b7d49e77bb64f26602294f6c42a1a3becc669cd9e0dc8ec9"}, - }, - { - {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, - {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, - {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, - {"1234fa", "x___________________________3", "65bb3aafea8121111d693ffe34881c14d27b128fd113fa120961f251fe28428d"}, - }, - { - {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, - {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, - {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, - {"1235aa", "x___________________________3", "f670e4d2547c533c5f21e0045442e2ecb733f347ad6d29ef36e0f5ba31bb11a8"}, - }, - { - {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, - {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, - {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, - {"124aaa", "x___________________________3", "c17464123050a9a6f29b5574bb2f92f6d305c1794976b475b7fb0316b6335598"}, - }, - { - {"000000", "x___________________________0", "3b32b7af0bddc7940e7364ee18b5a59702c1825e469452c8483b9c4e0218b55a"}, - {"1234da", "x___________________________1", "3ab152a1285dca31945566f872c1cc2f17a770440eda32aeee46a5e91033dde2"}, - {"1234ea", "x___________________________2", "0cccc87f96ddef55563c1b3be3c64fff6a644333c3d9cd99852cb53b6412b9b8"}, - {"13aaaa", "x___________________________3", "aa8301be8cb52ea5cd249f5feb79fb4315ee8de2140c604033f4b3fff78f0105"}, - }, - { - {"0000", "x___________________________0", "cb8c09ad07ae882136f602b3f21f8733a9f5a78f1d2525a8d24d1c13258000b2"}, - {"123d", "x___________________________1", "8f09663deb02f08958136410dc48565e077f76bb6c9d8c84d35fc8913a657d31"}, - {"123e", "x___________________________2", "0d230561e398c579e09a9f7b69ceaf7d3970f5a436fdb28b68b7a37c5bdd6b80"}, - {"123f", "x___________________________3", "80f7bad1893ca57e3443bb3305a517723a74d3ba831bcaca22a170645eb7aafb"}, - }, - { - {"0000", "x___________________________0", "cb8c09ad07ae882136f602b3f21f8733a9f5a78f1d2525a8d24d1c13258000b2"}, - {"123d", "x___________________________1", "8f09663deb02f08958136410dc48565e077f76bb6c9d8c84d35fc8913a657d31"}, - {"123e", "x___________________________2", "0d230561e398c579e09a9f7b69ceaf7d3970f5a436fdb28b68b7a37c5bdd6b80"}, - {"124a", "x___________________________3", "383bc1bb4f019e6bc4da3751509ea709b58dd1ac46081670834bae072f3e9557"}, - }, - { - {"0000", "x___________________________0", "cb8c09ad07ae882136f602b3f21f8733a9f5a78f1d2525a8d24d1c13258000b2"}, - {"123d", "x___________________________1", "8f09663deb02f08958136410dc48565e077f76bb6c9d8c84d35fc8913a657d31"}, - {"123e", "x___________________________2", "0d230561e398c579e09a9f7b69ceaf7d3970f5a436fdb28b68b7a37c5bdd6b80"}, - {"13aa", "x___________________________3", "ff0dc70ce2e5db90ee42a4c2ad12139596b890e90eb4e16526ab38fa465b35cf"}, - }, - { // branch node with short values - {"01", "a", "b48605025f5f4b129d40a420e721aa7d504487f015fce85b96e52126365ef7dc"}, - {"80", "b", "2dc6b680daf74db067cb7aeaad73265ded93d96fce190fcbf64f498d475672ab"}, - {"ee", "c", "017dc705a54ac5328dd263fa1bae68d655310fb3e3f7b7bc57e9a43ddf99c4bf"}, - {"ff", "d", "bd5a3584d271d459bd4eb95247b2fc88656b3671b60c1125ffe7bc0b689470d0"}, - }, - { // ext node with short branch node, then becoming long - {"a0", "a", "a83e028cb1e4365935661a9fd36a5c65c30b9ab416eaa877424146ca2a69d088"}, - {"a1", "b", "f586a4639b07b01798ca65e05c253b75d51135ebfbf6f8d6e87c0435089e65f0"}, - {"a2", "c", "63e297c295c008e09a8d531e18d57f270b6bc403e23179b915429db948cd62e3"}, - {"a3", "d", "94a7b721535578e9381f1f4e4b6ec29f8bdc5f0458a30320684c562f5d47b4b5"}, - {"a4", "e", "4b7e66d1c81965cdbe8fab8295ef56bc57fefdc5733d4782d2f8baf630f083c6"}, - {"a5", "f", "2997e7b502198ce1783b5277faacf52b25844fb55a99b63e88bdbbafac573106"}, - {"a6", "g", "bee629dd27a40772b2e1a67ec6db270d26acdf8d3b674dfae27866ad6ae1f48b"}, - }, - { // branch node with short values, then long ones - {"a001", "v1", "b9cc982d995392b51e6787f1915f0b88efd4ad8b30f138da0a3e2242f2323e35"}, - {"b002", "v2", "a7b474bc77ef5097096fa0ee6298fdae8928c0bc3724e7311cd0fa9ed1942fc7"}, - {"c003", "v___________________________3", "dceb5bb7c92b0e348df988a8d9fc36b101397e38ebd405df55ba6ee5f14a264a"}, - {"d004", "v___________________________4", "36e60ecb86b9626165e1c6543c42ecbe4d83bca58e8e1124746961511fce362a"}, - }, - { // ext node to branch node with short values, then long ones - {"8002", "v1", "3258fcb3e9e7d7234ecd3b8d4743999e4ab3a21592565e0a5ca64c141e8620d9"}, - {"8004", "v2", "b6cb95b7024a83c17624a3c9bed09b4b5e8ed426f49f54b8ad13c39028b1e75a"}, - {"8008", "v___________________________3", "c769d82963abe6f0900bf69754738eeb2f84559777cfa87a44f54e1aab417871"}, - {"800d", "v___________________________4", "1cad1fdaab1a6fa95d7b780fd680030e423eb76669971368ba04797a8d9cdfc9"}, - }, - { // ext node with a child of size 31 (Y) and branch node with a child of size 31 (X) - {"000001", "ZZZZZZZZZ", "cef154b87c03c563408520ff9b26923c360cbc3ddb590c079bedeeb25a8c9c77"}, - {"000002", "Y", "2130735e600f612f6e657a32bd7be64ddcaec6512c5694844b19de713922895d"}, - {"000003", "XXXXXXXXXXXXXXXXXXXXXXXXXXXX", "962c0fffdeef7612a4f7bff1950d67e3e81c878e48b9ae45b3b374253b050bd8"}, - }, - } - for i, test := range tests { - // The StackTrie does not allow Insert(), Hash(), Insert(), ... - // so we will create new trie for every sequence length of inserts. - for l := 1; l <= len(test); l++ { - st := NewStackTrie(nil) - for j := 0; j < l; j++ { - kv := &test[j] - if err := st.Update(common.FromHex(kv.K), []byte(kv.V)); err != nil { - t.Fatal(err) - } - } - expected := common.HexToHash(test[l-1].H) - if h := st.Hash(); h != expected { - t.Errorf("%d(%d): root hash mismatch: %x, expected %x", i, l, h, expected) - } - } - } -} - -func TestSizeBug(t *testing.T) { - st := NewStackTrie(nil) - nt := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - - leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") - value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3") - - nt.Update(leaf, value) - st.Update(leaf, value) - - if nt.Hash() != st.Hash() { - t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) - } -} - -func TestEmptyBug(t *testing.T) { - st := NewStackTrie(nil) - nt := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - - //leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") - //value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3") - kvs := []struct { - K string - V string - }{ - {K: "405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", V: "9496f4ec2bf9dab484cac6be589e8417d84781be08"}, - {K: "40edb63a35fcf86c08022722aa3287cdd36440d671b4918131b2514795fefa9c", V: "01"}, - {K: "b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", V: "947a30f7736e48d6599356464ba4c150d8da0302ff"}, - {K: "c2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b", V: "02"}, - } - - for _, kv := range kvs { - nt.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - st.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - } - - if nt.Hash() != st.Hash() { - t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) - } -} - -func TestValLength56(t *testing.T) { - st := NewStackTrie(nil) - nt := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - - //leaf := common.FromHex("290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") - //value := common.FromHex("94cf40d0d2b44f2b66e07cace1372ca42b73cf21a3") - kvs := []struct { - K string - V string - }{ - {K: "405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", V: "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"}, - } - - for _, kv := range kvs { - nt.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - st.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - } - - if nt.Hash() != st.Hash() { - t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) - } -} - -// TestUpdateSmallNodes tests a case where the leaves are small (both key and value), -// which causes a lot of node-within-node. This case was found via fuzzing. -func TestUpdateSmallNodes(t *testing.T) { - st := NewStackTrie(nil) - nt := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - kvs := []struct { - K string - V string - }{ - {"63303030", "3041"}, // stacktrie.Update - {"65", "3000"}, // stacktrie.Update - } - for _, kv := range kvs { - nt.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - st.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - } - if nt.Hash() != st.Hash() { - t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) - } -} - -// TestUpdateVariableKeys contains a case which stacktrie fails: when keys of different -// sizes are used, and the second one has the same prefix as the first, then the -// stacktrie fails, since it's unable to 'expand' on an already added leaf. -// For all practical purposes, this is fine, since keys are fixed-size length -// in account and storage tries. -// -// The test is marked as 'skipped', and exists just to have the behaviour documented. -// This case was found via fuzzing. -func TestUpdateVariableKeys(t *testing.T) { - t.SkipNow() - st := NewStackTrie(nil) - nt := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - kvs := []struct { - K string - V string - }{ - {"0x33303534636532393561313031676174", "303030"}, - {"0x3330353463653239356131303167617430", "313131"}, - } - for _, kv := range kvs { - nt.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - st.Update(common.FromHex(kv.K), common.FromHex(kv.V)) - } - if nt.Hash() != st.Hash() { - t.Fatalf("error %x != %x", st.Hash(), nt.Hash()) - } -} - -// TestStacktrieNotModifyValues checks that inserting blobs of data into the -// stacktrie does not mutate the blobs -func TestStacktrieNotModifyValues(t *testing.T) { - st := NewStackTrie(nil) - { // Test a very small trie - // Give it the value as a slice with large backing alloc, - // so if the stacktrie tries to append, it won't have to realloc - value := make([]byte, 1, 100) - value[0] = 0x2 - want := common.CopyBytes(value) - st.Update([]byte{0x01}, value) - st.Hash() - if have := value; !bytes.Equal(have, want) { - t.Fatalf("tiny trie: have %#x want %#x", have, want) - } - st = NewStackTrie(nil) - } - // Test with a larger trie - keyB := big.NewInt(1) - keyDelta := big.NewInt(1) - var vals [][]byte - getValue := func(i int) []byte { - if i%2 == 0 { // large - return crypto.Keccak256(big.NewInt(int64(i)).Bytes()) - } else { //small - return big.NewInt(int64(i)).Bytes() - } - } - for i := 0; i < 1000; i++ { - key := common.BigToHash(keyB) - value := getValue(i) - st.Update(key.Bytes(), value) - vals = append(vals, value) - keyB = keyB.Add(keyB, keyDelta) - keyDelta.Add(keyDelta, common.Big1) - } - st.Hash() - for i := 0; i < 1000; i++ { - want := getValue(i) - - have := vals[i] - if !bytes.Equal(have, want) { - t.Fatalf("item %d, have %#x want %#x", i, have, want) - } - } -} - -func buildPartialTree(entries []*kv, t *testing.T) map[string]common.Hash { - var ( - options = NewStackTrieOptions() - nodes = make(map[string]common.Hash) - ) - var ( - first int - last = len(entries) - 1 - - noLeft bool - noRight bool - ) - // Enter split mode if there are at least two elements - if rand.Intn(5) != 0 { - for { - first = rand.Intn(len(entries)) - last = rand.Intn(len(entries)) - if first <= last { - break - } - } - if first != 0 { - noLeft = true - } - if last != len(entries)-1 { - noRight = true - } - } - options = options.WithSkipBoundary(noLeft, noRight, nil) - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - nodes[string(path)] = hash - }) - tr := NewStackTrie(options) - - for i := first; i <= last; i++ { - tr.MustUpdate(entries[i].k, entries[i].v) - } - tr.Commit() - return nodes -} - -func TestPartialStackTrie(t *testing.T) { - for round := 0; round < 100; round++ { - var ( - n = rand.Intn(100) + 1 - entries []*kv - ) - for i := 0; i < n; i++ { - var val []byte - if rand.Intn(3) == 0 { - val = testutil.RandBytes(3) - } else { - val = testutil.RandBytes(32) - } - entries = append(entries, &kv{ - k: testutil.RandBytes(32), - v: val, - }) - } - slices.SortFunc(entries, (*kv).cmp) - - var ( - nodes = make(map[string]common.Hash) - options = NewStackTrieOptions().WithWriter(func(path []byte, hash common.Hash, blob []byte) { - nodes[string(path)] = hash - }) - ) - tr := NewStackTrie(options) - - for i := 0; i < len(entries); i++ { - tr.MustUpdate(entries[i].k, entries[i].v) - } - tr.Commit() - - for j := 0; j < 100; j++ { - for path, hash := range buildPartialTree(entries, t) { - if nodes[path] != hash { - t.Errorf("%v, want %x, got %x", []byte(path), nodes[path], hash) - } - } - } - } -} - -func TestStackTrieErrors(t *testing.T) { - s := NewStackTrie(nil) - // Deletion - if err := s.Update(nil, nil); err == nil { - t.Fatal("expected error") - } - if err := s.Update(nil, []byte{}); err == nil { - t.Fatal("expected error") - } - if err := s.Update([]byte{0xa}, []byte{}); err == nil { - t.Fatal("expected error") - } - // Non-ascending keys (going backwards or repeating) - assert.Nil(t, s.Update([]byte{0xaa}, []byte{0xa})) - assert.NotNil(t, s.Update([]byte{0xaa}, []byte{0xa}), "repeat insert same key") - assert.NotNil(t, s.Update([]byte{0xaa}, []byte{0xb}), "repeat insert same key") - assert.Nil(t, s.Update([]byte{0xab}, []byte{0xa})) - assert.NotNil(t, s.Update([]byte{0x10}, []byte{0xb}), "out of order insert") - assert.NotNil(t, s.Update([]byte{0xaa}, []byte{0xb}), "repeat insert same key") -} diff --git a/trie/sync_test.go b/trie/sync_test.go deleted file mode 100644 index b11c69f754..0000000000 --- a/trie/sync_test.go +++ /dev/null @@ -1,97 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2015 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "fmt" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" -) - -// makeTestTrie create a sample test trie to test node-wise reconstruction. -func makeTestTrie(scheme string) (ethdb.Database, *testDb, *StateTrie, map[string][]byte) { - // Create an empty trie - db := rawdb.NewMemoryDatabase() - triedb := newTestDatabase(db, scheme) - trie, _ := NewStateTrie(TrieID(types.EmptyRootHash), triedb) - - // Fill it with some arbitrary data - content := make(map[string][]byte) - for i := byte(0); i < 255; i++ { - // Map the same data under multiple keys - key, val := common.LeftPadBytes([]byte{1, i}, 32), []byte{i} - content[string(key)] = val - trie.MustUpdate(key, val) - - key, val = common.LeftPadBytes([]byte{2, i}, 32), []byte{i} - content[string(key)] = val - trie.MustUpdate(key, val) - - // Add some other data to inflate the trie - for j := byte(3); j < 13; j++ { - key, val = common.LeftPadBytes([]byte{j, i}, 32), []byte{j, i} - content[string(key)] = val - trie.MustUpdate(key, val) - } - } - root, nodes, _ := trie.Commit(false) - if err := triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)); err != nil { - panic(fmt.Errorf("failed to commit db %v", err)) - } - if err := triedb.Commit(root); err != nil { - panic(err) - } - // Re-create the trie based on the new state - trie, _ = NewStateTrie(TrieID(root), triedb) - return db, triedb, trie, content -} - -// checkTrieConsistency checks that all nodes in a trie are indeed present. -func checkTrieConsistency(db ethdb.Database, scheme string, root common.Hash, rawTrie bool) error { - ndb := newTestDatabase(db, scheme) - var it NodeIterator - if rawTrie { - trie, err := New(TrieID(root), ndb) - if err != nil { - return nil // Consider a non existent state consistent - } - it = trie.MustNodeIterator(nil) - } else { - trie, err := NewStateTrie(TrieID(root), ndb) - if err != nil { - return nil // Consider a non existent state consistent - } - it = trie.MustNodeIterator(nil) - } - for it.Next(true) { - } - return it.Error() -} diff --git a/trie/testutil/utils.go b/trie/testutil/utils.go deleted file mode 100644 index 9f6e6fac87..0000000000 --- a/trie/testutil/utils.go +++ /dev/null @@ -1,71 +0,0 @@ -// (c) 2024, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package testutil - -import ( - crand "crypto/rand" - "encoding/binary" - mrand "math/rand" - - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -// Prng is a pseudo random number generator seeded by strong randomness. -// The randomness is printed on startup in order to make failures reproducible. -var prng = initRand() - -func initRand() *mrand.Rand { - var seed [8]byte - crand.Read(seed[:]) - rnd := mrand.New(mrand.NewSource(int64(binary.LittleEndian.Uint64(seed[:])))) - return rnd -} - -// RandBytes generates a random byte slice with specified length. -func RandBytes(n int) []byte { - r := make([]byte, n) - prng.Read(r) - return r -} - -// RandomHash generates a random blob of data and returns it as a hash. -func RandomHash() common.Hash { - return common.BytesToHash(RandBytes(common.HashLength)) -} - -// RandomAddress generates a random blob of data and returns it as an address. -func RandomAddress() common.Address { - return common.BytesToAddress(RandBytes(common.AddressLength)) -} - -// RandomNode generates a random node. -func RandomNode() *trienode.Node { - val := RandBytes(100) - return trienode.New(crypto.Keccak256Hash(val), val) -} diff --git a/trie/tracer.go b/trie/tracer.go deleted file mode 100644 index 5786af4d3e..0000000000 --- a/trie/tracer.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "github.com/ethereum/go-ethereum/common" -) - -// tracer tracks the changes of trie nodes. During the trie operations, -// some nodes can be deleted from the trie, while these deleted nodes -// won't be captured by trie.Hasher or trie.Committer. Thus, these deleted -// nodes won't be removed from the disk at all. Tracer is an auxiliary tool -// used to track all insert and delete operations of trie and capture all -// deleted nodes eventually. -// -// The changed nodes can be mainly divided into two categories: the leaf -// node and intermediate node. The former is inserted/deleted by callers -// while the latter is inserted/deleted in order to follow the rule of trie. -// This tool can track all of them no matter the node is embedded in its -// parent or not, but valueNode is never tracked. -// -// Besides, it's also used for recording the original value of the nodes -// when they are resolved from the disk. The pre-value of the nodes will -// be used to construct trie history in the future. -// -// Note tracer is not thread-safe, callers should be responsible for handling -// the concurrency issues by themselves. -type tracer struct { - inserts map[string]struct{} - deletes map[string]struct{} - accessList map[string][]byte -} - -// newTracer initializes the tracer for capturing trie changes. -func newTracer() *tracer { - return &tracer{ - inserts: make(map[string]struct{}), - deletes: make(map[string]struct{}), - accessList: make(map[string][]byte), - } -} - -// onRead tracks the newly loaded trie node and caches the rlp-encoded -// blob internally. Don't change the value outside of function since -// it's not deep-copied. -func (t *tracer) onRead(path []byte, val []byte) { - t.accessList[string(path)] = val -} - -// onInsert tracks the newly inserted trie node. If it's already -// in the deletion set (resurrected node), then just wipe it from -// the deletion set as it's "untouched". -func (t *tracer) onInsert(path []byte) { - if _, present := t.deletes[string(path)]; present { - delete(t.deletes, string(path)) - return - } - t.inserts[string(path)] = struct{}{} -} - -// onDelete tracks the newly deleted trie node. If it's already -// in the addition set, then just wipe it from the addition set -// as it's untouched. -func (t *tracer) onDelete(path []byte) { - if _, present := t.inserts[string(path)]; present { - delete(t.inserts, string(path)) - return - } - t.deletes[string(path)] = struct{}{} -} - -// reset clears the content tracked by tracer. -func (t *tracer) reset() { - t.inserts = make(map[string]struct{}) - t.deletes = make(map[string]struct{}) - t.accessList = make(map[string][]byte) -} - -// copy returns a deep copied tracer instance. -func (t *tracer) copy() *tracer { - var ( - inserts = make(map[string]struct{}) - deletes = make(map[string]struct{}) - accessList = make(map[string][]byte) - ) - for path := range t.inserts { - inserts[path] = struct{}{} - } - for path := range t.deletes { - deletes[path] = struct{}{} - } - for path, blob := range t.accessList { - accessList[path] = common.CopyBytes(blob) - } - return &tracer{ - inserts: inserts, - deletes: deletes, - accessList: accessList, - } -} - -// deletedNodes returns a list of node paths which are deleted from the trie. -func (t *tracer) deletedNodes() []string { - var paths []string - for path := range t.deletes { - // It's possible a few deleted nodes were embedded - // in their parent before, the deletions can be no - // effect by deleting nothing, filter them out. - _, ok := t.accessList[path] - if !ok { - continue - } - paths = append(paths, path) - } - return paths -} diff --git a/trie/tracer_test.go b/trie/tracer_test.go deleted file mode 100644 index 89460a5f03..0000000000 --- a/trie/tracer_test.go +++ /dev/null @@ -1,376 +0,0 @@ -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" -) - -var ( - tiny = []struct{ k, v string }{ - {"k1", "v1"}, - {"k2", "v2"}, - {"k3", "v3"}, - } - nonAligned = []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - {"shaman", "horse"}, - {"doge", "coin"}, - {"dog", "puppy"}, - {"somethingveryoddindeedthis is", "myothernodedata"}, - } - standard = []struct{ k, v string }{ - {string(randBytes(32)), "verb"}, - {string(randBytes(32)), "wookiedoo"}, - {string(randBytes(32)), "stallion"}, - {string(randBytes(32)), "horse"}, - {string(randBytes(32)), "coin"}, - {string(randBytes(32)), "puppy"}, - {string(randBytes(32)), "myothernodedata"}, - } -) - -func TestTrieTracer(t *testing.T) { - testTrieTracer(t, tiny) - testTrieTracer(t, nonAligned) - testTrieTracer(t, standard) -} - -// Tests if the trie diffs are tracked correctly. Tracer should capture -// all non-leaf dirty nodes, no matter the node is embedded or not. -func testTrieTracer(t *testing.T, vals []struct{ k, v string }) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie := NewEmpty(db) - - // Determine all new nodes are tracked - for _, val := range vals { - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - insertSet := copySet(trie.tracer.inserts) // copy before commit - deleteSet := copySet(trie.tracer.deletes) // copy before commit - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - - seen := setKeys(iterNodes(db, root)) - if !compareSet(insertSet, seen) { - t.Fatal("Unexpected insertion set") - } - if !compareSet(deleteSet, nil) { - t.Fatal("Unexpected deletion set") - } - - // Determine all deletions are tracked - trie, _ = New(TrieID(root), db) - for _, val := range vals { - trie.MustDelete([]byte(val.k)) - } - insertSet, deleteSet = copySet(trie.tracer.inserts), copySet(trie.tracer.deletes) - if !compareSet(insertSet, nil) { - t.Fatal("Unexpected insertion set") - } - if !compareSet(deleteSet, seen) { - t.Fatal("Unexpected deletion set") - } -} - -// Test that after inserting a new batch of nodes and deleting them immediately, -// the trie tracer should be cleared normally as no operation happened. -func TestTrieTracerNoop(t *testing.T) { - testTrieTracerNoop(t, tiny) - testTrieTracerNoop(t, nonAligned) - testTrieTracerNoop(t, standard) -} - -func testTrieTracerNoop(t *testing.T, vals []struct{ k, v string }) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie := NewEmpty(db) - for _, val := range vals { - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - for _, val := range vals { - trie.MustDelete([]byte(val.k)) - } - if len(trie.tracer.inserts) != 0 { - t.Fatal("Unexpected insertion set") - } - if len(trie.tracer.deletes) != 0 { - t.Fatal("Unexpected deletion set") - } -} - -// Tests if the accessList is correctly tracked. -func TestAccessList(t *testing.T) { - testAccessList(t, tiny) - testAccessList(t, nonAligned) - testAccessList(t, standard) -} - -func testAccessList(t *testing.T, vals []struct{ k, v string }) { - var ( - db = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie = NewEmpty(db) - orig = trie.Copy() - ) - // Create trie from scratch - for _, val := range vals { - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - - trie, _ = New(TrieID(root), db) - if err := verifyAccessList(orig, trie, nodes); err != nil { - t.Fatalf("Invalid accessList %v", err) - } - - // Update trie - parent := root - trie, _ = New(TrieID(root), db) - orig = trie.Copy() - for _, val := range vals { - trie.MustUpdate([]byte(val.k), randBytes(32)) - } - root, nodes, _ = trie.Commit(false) - db.Update(root, parent, trienode.NewWithNodeSet(nodes)) - - trie, _ = New(TrieID(root), db) - if err := verifyAccessList(orig, trie, nodes); err != nil { - t.Fatalf("Invalid accessList %v", err) - } - - // Add more new nodes - parent = root - trie, _ = New(TrieID(root), db) - orig = trie.Copy() - var keys []string - for i := 0; i < 30; i++ { - key := randBytes(32) - keys = append(keys, string(key)) - trie.MustUpdate(key, randBytes(32)) - } - root, nodes, _ = trie.Commit(false) - db.Update(root, parent, trienode.NewWithNodeSet(nodes)) - - trie, _ = New(TrieID(root), db) - if err := verifyAccessList(orig, trie, nodes); err != nil { - t.Fatalf("Invalid accessList %v", err) - } - - // Partial deletions - parent = root - trie, _ = New(TrieID(root), db) - orig = trie.Copy() - for _, key := range keys { - trie.MustUpdate([]byte(key), nil) - } - root, nodes, _ = trie.Commit(false) - db.Update(root, parent, trienode.NewWithNodeSet(nodes)) - - trie, _ = New(TrieID(root), db) - if err := verifyAccessList(orig, trie, nodes); err != nil { - t.Fatalf("Invalid accessList %v", err) - } - - // Delete all - parent = root - trie, _ = New(TrieID(root), db) - orig = trie.Copy() - for _, val := range vals { - trie.MustUpdate([]byte(val.k), nil) - } - root, nodes, _ = trie.Commit(false) - db.Update(root, parent, trienode.NewWithNodeSet(nodes)) - - trie, _ = New(TrieID(root), db) - if err := verifyAccessList(orig, trie, nodes); err != nil { - t.Fatalf("Invalid accessList %v", err) - } -} - -// Tests origin values won't be tracked in Iterator or Prover -func TestAccessListLeak(t *testing.T) { - var ( - db = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie = NewEmpty(db) - ) - // Create trie from scratch - for _, val := range standard { - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - - var cases = []struct { - op func(tr *Trie) - }{ - { - func(tr *Trie) { - it := tr.MustNodeIterator(nil) - for it.Next(true) { - } - }, - }, - { - func(tr *Trie) { - it := NewIterator(tr.MustNodeIterator(nil)) - for it.Next() { - } - }, - }, - { - func(tr *Trie) { - for _, val := range standard { - tr.Prove([]byte(val.k), rawdb.NewMemoryDatabase()) - } - }, - }, - } - for _, c := range cases { - trie, _ = New(TrieID(root), db) - n1 := len(trie.tracer.accessList) - c.op(trie) - n2 := len(trie.tracer.accessList) - - if n1 != n2 { - t.Fatalf("AccessList is leaked, prev %d after %d", n1, n2) - } - } -} - -// Tests whether the original tree node is correctly deleted after being embedded -// in its parent due to the smaller size of the original tree node. -func TestTinyTree(t *testing.T) { - var ( - db = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie = NewEmpty(db) - ) - for _, val := range tiny { - trie.MustUpdate([]byte(val.k), randBytes(32)) - } - root, set, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(set)) - - parent := root - trie, _ = New(TrieID(root), db) - orig := trie.Copy() - for _, val := range tiny { - trie.MustUpdate([]byte(val.k), []byte(val.v)) - } - root, set, _ = trie.Commit(false) - db.Update(root, parent, trienode.NewWithNodeSet(set)) - - trie, _ = New(TrieID(root), db) - if err := verifyAccessList(orig, trie, set); err != nil { - t.Fatalf("Invalid accessList %v", err) - } -} - -func compareSet(setA, setB map[string]struct{}) bool { - if len(setA) != len(setB) { - return false - } - for key := range setA { - if _, ok := setB[key]; !ok { - return false - } - } - return true -} - -func forNodes(tr *Trie) map[string][]byte { - var ( - it = tr.MustNodeIterator(nil) - nodes = make(map[string][]byte) - ) - for it.Next(true) { - if it.Leaf() { - continue - } - nodes[string(it.Path())] = common.CopyBytes(it.NodeBlob()) - } - return nodes -} - -func iterNodes(db *testDb, root common.Hash) map[string][]byte { - tr, _ := New(TrieID(root), db) - return forNodes(tr) -} - -func forHashedNodes(tr *Trie) map[string][]byte { - var ( - it = tr.MustNodeIterator(nil) - nodes = make(map[string][]byte) - ) - for it.Next(true) { - if it.Hash() == (common.Hash{}) { - continue - } - nodes[string(it.Path())] = common.CopyBytes(it.NodeBlob()) - } - return nodes -} - -func diffTries(trieA, trieB *Trie) (map[string][]byte, map[string][]byte, map[string][]byte) { - var ( - nodesA = forHashedNodes(trieA) - nodesB = forHashedNodes(trieB) - inA = make(map[string][]byte) // hashed nodes in trie a but not b - inB = make(map[string][]byte) // hashed nodes in trie b but not a - both = make(map[string][]byte) // hashed nodes in both tries but different value - ) - for path, blobA := range nodesA { - if blobB, ok := nodesB[path]; ok { - if bytes.Equal(blobA, blobB) { - continue - } - both[path] = blobA - continue - } - inA[path] = blobA - } - for path, blobB := range nodesB { - if _, ok := nodesA[path]; ok { - continue - } - inB[path] = blobB - } - return inA, inB, both -} - -func setKeys(set map[string][]byte) map[string]struct{} { - keys := make(map[string]struct{}) - for k := range set { - keys[k] = struct{}{} - } - return keys -} - -func copySet(set map[string]struct{}) map[string]struct{} { - copied := make(map[string]struct{}) - for k := range set { - copied[k] = struct{}{} - } - return copied -} diff --git a/trie/trie.go b/trie/trie.go deleted file mode 100644 index f12a4d0f6e..0000000000 --- a/trie/trie.go +++ /dev/null @@ -1,683 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// Package trie implements Merkle Patricia Tries. -package trie - -import ( - "bytes" - "errors" - "fmt" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/triedb/database" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" -) - -// Trie is a Merkle Patricia Trie. Use New to create a trie that sits on -// top of a database. Whenever trie performs a commit operation, the generated -// nodes will be gathered and returned in a set. Once the trie is committed, -// it's not usable anymore. Callers have to re-create the trie with new root -// based on the updated trie database. -// -// Trie is not safe for concurrent use. -type Trie struct { - root node - owner common.Hash - - // Flag whether the commit operation is already performed. If so the - // trie is not usable(latest states is invisible). - committed bool - - // Keep track of the number leaves which have been inserted since the last - // hashing operation. This number will not directly map to the number of - // actually unhashed nodes. - unhashed int - - // reader is the handler trie can retrieve nodes from. - reader *trieReader - - // tracer is the tool to track the trie changes. - // It will be reset after each commit operation. - tracer *tracer -} - -// newFlag returns the cache flag value for a newly created node. -func (t *Trie) newFlag() nodeFlag { - return nodeFlag{dirty: true} -} - -// Copy returns a copy of Trie. -func (t *Trie) Copy() *Trie { - return &Trie{ - root: t.root, - owner: t.owner, - committed: t.committed, - unhashed: t.unhashed, - reader: t.reader, - tracer: t.tracer.copy(), - } -} - -// New creates the trie instance with provided trie id and the read-only -// database. The state specified by trie id must be available, otherwise -// an error will be returned. The trie root specified by trie id can be -// zero hash or the sha3 hash of an empty string, then trie is initially -// empty, otherwise, the root node must be present in database or returns -// a MissingNodeError if not. -func New(id *ID, db database.Database) (*Trie, error) { - reader, err := newTrieReader(id.StateRoot, id.Owner, db) - if err != nil { - return nil, err - } - trie := &Trie{ - owner: id.Owner, - reader: reader, - tracer: newTracer(), - } - if id.Root != (common.Hash{}) && id.Root != types.EmptyRootHash { - rootnode, err := trie.resolveAndTrack(id.Root[:], nil) - if err != nil { - return nil, err - } - trie.root = rootnode - } - return trie, nil -} - -// NewEmpty is a shortcut to create empty tree. It's mostly used in tests. -func NewEmpty(db database.Database) *Trie { - tr, _ := New(TrieID(types.EmptyRootHash), db) - return tr -} - -// MustNodeIterator is a wrapper of NodeIterator and will omit any encountered -// error but just print out an error message. -func (t *Trie) MustNodeIterator(start []byte) NodeIterator { - it, err := t.NodeIterator(start) - if err != nil { - log.Error("Unhandled trie error in Trie.NodeIterator", "err", err) - } - return it -} - -// NodeIterator returns an iterator that returns nodes of the trie. Iteration starts at -// the key after the given start key. -func (t *Trie) NodeIterator(start []byte) (NodeIterator, error) { - // Short circuit if the trie is already committed and not usable. - if t.committed { - return nil, ErrCommitted - } - return newNodeIterator(t, start), nil -} - -// MustGet is a wrapper of Get and will omit any encountered error but just -// print out an error message. -func (t *Trie) MustGet(key []byte) []byte { - res, err := t.Get(key) - if err != nil { - log.Error("Unhandled trie error in Trie.Get", "err", err) - } - return res -} - -// Get returns the value for key stored in the trie. -// The value bytes must not be modified by the caller. -// -// If the requested node is not present in trie, no error will be returned. -// If the trie is corrupted, a MissingNodeError is returned. -func (t *Trie) Get(key []byte) ([]byte, error) { - // Short circuit if the trie is already committed and not usable. - if t.committed { - return nil, ErrCommitted - } - value, newroot, didResolve, err := t.get(t.root, keybytesToHex(key), 0) - if err == nil && didResolve { - t.root = newroot - } - return value, err -} - -func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, newnode node, didResolve bool, err error) { - switch n := (origNode).(type) { - case nil: - return nil, nil, false, nil - case valueNode: - return n, n, false, nil - case *shortNode: - if len(key)-pos < len(n.Key) || !bytes.Equal(n.Key, key[pos:pos+len(n.Key)]) { - // key not found in trie - return nil, n, false, nil - } - value, newnode, didResolve, err = t.get(n.Val, key, pos+len(n.Key)) - if err == nil && didResolve { - n = n.copy() - n.Val = newnode - } - return value, n, didResolve, err - case *fullNode: - value, newnode, didResolve, err = t.get(n.Children[key[pos]], key, pos+1) - if err == nil && didResolve { - n = n.copy() - n.Children[key[pos]] = newnode - } - return value, n, didResolve, err - case hashNode: - child, err := t.resolveAndTrack(n, key[:pos]) - if err != nil { - return nil, n, true, err - } - value, newnode, _, err := t.get(child, key, pos) - return value, newnode, true, err - default: - panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode)) - } -} - -// MustGetNode is a wrapper of GetNode and will omit any encountered error but -// just print out an error message. -func (t *Trie) MustGetNode(path []byte) ([]byte, int) { - item, resolved, err := t.GetNode(path) - if err != nil { - log.Error("Unhandled trie error in Trie.GetNode", "err", err) - } - return item, resolved -} - -// GetNode retrieves a trie node by compact-encoded path. It is not possible -// to use keybyte-encoding as the path might contain odd nibbles. -// -// If the requested node is not present in trie, no error will be returned. -// If the trie is corrupted, a MissingNodeError is returned. -func (t *Trie) GetNode(path []byte) ([]byte, int, error) { - // Short circuit if the trie is already committed and not usable. - if t.committed { - return nil, 0, ErrCommitted - } - item, newroot, resolved, err := t.getNode(t.root, compactToHex(path), 0) - if err != nil { - return nil, resolved, err - } - if resolved > 0 { - t.root = newroot - } - if item == nil { - return nil, resolved, nil - } - return item, resolved, nil -} - -func (t *Trie) getNode(origNode node, path []byte, pos int) (item []byte, newnode node, resolved int, err error) { - // If non-existent path requested, abort - if origNode == nil { - return nil, nil, 0, nil - } - // If we reached the requested path, return the current node - if pos >= len(path) { - // Although we most probably have the original node expanded, encoding - // that into consensus form can be nasty (needs to cascade down) and - // time consuming. Instead, just pull the hash up from disk directly. - var hash hashNode - if node, ok := origNode.(hashNode); ok { - hash = node - } else { - hash, _ = origNode.cache() - } - if hash == nil { - return nil, origNode, 0, errors.New("non-consensus node") - } - blob, err := t.reader.node(path, common.BytesToHash(hash)) - return blob, origNode, 1, err - } - // Path still needs to be traversed, descend into children - switch n := (origNode).(type) { - case valueNode: - // Path prematurely ended, abort - return nil, nil, 0, nil - - case *shortNode: - if len(path)-pos < len(n.Key) || !bytes.Equal(n.Key, path[pos:pos+len(n.Key)]) { - // Path branches off from short node - return nil, n, 0, nil - } - item, newnode, resolved, err = t.getNode(n.Val, path, pos+len(n.Key)) - if err == nil && resolved > 0 { - n = n.copy() - n.Val = newnode - } - return item, n, resolved, err - - case *fullNode: - item, newnode, resolved, err = t.getNode(n.Children[path[pos]], path, pos+1) - if err == nil && resolved > 0 { - n = n.copy() - n.Children[path[pos]] = newnode - } - return item, n, resolved, err - - case hashNode: - child, err := t.resolveAndTrack(n, path[:pos]) - if err != nil { - return nil, n, 1, err - } - item, newnode, resolved, err := t.getNode(child, path, pos) - return item, newnode, resolved + 1, err - - default: - panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode)) - } -} - -// MustUpdate is a wrapper of Update and will omit any encountered error but -// just print out an error message. -func (t *Trie) MustUpdate(key, value []byte) { - if err := t.Update(key, value); err != nil { - log.Error("Unhandled trie error in Trie.Update", "err", err) - } -} - -// Update associates key with value in the trie. Subsequent calls to -// Get will return value. If value has length zero, any existing value -// is deleted from the trie and calls to Get will return nil. -// -// The value bytes must not be modified by the caller while they are -// stored in the trie. -// -// If the requested node is not present in trie, no error will be returned. -// If the trie is corrupted, a MissingNodeError is returned. -func (t *Trie) Update(key, value []byte) error { - // Short circuit if the trie is already committed and not usable. - if t.committed { - return ErrCommitted - } - return t.update(key, value) -} - -func (t *Trie) update(key, value []byte) error { - t.unhashed++ - k := keybytesToHex(key) - if len(value) != 0 { - _, n, err := t.insert(t.root, nil, k, valueNode(value)) - if err != nil { - return err - } - t.root = n - } else { - _, n, err := t.delete(t.root, nil, k) - if err != nil { - return err - } - t.root = n - } - return nil -} - -func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error) { - if len(key) == 0 { - if v, ok := n.(valueNode); ok { - return !bytes.Equal(v, value.(valueNode)), value, nil - } - return true, value, nil - } - switch n := n.(type) { - case *shortNode: - matchlen := prefixLen(key, n.Key) - // If the whole key matches, keep this short node as is - // and only update the value. - if matchlen == len(n.Key) { - dirty, nn, err := t.insert(n.Val, append(prefix, key[:matchlen]...), key[matchlen:], value) - if !dirty || err != nil { - return false, n, err - } - return true, &shortNode{n.Key, nn, t.newFlag()}, nil - } - // Otherwise branch out at the index where they differ. - branch := &fullNode{flags: t.newFlag()} - var err error - _, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val) - if err != nil { - return false, nil, err - } - _, branch.Children[key[matchlen]], err = t.insert(nil, append(prefix, key[:matchlen+1]...), key[matchlen+1:], value) - if err != nil { - return false, nil, err - } - // Replace this shortNode with the branch if it occurs at index 0. - if matchlen == 0 { - return true, branch, nil - } - // New branch node is created as a child of the original short node. - // Track the newly inserted node in the tracer. The node identifier - // passed is the path from the root node. - t.tracer.onInsert(append(prefix, key[:matchlen]...)) - - // Replace it with a short node leading up to the branch. - return true, &shortNode{key[:matchlen], branch, t.newFlag()}, nil - - case *fullNode: - dirty, nn, err := t.insert(n.Children[key[0]], append(prefix, key[0]), key[1:], value) - if !dirty || err != nil { - return false, n, err - } - n = n.copy() - n.flags = t.newFlag() - n.Children[key[0]] = nn - return true, n, nil - - case nil: - // New short node is created and track it in the tracer. The node identifier - // passed is the path from the root node. Note the valueNode won't be tracked - // since it's always embedded in its parent. - t.tracer.onInsert(prefix) - - return true, &shortNode{key, value, t.newFlag()}, nil - - case hashNode: - // We've hit a part of the trie that isn't loaded yet. Load - // the node and insert into it. This leaves all child nodes on - // the path to the value in the trie. - rn, err := t.resolveAndTrack(n, prefix) - if err != nil { - return false, nil, err - } - dirty, nn, err := t.insert(rn, prefix, key, value) - if !dirty || err != nil { - return false, rn, err - } - return true, nn, nil - - default: - panic(fmt.Sprintf("%T: invalid node: %v", n, n)) - } -} - -// MustDelete is a wrapper of Delete and will omit any encountered error but -// just print out an error message. -func (t *Trie) MustDelete(key []byte) { - if err := t.Delete(key); err != nil { - log.Error("Unhandled trie error in Trie.Delete", "err", err) - } -} - -// Delete removes any existing value for key from the trie. -// -// If the requested node is not present in trie, no error will be returned. -// If the trie is corrupted, a MissingNodeError is returned. -func (t *Trie) Delete(key []byte) error { - // Short circuit if the trie is already committed and not usable. - if t.committed { - return ErrCommitted - } - t.unhashed++ - k := keybytesToHex(key) - _, n, err := t.delete(t.root, nil, k) - if err != nil { - return err - } - t.root = n - return nil -} - -// delete returns the new root of the trie with key deleted. -// It reduces the trie to minimal form by simplifying -// nodes on the way up after deleting recursively. -func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { - switch n := n.(type) { - case *shortNode: - matchlen := prefixLen(key, n.Key) - if matchlen < len(n.Key) { - return false, n, nil // don't replace n on mismatch - } - if matchlen == len(key) { - // The matched short node is deleted entirely and track - // it in the deletion set. The same the valueNode doesn't - // need to be tracked at all since it's always embedded. - t.tracer.onDelete(prefix) - - return true, nil, nil // remove n entirely for whole matches - } - // The key is longer than n.Key. Remove the remaining suffix - // from the subtrie. Child can never be nil here since the - // subtrie must contain at least two other values with keys - // longer than n.Key. - dirty, child, err := t.delete(n.Val, append(prefix, key[:len(n.Key)]...), key[len(n.Key):]) - if !dirty || err != nil { - return false, n, err - } - switch child := child.(type) { - case *shortNode: - // The child shortNode is merged into its parent, track - // is deleted as well. - t.tracer.onDelete(append(prefix, n.Key...)) - - // Deleting from the subtrie reduced it to another - // short node. Merge the nodes to avoid creating a - // shortNode{..., shortNode{...}}. Use concat (which - // always creates a new slice) instead of append to - // avoid modifying n.Key since it might be shared with - // other nodes. - return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil - default: - return true, &shortNode{n.Key, child, t.newFlag()}, nil - } - - case *fullNode: - dirty, nn, err := t.delete(n.Children[key[0]], append(prefix, key[0]), key[1:]) - if !dirty || err != nil { - return false, n, err - } - n = n.copy() - n.flags = t.newFlag() - n.Children[key[0]] = nn - - // Because n is a full node, it must've contained at least two children - // before the delete operation. If the new child value is non-nil, n still - // has at least two children after the deletion, and cannot be reduced to - // a short node. - if nn != nil { - return true, n, nil - } - // Reduction: - // Check how many non-nil entries are left after deleting and - // reduce the full node to a short node if only one entry is - // left. Since n must've contained at least two children - // before deletion (otherwise it would not be a full node) n - // can never be reduced to nil. - // - // When the loop is done, pos contains the index of the single - // value that is left in n or -2 if n contains at least two - // values. - pos := -1 - for i, cld := range &n.Children { - if cld != nil { - if pos == -1 { - pos = i - } else { - pos = -2 - break - } - } - } - if pos >= 0 { - if pos != 16 { - // If the remaining entry is a short node, it replaces - // n and its key gets the missing nibble tacked to the - // front. This avoids creating an invalid - // shortNode{..., shortNode{...}}. Since the entry - // might not be loaded yet, resolve it just for this - // check. - cnode, err := t.resolve(n.Children[pos], append(prefix, byte(pos))) - if err != nil { - return false, nil, err - } - if cnode, ok := cnode.(*shortNode); ok { - // Replace the entire full node with the short node. - // Mark the original short node as deleted since the - // value is embedded into the parent now. - t.tracer.onDelete(append(prefix, byte(pos))) - - k := append([]byte{byte(pos)}, cnode.Key...) - return true, &shortNode{k, cnode.Val, t.newFlag()}, nil - } - } - // Otherwise, n is replaced by a one-nibble short node - // containing the child. - return true, &shortNode{[]byte{byte(pos)}, n.Children[pos], t.newFlag()}, nil - } - // n still contains at least two values and cannot be reduced. - return true, n, nil - - case valueNode: - return true, nil, nil - - case nil: - return false, nil, nil - - case hashNode: - // We've hit a part of the trie that isn't loaded yet. Load - // the node and delete from it. This leaves all child nodes on - // the path to the value in the trie. - rn, err := t.resolveAndTrack(n, prefix) - if err != nil { - return false, nil, err - } - dirty, nn, err := t.delete(rn, prefix, key) - if !dirty || err != nil { - return false, rn, err - } - return true, nn, nil - - default: - panic(fmt.Sprintf("%T: invalid node: %v (%v)", n, n, key)) - } -} - -func concat(s1 []byte, s2 ...byte) []byte { - r := make([]byte, len(s1)+len(s2)) - copy(r, s1) - copy(r[len(s1):], s2) - return r -} - -func (t *Trie) resolve(n node, prefix []byte) (node, error) { - if n, ok := n.(hashNode); ok { - return t.resolveAndTrack(n, prefix) - } - return n, nil -} - -// resolveAndTrack loads node from the underlying store with the given node hash -// and path prefix and also tracks the loaded node blob in tracer treated as the -// node's original value. The rlp-encoded blob is preferred to be loaded from -// database because it's easy to decode node while complex to encode node to blob. -func (t *Trie) resolveAndTrack(n hashNode, prefix []byte) (node, error) { - blob, err := t.reader.node(prefix, common.BytesToHash(n)) - if err != nil { - return nil, err - } - t.tracer.onRead(prefix, blob) - return mustDecodeNode(n, blob), nil -} - -// Hash returns the root hash of the trie. It does not write to the -// database and can be used even if the trie doesn't have one. -func (t *Trie) Hash() common.Hash { - hash, cached := t.hashRoot() - t.root = cached - return common.BytesToHash(hash.(hashNode)) -} - -// Commit collects all dirty nodes in the trie and replaces them with the -// corresponding node hash. All collected nodes (including dirty leaves if -// collectLeaf is true) will be encapsulated into a nodeset for return. -// The returned nodeset can be nil if the trie is clean (nothing to commit). -// Once the trie is committed, it's not usable anymore. A new trie must -// be created with new root and updated trie database for following usage -func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) { - defer t.tracer.reset() - defer func() { - t.committed = true - }() - // Trie is empty and can be classified into two types of situations: - // (a) The trie was empty and no update happens => return nil - // (b) The trie was non-empty and all nodes are dropped => return - // the node set includes all deleted nodes - if t.root == nil { - paths := t.tracer.deletedNodes() - if len(paths) == 0 { - return types.EmptyRootHash, nil, nil // case (a) - } - nodes := trienode.NewNodeSet(t.owner) - for _, path := range paths { - nodes.AddNode([]byte(path), trienode.NewDeleted()) - } - return types.EmptyRootHash, nodes, nil // case (b) - } - // Derive the hash for all dirty nodes first. We hold the assumption - // in the following procedure that all nodes are hashed. - rootHash := t.Hash() - - // Do a quick check if we really need to commit. This can happen e.g. - // if we load a trie for reading storage values, but don't write to it. - if hashedNode, dirty := t.root.cache(); !dirty { - // Replace the root node with the origin hash in order to - // ensure all resolved nodes are dropped after the commit. - t.root = hashedNode - return rootHash, nil, nil - } - nodes := trienode.NewNodeSet(t.owner) - for _, path := range t.tracer.deletedNodes() { - nodes.AddNode([]byte(path), trienode.NewDeleted()) - } - t.root = newCommitter(nodes, t.tracer, collectLeaf).Commit(t.root) - return rootHash, nodes, nil -} - -// hashRoot calculates the root hash of the given trie -func (t *Trie) hashRoot() (node, node) { - if t.root == nil { - return hashNode(types.EmptyRootHash.Bytes()), nil - } - // If the number of changes is below 100, we let one thread handle it - h := newHasher(t.unhashed >= 100) - defer func() { - returnHasherToPool(h) - t.unhashed = 0 - }() - hashed, cached := h.hash(t.root, true) - return hashed, cached -} - -// Reset drops the referenced root node and cleans all internal state. -func (t *Trie) Reset() { - t.root = nil - t.owner = common.Hash{} - t.unhashed = 0 - t.tracer.reset() - t.committed = false -} diff --git a/trie/trie_id.go b/trie/trie_id.go deleted file mode 100644 index b3ba417dcc..0000000000 --- a/trie/trie_id.go +++ /dev/null @@ -1,65 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see - -package trie - -import "github.com/ethereum/go-ethereum/common" - -// ID is the identifier for uniquely identifying a trie. -type ID struct { - StateRoot common.Hash // The root of the corresponding state(block.root) - Owner common.Hash // The contract address hash which the trie belongs to - Root common.Hash // The root hash of trie -} - -// StateTrieID constructs an identifier for state trie with the provided state root. -func StateTrieID(root common.Hash) *ID { - return &ID{ - StateRoot: root, - Owner: common.Hash{}, - Root: root, - } -} - -// StorageTrieID constructs an identifier for storage trie which belongs to a certain -// state and contract specified by the stateRoot and owner. -func StorageTrieID(stateRoot common.Hash, owner common.Hash, root common.Hash) *ID { - return &ID{ - StateRoot: stateRoot, - Owner: owner, - Root: root, - } -} - -// TrieID constructs an identifier for a standard trie(not a second-layer trie) -// with provided root. It's mostly used in tests and some other tries like CHT trie. -func TrieID(root common.Hash) *ID { - return &ID{ - StateRoot: root, - Owner: common.Hash{}, - Root: root, - } -} diff --git a/trie/trie_reader.go b/trie/trie_reader.go deleted file mode 100644 index 0b5e8a6cf9..0000000000 --- a/trie/trie_reader.go +++ /dev/null @@ -1,104 +0,0 @@ -// (c) 2023, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ava-labs/coreth/triedb/database" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" -) - -// trieReader is a wrapper of the underlying node reader. It's not safe -// for concurrent usage. -type trieReader struct { - owner common.Hash - reader database.Reader - banned map[string]struct{} // Marker to prevent node from being accessed, for tests -} - -// newTrieReader initializes the trie reader with the given node reader. -func newTrieReader(stateRoot, owner common.Hash, db database.Database) (*trieReader, error) { - if stateRoot == (common.Hash{}) || stateRoot == types.EmptyRootHash { - if stateRoot == (common.Hash{}) { - log.Error("Zero state root hash!") - } - return &trieReader{owner: owner}, nil - } - reader, err := db.Reader(stateRoot) - if err != nil { - return nil, &MissingNodeError{Owner: owner, NodeHash: stateRoot, err: err} - } - return &trieReader{owner: owner, reader: reader}, nil -} - -// newEmptyReader initializes the pure in-memory reader. All read operations -// should be forbidden and returns the MissingNodeError. -func newEmptyReader() *trieReader { - return &trieReader{} -} - -// node retrieves the rlp-encoded trie node with the provided trie node -// information. An MissingNodeError will be returned in case the node is -// not found or any error is encountered. -func (r *trieReader) node(path []byte, hash common.Hash) ([]byte, error) { - // Perform the logics in tests for preventing trie node access. - if r.banned != nil { - if _, ok := r.banned[string(path)]; ok { - return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path} - } - } - if r.reader == nil { - return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path} - } - blob, err := r.reader.Node(r.owner, path, hash) - if err != nil || len(blob) == 0 { - return nil, &MissingNodeError{Owner: r.owner, NodeHash: hash, Path: path, err: err} - } - return blob, nil -} - -// MerkleLoader implements triestate.TrieLoader for constructing tries. -type MerkleLoader struct { - db database.Database -} - -// NewMerkleLoader creates the merkle trie loader. -func NewMerkleLoader(db database.Database) *MerkleLoader { - return &MerkleLoader{db: db} -} - -// OpenTrie opens the main account trie. -func (l *MerkleLoader) OpenTrie(root common.Hash) (triestate.Trie, error) { - return New(TrieID(root), l.db) -} - -// OpenStorageTrie opens the storage trie of an account. -func (l *MerkleLoader) OpenStorageTrie(stateRoot common.Hash, addrHash, root common.Hash) (triestate.Trie, error) { - return New(StorageTrieID(stateRoot, addrHash, root), l.db) -} diff --git a/trie/trie_test.go b/trie/trie_test.go deleted file mode 100644 index 61014feb70..0000000000 --- a/trie/trie_test.go +++ /dev/null @@ -1,1224 +0,0 @@ -// (c) 2020-2021, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - "hash" - "io" - "math/rand" - "reflect" - "sort" - "testing" - "testing/quick" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/davecgh/go-spew/spew" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/rlp" - "github.com/holiman/uint256" - "github.com/stretchr/testify/require" - "golang.org/x/crypto/sha3" -) - -func init() { - spew.Config.Indent = " " - spew.Config.DisableMethods = false -} - -func TestEmptyTrie(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - res := trie.Hash() - exp := types.EmptyRootHash - if res != exp { - t.Errorf("expected %x got %x", exp, res) - } -} - -func TestNull(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - key := make([]byte, 32) - value := []byte("test") - trie.MustUpdate(key, value) - if !bytes.Equal(trie.MustGet(key), value) { - t.Fatal("wrong value") - } -} - -func TestMissingRoot(t *testing.T) { - testMissingRoot(t, rawdb.HashScheme) - testMissingRoot(t, rawdb.PathScheme) -} - -func testMissingRoot(t *testing.T, scheme string) { - root := common.HexToHash("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33") - trie, err := New(TrieID(root), newTestDatabase(rawdb.NewMemoryDatabase(), scheme)) - if trie != nil { - t.Error("New returned non-nil trie for invalid root") - } - if _, ok := err.(*MissingNodeError); !ok { - t.Errorf("New returned wrong error: %v", err) - } -} - -func TestMissingNode(t *testing.T) { - testMissingNode(t, false, rawdb.HashScheme) - testMissingNode(t, false, rawdb.PathScheme) - testMissingNode(t, true, rawdb.HashScheme) - testMissingNode(t, true, rawdb.PathScheme) -} - -func testMissingNode(t *testing.T, memonly bool, scheme string) { - diskdb := rawdb.NewMemoryDatabase() - triedb := newTestDatabase(diskdb, scheme) - - trie := NewEmpty(triedb) - updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer") - updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf") - root, nodes, _ := trie.Commit(false) - triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - - if !memonly { - require.NoError(t, triedb.Commit(root)) - } - - trie, _ = New(TrieID(root), triedb) - _, err := trie.Get([]byte("120000")) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - trie, _ = New(TrieID(root), triedb) - _, err = trie.Get([]byte("120099")) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - trie, _ = New(TrieID(root), triedb) - _, err = trie.Get([]byte("123456")) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - trie, _ = New(TrieID(root), triedb) - err = trie.Update([]byte("120099"), []byte("zxcvzxcvzxcvzxcvzxcvzxcvzxcvzxcv")) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - trie, _ = New(TrieID(root), triedb) - err = trie.Delete([]byte("123456")) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - - var ( - path []byte - hash = common.HexToHash("0xe1d943cc8f061a0c0b98162830b970395ac9315654824bf21b73b891365262f9") - ) - for p, n := range nodes.Nodes { - if n.Hash == hash { - path = common.CopyBytes([]byte(p)) - break - } - } - trie, _ = New(TrieID(root), triedb) - if memonly { - trie.reader.banned = map[string]struct{}{string(path): {}} - } else { - rawdb.DeleteTrieNode(diskdb, common.Hash{}, path, hash, scheme) - } - - _, err = trie.Get([]byte("120000")) - if _, ok := err.(*MissingNodeError); !ok { - t.Errorf("Wrong error: %v", err) - } - _, err = trie.Get([]byte("120099")) - if _, ok := err.(*MissingNodeError); !ok { - t.Errorf("Wrong error: %v", err) - } - _, err = trie.Get([]byte("123456")) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - err = trie.Update([]byte("120099"), []byte("zxcv")) - if _, ok := err.(*MissingNodeError); !ok { - t.Errorf("Wrong error: %v", err) - } - err = trie.Delete([]byte("123456")) - if _, ok := err.(*MissingNodeError); !ok { - t.Errorf("Wrong error: %v", err) - } -} - -func TestInsert(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - - updateString(trie, "doe", "reindeer") - updateString(trie, "dog", "puppy") - updateString(trie, "dogglesworth", "cat") - - exp := common.HexToHash("8aad789dff2f538bca5d8ea56e8abe10f4c7ba3a5dea95fea4cd6e7c3a1168d3") - root := trie.Hash() - if root != exp { - t.Errorf("case 1: exp %x got %x", exp, root) - } - - trie = NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - updateString(trie, "A", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") - - exp = common.HexToHash("d23786fb4a010da3ce639d66d5e904a11dbc02746d1ce25029e53290cabf28ab") - root, _, _ = trie.Commit(false) - if root != exp { - t.Errorf("case 2: exp %x got %x", exp, root) - } -} - -func TestGet(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie := NewEmpty(db) - updateString(trie, "doe", "reindeer") - updateString(trie, "dog", "puppy") - updateString(trie, "dogglesworth", "cat") - - for i := 0; i < 2; i++ { - res := getString(trie, "dog") - if !bytes.Equal(res, []byte("puppy")) { - t.Errorf("expected puppy got %x", res) - } - unknown := getString(trie, "unknown") - if unknown != nil { - t.Errorf("expected nil got %x", unknown) - } - if i == 1 { - return - } - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - trie, _ = New(TrieID(root), db) - } -} - -func TestDelete(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie := NewEmpty(db) - vals := []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - {"shaman", "horse"}, - {"doge", "coin"}, - {"ether", ""}, - {"dog", "puppy"}, - {"shaman", ""}, - } - for _, val := range vals { - if val.v != "" { - updateString(trie, val.k, val.v) - } else { - deleteString(trie, val.k) - } - } - - hash := trie.Hash() - exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84") - if hash != exp { - t.Errorf("expected %x got %x", exp, hash) - } -} - -func TestEmptyValues(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - - vals := []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - {"shaman", "horse"}, - {"doge", "coin"}, - {"ether", ""}, - {"dog", "puppy"}, - {"shaman", ""}, - } - for _, val := range vals { - updateString(trie, val.k, val.v) - } - - hash := trie.Hash() - exp := common.HexToHash("5991bb8c6514148a29db676a14ac506cd2cd5775ace63c30a4fe457715e9ac84") - if hash != exp { - t.Errorf("expected %x got %x", exp, hash) - } -} - -func TestReplication(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie := NewEmpty(db) - vals := []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - {"shaman", "horse"}, - {"doge", "coin"}, - {"dog", "puppy"}, - {"somethingveryoddindeedthis is", "myothernodedata"}, - } - for _, val := range vals { - updateString(trie, val.k, val.v) - } - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - - // create a new trie on top of the database and check that lookups work. - trie2, err := New(TrieID(root), db) - if err != nil { - t.Fatalf("can't recreate trie at %x: %v", root, err) - } - for _, kv := range vals { - if string(getString(trie2, kv.k)) != kv.v { - t.Errorf("trie2 doesn't have %q => %q", kv.k, kv.v) - } - } - hash, nodes, _ := trie2.Commit(false) - if hash != root { - t.Errorf("root failure. expected %x got %x", root, hash) - } - - // recreate the trie after commit - if nodes != nil { - db.Update(hash, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - } - trie2, err = New(TrieID(hash), db) - if err != nil { - t.Fatalf("can't recreate trie at %x: %v", hash, err) - } - // perform some insertions on the new trie. - vals2 := []struct{ k, v string }{ - {"do", "verb"}, - {"ether", "wookiedoo"}, - {"horse", "stallion"}, - // {"shaman", "horse"}, - // {"doge", "coin"}, - // {"ether", ""}, - // {"dog", "puppy"}, - // {"somethingveryoddindeedthis is", "myothernodedata"}, - // {"shaman", ""}, - } - for _, val := range vals2 { - updateString(trie2, val.k, val.v) - } - if trie2.Hash() != hash { - t.Errorf("root failure. expected %x got %x", hash, hash) - } -} - -func TestLargeValue(t *testing.T) { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - trie.MustUpdate([]byte("key1"), []byte{99, 99, 99, 99}) - trie.MustUpdate([]byte("key2"), bytes.Repeat([]byte{1}, 32)) - trie.Hash() -} - -// TestRandomCases tests some cases that were found via random fuzzing -func TestRandomCases(t *testing.T) { - var rt = []randTestStep{ - {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 0 - {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 1 - {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000002")}, // step 2 - {op: 2, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")}, // step 3 - {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 4 - {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 5 - {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 6 - {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 7 - {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000008")}, // step 8 - {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000009")}, // step 9 - {op: 2, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")}, // step 10 - {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 11 - {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 12 - {op: 0, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("000000000000000d")}, // step 13 - {op: 6, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 14 - {op: 1, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("")}, // step 15 - {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 16 - {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000011")}, // step 17 - {op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 18 - {op: 3, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 19 - {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000014")}, // step 20 - {op: 0, key: common.Hex2Bytes("d51b182b95d677e5f1c82508c0228de96b73092d78ce78b2230cd948674f66fd1483bd"), value: common.Hex2Bytes("0000000000000015")}, // step 21 - {op: 0, key: common.Hex2Bytes("c2a38512b83107d665c65235b0250002882ac2022eb00711552354832c5f1d030d0e408e"), value: common.Hex2Bytes("0000000000000016")}, // step 22 - {op: 5, key: common.Hex2Bytes(""), value: common.Hex2Bytes("")}, // step 23 - {op: 1, key: common.Hex2Bytes("980c393656413a15c8da01978ed9f89feb80b502f58f2d640e3a2f5f7a99a7018f1b573befd92053ac6f78fca4a87268"), value: common.Hex2Bytes("")}, // step 24 - {op: 1, key: common.Hex2Bytes("fd"), value: common.Hex2Bytes("")}, // step 25 - } - if err := runRandTest(rt); err != nil { - t.Fatal(err) - } -} - -// randTest performs random trie operations. -// Instances of this test are created by Generate. -type randTest []randTestStep - -// compile-time interface check -var _ quick.Generator = (randTest)(nil) - -type randTestStep struct { - op int - key []byte // for opUpdate, opDelete, opGet - value []byte // for opUpdate - err error // for debugging -} - -const ( - opUpdate = iota - opDelete - opGet - opHash - opCommit - opItercheckhash - opNodeDiff - opProve - opMax // boundary value, not an actual op -) - -func (randTest) Generate(r *rand.Rand, size int) reflect.Value { - var finishedFn = func() bool { - size-- - return size == 0 - } - return reflect.ValueOf(generateSteps(finishedFn, r)) -} - -func generateSteps(finished func() bool, r io.Reader) randTest { - var allKeys [][]byte - var one = []byte{0} - genKey := func() []byte { - r.Read(one) - if len(allKeys) < 2 || one[0]%100 > 90 { - // new key - size := one[0] % 50 - key := make([]byte, size) - r.Read(key) - allKeys = append(allKeys, key) - return key - } - // use existing key - idx := int(one[0]) % len(allKeys) - return allKeys[idx] - } - var steps randTest - for !finished() { - r.Read(one) - step := randTestStep{op: int(one[0]) % opMax} - switch step.op { - case opUpdate: - step.key = genKey() - step.value = make([]byte, 8) - binary.BigEndian.PutUint64(step.value, uint64(len(steps))) - case opGet, opDelete, opProve: - step.key = genKey() - } - steps = append(steps, step) - } - return steps -} - -func verifyAccessList(old *Trie, new *Trie, set *trienode.NodeSet) error { - deletes, inserts, updates := diffTries(old, new) - - // Check insertion set - for path := range inserts { - n, ok := set.Nodes[path] - if !ok || n.IsDeleted() { - return errors.New("expect new node") - } - //if len(n.Prev) > 0 { - // return errors.New("unexpected origin value") - //} - } - // Check deletion set - for path := range deletes { - n, ok := set.Nodes[path] - if !ok || !n.IsDeleted() { - return errors.New("expect deleted node") - } - //if len(n.Prev) == 0 { - // return errors.New("expect origin value") - //} - //if !bytes.Equal(n.Prev, blob) { - // return errors.New("invalid origin value") - //} - } - // Check update set - for path := range updates { - n, ok := set.Nodes[path] - if !ok || n.IsDeleted() { - return errors.New("expect updated node") - } - //if len(n.Prev) == 0 { - // return errors.New("expect origin value") - //} - //if !bytes.Equal(n.Prev, blob) { - // return errors.New("invalid origin value") - //} - } - return nil -} - -// runRandTestBool coerces error to boolean, for use in quick.Check -func runRandTestBool(rt randTest) bool { - return runRandTest(rt) == nil -} - -func runRandTest(rt randTest) error { - var scheme = rawdb.HashScheme - if rand.Intn(2) == 0 { - scheme = rawdb.PathScheme - } - var ( - origin = types.EmptyRootHash - triedb = newTestDatabase(rawdb.NewMemoryDatabase(), scheme) - tr = NewEmpty(triedb) - values = make(map[string]string) // tracks content of the trie - origTrie = NewEmpty(triedb) - ) - for i, step := range rt { - // fmt.Printf("{op: %d, key: common.Hex2Bytes(\"%x\"), value: common.Hex2Bytes(\"%x\")}, // step %d\n", - // step.op, step.key, step.value, i) - switch step.op { - case opUpdate: - tr.MustUpdate(step.key, step.value) - values[string(step.key)] = string(step.value) - case opDelete: - tr.MustDelete(step.key) - delete(values, string(step.key)) - case opGet: - v := tr.MustGet(step.key) - want := values[string(step.key)] - if string(v) != want { - rt[i].err = fmt.Errorf("mismatch for key %#x, got %#x want %#x", step.key, v, want) - } - case opProve: - hash := tr.Hash() - if hash == types.EmptyRootHash { - continue - } - proofDb := rawdb.NewMemoryDatabase() - err := tr.Prove(step.key, proofDb) - if err != nil { - rt[i].err = fmt.Errorf("failed for proving key %#x, %v", step.key, err) - } - _, err = VerifyProof(hash, step.key, proofDb) - if err != nil { - rt[i].err = fmt.Errorf("failed for verifying key %#x, %v", step.key, err) - } - case opHash: - tr.Hash() - case opCommit: - root, nodes, _ := tr.Commit(true) - if nodes != nil { - triedb.Update(root, origin, trienode.NewWithNodeSet(nodes)) - } - newtr, err := New(TrieID(root), triedb) - if err != nil { - rt[i].err = err - return err - } - if nodes != nil { - if err := verifyAccessList(origTrie, newtr, nodes); err != nil { - rt[i].err = err - return err - } - } - tr = newtr - origTrie = tr.Copy() - origin = root - case opItercheckhash: - checktr := NewEmpty(triedb) - it := NewIterator(tr.MustNodeIterator(nil)) - for it.Next() { - checktr.MustUpdate(it.Key, it.Value) - } - if tr.Hash() != checktr.Hash() { - rt[i].err = fmt.Errorf("hash mismatch in opItercheckhash") - } - case opNodeDiff: - var ( - origIter = origTrie.MustNodeIterator(nil) - curIter = tr.MustNodeIterator(nil) - origSeen = make(map[string]struct{}) - curSeen = make(map[string]struct{}) - ) - for origIter.Next(true) { - if origIter.Leaf() { - continue - } - origSeen[string(origIter.Path())] = struct{}{} - } - for curIter.Next(true) { - if curIter.Leaf() { - continue - } - curSeen[string(curIter.Path())] = struct{}{} - } - var ( - insertExp = make(map[string]struct{}) - deleteExp = make(map[string]struct{}) - ) - for path := range curSeen { - _, present := origSeen[path] - if !present { - insertExp[path] = struct{}{} - } - } - for path := range origSeen { - _, present := curSeen[path] - if !present { - deleteExp[path] = struct{}{} - } - } - if len(insertExp) != len(tr.tracer.inserts) { - rt[i].err = fmt.Errorf("insert set mismatch") - } - if len(deleteExp) != len(tr.tracer.deletes) { - rt[i].err = fmt.Errorf("delete set mismatch") - } - for insert := range tr.tracer.inserts { - if _, present := insertExp[insert]; !present { - rt[i].err = fmt.Errorf("missing inserted node") - } - } - for del := range tr.tracer.deletes { - if _, present := deleteExp[del]; !present { - rt[i].err = fmt.Errorf("missing deleted node") - } - } - } - // Abort the test on error. - if rt[i].err != nil { - return rt[i].err - } - } - return nil -} - -func TestRandom(t *testing.T) { - if err := quick.Check(runRandTestBool, nil); err != nil { - if cerr, ok := err.(*quick.CheckError); ok { - t.Fatalf("random test iteration %d failed: %s", cerr.Count, spew.Sdump(cerr.In)) - } - t.Fatal(err) - } -} - -func BenchmarkGet(b *testing.B) { benchGet(b) } -func BenchmarkUpdateBE(b *testing.B) { benchUpdate(b, binary.BigEndian) } -func BenchmarkUpdateLE(b *testing.B) { benchUpdate(b, binary.LittleEndian) } - -const benchElemCount = 20000 - -func benchGet(b *testing.B) { - triedb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) - trie := NewEmpty(triedb) - k := make([]byte, 32) - for i := 0; i < benchElemCount; i++ { - binary.LittleEndian.PutUint64(k, uint64(i)) - v := make([]byte, 32) - binary.LittleEndian.PutUint64(v, uint64(i)) - trie.MustUpdate(k, v) - } - binary.LittleEndian.PutUint64(k, benchElemCount/2) - - b.ResetTimer() - for i := 0; i < b.N; i++ { - trie.MustGet(k) - } - b.StopTimer() -} - -func benchUpdate(b *testing.B, e binary.ByteOrder) *Trie { - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - k := make([]byte, 32) - b.ReportAllocs() - for i := 0; i < b.N; i++ { - v := make([]byte, 32) - e.PutUint64(k, uint64(i)) - e.PutUint64(v, uint64(i)) - trie.MustUpdate(k, v) - } - return trie -} - -// Benchmarks the trie hashing. Since the trie caches the result of any operation, -// we cannot use b.N as the number of hashing rounds, since all rounds apart from -// the first one will be NOOP. As such, we'll use b.N as the number of account to -// insert into the trie before measuring the hashing. -// BenchmarkHash-6 288680 4561 ns/op 682 B/op 9 allocs/op -// BenchmarkHash-6 275095 4800 ns/op 685 B/op 9 allocs/op -// pure hasher: -// BenchmarkHash-6 319362 4230 ns/op 675 B/op 9 allocs/op -// BenchmarkHash-6 257460 4674 ns/op 689 B/op 9 allocs/op -// With hashing in-between and pure hasher: -// BenchmarkHash-6 225417 7150 ns/op 982 B/op 12 allocs/op -// BenchmarkHash-6 220378 6197 ns/op 983 B/op 12 allocs/op -// same with old hasher -// BenchmarkHash-6 229758 6437 ns/op 981 B/op 12 allocs/op -// BenchmarkHash-6 212610 7137 ns/op 986 B/op 12 allocs/op -func BenchmarkHash(b *testing.B) { - // Create a realistic account trie to hash. We're first adding and hashing N - // entries, then adding N more. - addresses, accounts := makeAccounts(2 * b.N) - // Insert the accounts into the trie and hash it - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - i := 0 - for ; i < len(addresses)/2; i++ { - trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) - } - trie.Hash() - for ; i < len(addresses); i++ { - trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) - } - b.ResetTimer() - b.ReportAllocs() - //trie.hashRoot(nil, nil) - trie.Hash() -} - -// Benchmarks the trie Commit following a Hash. Since the trie caches the result of any operation, -// we cannot use b.N as the number of hashing rounds, since all rounds apart from -// the first one will be NOOP. As such, we'll use b.N as the number of account to -// insert into the trie before measuring the hashing. -func BenchmarkCommitAfterHash(b *testing.B) { - b.Run("no-onleaf", func(b *testing.B) { - benchmarkCommitAfterHash(b, false) - }) - b.Run("with-onleaf", func(b *testing.B) { - benchmarkCommitAfterHash(b, true) - }) -} - -func benchmarkCommitAfterHash(b *testing.B, collectLeaf bool) { - // Make the random benchmark deterministic - addresses, accounts := makeAccounts(b.N) - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - for i := 0; i < len(addresses); i++ { - trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) - } - // Insert the accounts into the trie and hash it - trie.Hash() - b.ResetTimer() - b.ReportAllocs() - trie.Commit(collectLeaf) -} - -func TestTinyTrie(t *testing.T) { - // Create a realistic account trie to hash - _, accounts := makeAccounts(5) - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - trie.MustUpdate(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001337"), accounts[3]) - if exp, root := common.HexToHash("dfb9311ba769a2bdb9d4126d0ae49046f9551063c738d10b9021343fb6550b3f"), trie.Hash(); exp != root { - t.Errorf("1: got %x, exp %x", root, exp) - } - trie.MustUpdate(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001338"), accounts[4]) - if exp, root := common.HexToHash("21d0f2f4c72fed985d1196993a784d36321a44085bbe60990cb65b7bc478f52b"), trie.Hash(); exp != root { - t.Errorf("2: got %x, exp %x", root, exp) - } - trie.MustUpdate(common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000001339"), accounts[4]) - if exp, root := common.HexToHash("e71f7f0bbcd0daf37bc03a3389408eced206e796ed6d76186387847e2193ac4e"), trie.Hash(); exp != root { - t.Errorf("3: got %x, exp %x", root, exp) - } - checktr := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - it := NewIterator(trie.MustNodeIterator(nil)) - for it.Next() { - checktr.MustUpdate(it.Key, it.Value) - } - if troot, itroot := trie.Hash(), checktr.Hash(); troot != itroot { - t.Fatalf("hash mismatch in opItercheckhash, trie: %x, check: %x", troot, itroot) - } -} - -func TestCommitAfterHash(t *testing.T) { - // Create a realistic account trie to hash - addresses, accounts := makeAccounts(1000) - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - for i := 0; i < len(addresses); i++ { - trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) - } - // Insert the accounts into the trie and hash it - trie.Hash() - trie.Commit(false) - root := trie.Hash() - exp := common.HexToHash("6dcf62a0c1575866467426b55e3acab075312b38c6b112457c3cd23ab9b94fc1") - if exp != root { - t.Errorf("got %x, exp %x", root, exp) - } - root, _, _ = trie.Commit(false) - if exp != root { - t.Errorf("got %x, exp %x", root, exp) - } -} - -func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) { - // Make the random benchmark deterministic - random := rand.New(rand.NewSource(0)) - // Create a realistic account trie to hash - addresses = make([][20]byte, size) - for i := 0; i < len(addresses); i++ { - data := make([]byte, 20) - random.Read(data) - copy(addresses[i][:], data) - } - accounts = make([][]byte, len(addresses)) - for i := 0; i < len(accounts); i++ { - var ( - nonce = uint64(random.Int63()) - root = types.EmptyRootHash - code = crypto.Keccak256(nil) - ) - // The big.Rand function is not deterministic with regards to 64 vs 32 bit systems, - // and will consume different amount of data from the rand source. - //balance = new(big.Int).Rand(random, new(big.Int).Exp(common.Big2, common.Big256, nil)) - // Therefore, we instead just read via byte buffer - numBytes := random.Uint32() % 33 // [0, 32] bytes - balanceBytes := make([]byte, numBytes) - random.Read(balanceBytes) - balance := new(uint256.Int).SetBytes(balanceBytes) - data, _ := rlp.EncodeToBytes(&types.StateAccount{Nonce: nonce, Balance: balance, Root: root, CodeHash: code}) - accounts[i] = data - } - return addresses, accounts -} - -// spongeDb is a dummy db backend which accumulates writes in a sponge -type spongeDb struct { - sponge hash.Hash - id string - journal []string - keys []string - values map[string]string -} - -func (s *spongeDb) Has(key []byte) (bool, error) { panic("implement me") } -func (s *spongeDb) Get(key []byte) ([]byte, error) { return nil, errors.New("no such elem") } -func (s *spongeDb) Delete(key []byte) error { panic("implement me") } -func (s *spongeDb) NewBatch() ethdb.Batch { return &spongeBatch{s} } -func (s *spongeDb) NewBatchWithSize(size int) ethdb.Batch { return &spongeBatch{s} } -func (s *spongeDb) NewSnapshot() (ethdb.Snapshot, error) { panic("implement me") } -func (s *spongeDb) Stat(property string) (string, error) { panic("implement me") } -func (s *spongeDb) Compact(start []byte, limit []byte) error { panic("implement me") } -func (s *spongeDb) Close() error { return nil } -func (s *spongeDb) Put(key []byte, value []byte) error { - var ( - keybrief = key - valbrief = value - ) - if len(keybrief) > 8 { - keybrief = keybrief[:8] - } - if len(valbrief) > 8 { - valbrief = valbrief[:8] - } - s.journal = append(s.journal, fmt.Sprintf("%v: PUT([%x...], [%d bytes] %x...)\n", s.id, keybrief, len(value), valbrief)) - - if s.values == nil { - s.sponge.Write(key) - s.sponge.Write(value) - } else { - s.keys = append(s.keys, string(key)) - s.values[string(key)] = string(value) - } - return nil -} -func (s *spongeDb) NewIterator(prefix []byte, start []byte) ethdb.Iterator { panic("implement me") } - -func (s *spongeDb) Flush() { - // Bottom-up, the longest path first - sort.Sort(sort.Reverse(sort.StringSlice(s.keys))) - for _, key := range s.keys { - s.sponge.Write([]byte(key)) - s.sponge.Write([]byte(s.values[key])) - } -} - -// spongeBatch is a dummy batch which immediately writes to the underlying spongedb -type spongeBatch struct { - db *spongeDb -} - -func (b *spongeBatch) Put(key, value []byte) error { - b.db.Put(key, value) - return nil -} -func (b *spongeBatch) Delete(key []byte) error { panic("implement me") } -func (b *spongeBatch) ValueSize() int { return 100 } -func (b *spongeBatch) Write() error { return nil } -func (b *spongeBatch) Reset() {} -func (b *spongeBatch) Replay(w ethdb.KeyValueWriter) error { return nil } - -// TestCommitSequence tests that the trie.Commit operation writes the elements of the trie -// in the expected order. -// The test data was based on the 'master' code, and is basically random. It can be used -// to check whether changes to the trie modifies the write order or data in any way. -func TestCommitSequence(t *testing.T) { - for i, tc := range []struct { - count int - expWriteSeqHash []byte - }{ - {20, common.FromHex("2e4ec8744409f17d6a3fe1540282e3ba0cf434b3a11974a2a033e3caa476a83c")}, - {200, common.FromHex("f7abb2c93e89e7e68696d855fa8982cb454190dcd7e4e7f4c7d60fd5c9f465f3")}, - {2000, common.FromHex("226f735a06e25b5306216d52ce0652ba9df17341bb0d1ae8be5484d691e8fe5c")}, - } { - addresses, accounts := makeAccounts(tc.count) - // This spongeDb is used to check the sequence of disk-db-writes - s := &spongeDb{sponge: sha3.NewLegacyKeccak256()} - db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) - trie := NewEmpty(db) - // Fill the trie with elements - for i := 0; i < tc.count; i++ { - trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) - } - // Flush trie -> database - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - // Flush memdb -> disk (sponge) - db.Commit(root) - if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) { - t.Errorf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp) - } - } -} - -// TestCommitSequenceRandomBlobs is identical to TestCommitSequence -// but uses random blobs instead of 'accounts' -func TestCommitSequenceRandomBlobs(t *testing.T) { - for i, tc := range []struct { - count int - expWriteSeqHash []byte - }{ - {20, common.FromHex("8016650c7a50cf88485fd06cde52d634a89711051107f00d21fae98234f2f13d")}, - {200, common.FromHex("dde92ca9812e068e6982d04b40846dc65a61a9fd4996fc0f55f2fde172a8e13c")}, - {2000, common.FromHex("ab553a7f9aff82e3929c382908e30ef7dd17a332933e92ba3fe873fc661ef382")}, - } { - prng := rand.New(rand.NewSource(int64(i))) - // This spongeDb is used to check the sequence of disk-db-writes - s := &spongeDb{sponge: sha3.NewLegacyKeccak256()} - db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) - trie := NewEmpty(db) - // Fill the trie with elements - for i := 0; i < tc.count; i++ { - key := make([]byte, 32) - var val []byte - // 50% short elements, 50% large elements - if prng.Intn(2) == 0 { - val = make([]byte, 1+prng.Intn(32)) - } else { - val = make([]byte, 1+prng.Intn(4096)) - } - prng.Read(key) - prng.Read(val) - trie.MustUpdate(key, val) - } - // Flush trie -> database - root, nodes, _ := trie.Commit(false) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - // Flush memdb -> disk (sponge) - db.Commit(root) - if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) { - t.Fatalf("test %d, disk write sequence wrong:\ngot %x exp %x\n", i, got, exp) - } - } -} - -func TestCommitSequenceStackTrie(t *testing.T) { - for count := 1; count < 200; count++ { - prng := rand.New(rand.NewSource(int64(count))) - // This spongeDb is used to check the sequence of disk-db-writes - s := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), - id: "a", - values: make(map[string]string), - } - db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) - trie := NewEmpty(db) - - // Another sponge is used for the stacktrie commits - stackTrieSponge := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), - id: "b", - values: make(map[string]string), - } - options := NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(stackTrieSponge, common.Hash{}, path, hash, blob, db.Scheme()) - }) - stTrie := NewStackTrie(options) - - // Fill the trie with elements - for i := 0; i < count; i++ { - // For the stack trie, we need to do inserts in proper order - key := make([]byte, 32) - binary.BigEndian.PutUint64(key, uint64(i)) - var val []byte - // 50% short elements, 50% large elements - if prng.Intn(2) == 0 { - val = make([]byte, 1+prng.Intn(32)) - } else { - val = make([]byte, 1+prng.Intn(1024)) - } - prng.Read(val) - trie.Update(key, val) - stTrie.Update(key, val) - } - // Flush trie -> database - root, nodes, _ := trie.Commit(false) - // Flush memdb -> disk (sponge) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - db.Commit(root) - s.Flush() - - // And flush stacktrie -> disk - stRoot := stTrie.Commit() - if stRoot != root { - t.Fatalf("root wrong, got %x exp %x", stRoot, root) - } - stackTrieSponge.Flush() - if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) { - // Show the journal - t.Logf("Expected:") - for i, v := range s.journal { - t.Logf("op %d: %v", i, v) - } - t.Logf("Stacktrie:") - for i, v := range stackTrieSponge.journal { - t.Logf("op %d: %v", i, v) - } - t.Fatalf("test %d, disk write sequence wrong:\ngot %x exp %x\n", count, got, exp) - } - } -} - -// TestCommitSequenceSmallRoot tests that a trie which is essentially only a -// small (<32 byte) shortnode with an included value is properly committed to a -// database. -// This case might not matter, since in practice, all keys are 32 bytes, which means -// that even a small trie which contains a leaf will have an extension making it -// not fit into 32 bytes, rlp-encoded. However, it's still the correct thing to do. -func TestCommitSequenceSmallRoot(t *testing.T) { - s := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), - id: "a", - values: make(map[string]string), - } - db := newTestDatabase(rawdb.NewDatabase(s), rawdb.HashScheme) - trie := NewEmpty(db) - - // Another sponge is used for the stacktrie commits - stackTrieSponge := &spongeDb{ - sponge: sha3.NewLegacyKeccak256(), - id: "b", - values: make(map[string]string), - } - options := NewStackTrieOptions() - options = options.WithWriter(func(path []byte, hash common.Hash, blob []byte) { - rawdb.WriteTrieNode(stackTrieSponge, common.Hash{}, path, hash, blob, db.Scheme()) - }) - stTrie := NewStackTrie(options) - - // Add a single small-element to the trie(s) - key := make([]byte, 5) - key[0] = 1 - trie.Update(key, []byte{0x1}) - stTrie.Update(key, []byte{0x1}) - - // Flush trie -> database - root, nodes, _ := trie.Commit(false) - // Flush memdb -> disk (sponge) - db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) - db.Commit(root) - - // And flush stacktrie -> disk - stRoot := stTrie.Commit() - if stRoot != root { - t.Fatalf("root wrong, got %x exp %x", stRoot, root) - } - t.Logf("root: %x\n", stRoot) - - s.Flush() - stackTrieSponge.Flush() - if got, exp := stackTrieSponge.sponge.Sum(nil), s.sponge.Sum(nil); !bytes.Equal(got, exp) { - t.Fatalf("test, disk write sequence wrong:\ngot %x exp %x\n", got, exp) - } -} - -// BenchmarkCommitAfterHashFixedSize benchmarks the Commit (after Hash) of a fixed number of updates to a trie. -// This benchmark is meant to capture the difference on efficiency of small versus large changes. Typically, -// storage tries are small (a couple of entries), whereas the full post-block account trie update is large (a couple -// of thousand entries) -func BenchmarkHashFixedSize(b *testing.B) { - b.Run("10", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(20) - for i := 0; i < b.N; i++ { - benchmarkHashFixedSize(b, acc, add) - } - }) - b.Run("100", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(100) - for i := 0; i < b.N; i++ { - benchmarkHashFixedSize(b, acc, add) - } - }) - - b.Run("1K", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(1000) - for i := 0; i < b.N; i++ { - benchmarkHashFixedSize(b, acc, add) - } - }) - b.Run("10K", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(10000) - for i := 0; i < b.N; i++ { - benchmarkHashFixedSize(b, acc, add) - } - }) - b.Run("100K", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(100000) - for i := 0; i < b.N; i++ { - benchmarkHashFixedSize(b, acc, add) - } - }) -} - -func benchmarkHashFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) { - b.ReportAllocs() - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - for i := 0; i < len(addresses); i++ { - trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) - } - // Insert the accounts into the trie and hash it - b.StartTimer() - trie.Hash() - b.StopTimer() -} - -func BenchmarkCommitAfterHashFixedSize(b *testing.B) { - b.Run("10", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(20) - for i := 0; i < b.N; i++ { - benchmarkCommitAfterHashFixedSize(b, acc, add) - } - }) - b.Run("100", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(100) - for i := 0; i < b.N; i++ { - benchmarkCommitAfterHashFixedSize(b, acc, add) - } - }) - - b.Run("1K", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(1000) - for i := 0; i < b.N; i++ { - benchmarkCommitAfterHashFixedSize(b, acc, add) - } - }) - b.Run("10K", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(10000) - for i := 0; i < b.N; i++ { - benchmarkCommitAfterHashFixedSize(b, acc, add) - } - }) - b.Run("100K", func(b *testing.B) { - b.StopTimer() - acc, add := makeAccounts(100000) - for i := 0; i < b.N; i++ { - benchmarkCommitAfterHashFixedSize(b, acc, add) - } - }) -} - -func benchmarkCommitAfterHashFixedSize(b *testing.B, addresses [][20]byte, accounts [][]byte) { - b.ReportAllocs() - trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) - for i := 0; i < len(addresses); i++ { - trie.MustUpdate(crypto.Keccak256(addresses[i][:]), accounts[i]) - } - // Insert the accounts into the trie and hash it - trie.Hash() - b.StartTimer() - trie.Commit(false) - b.StopTimer() -} - -func getString(trie *Trie, k string) []byte { - return trie.MustGet([]byte(k)) -} - -func updateString(trie *Trie, k, v string) { - trie.MustUpdate([]byte(k), []byte(v)) -} - -func deleteString(trie *Trie, k string) { - trie.MustDelete([]byte(k)) -} - -func TestDecodeNode(t *testing.T) { - t.Parallel() - - var ( - hash = make([]byte, 20) - elems = make([]byte, 20) - ) - for i := 0; i < 5000000; i++ { - prng.Read(hash) - prng.Read(elems) - decodeNode(hash, elems) - } -} - -func FuzzTrie(f *testing.F) { - f.Fuzz(func(t *testing.T, data []byte) { - var steps = 500 - var input = bytes.NewReader(data) - var finishedFn = func() bool { - steps-- - return steps < 0 || input.Len() == 0 - } - if err := runRandTest(generateSteps(finishedFn, input)); err != nil { - t.Fatal(err) - } - }) -} diff --git a/trie/trienode/node.go b/trie/trienode/node.go deleted file mode 100644 index 95315c2e9a..0000000000 --- a/trie/trienode/node.go +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see - -package trienode - -import ( - "fmt" - "sort" - "strings" - - "github.com/ethereum/go-ethereum/common" -) - -// Node is a wrapper which contains the encoded blob of the trie node and its -// node hash. It is general enough that can be used to represent trie node -// corresponding to different trie implementations. -type Node struct { - Hash common.Hash // Node hash, empty for deleted node - Blob []byte // Encoded node blob, nil for the deleted node -} - -// Size returns the total memory size used by this node. -func (n *Node) Size() int { - return len(n.Blob) + common.HashLength -} - -// IsDeleted returns the indicator if the node is marked as deleted. -func (n *Node) IsDeleted() bool { - return len(n.Blob) == 0 -} - -// New constructs a node with provided node information. -func New(hash common.Hash, blob []byte) *Node { - return &Node{Hash: hash, Blob: blob} -} - -// NewDeleted constructs a node which is deleted. -func NewDeleted() *Node { return New(common.Hash{}, nil) } - -// leaf represents a trie leaf node -type leaf struct { - Blob []byte // raw blob of leaf - Parent common.Hash // the hash of parent node -} - -// NodeSet contains a set of nodes collected during the commit operation. -// Each node is keyed by path. It's not thread-safe to use. -type NodeSet struct { - Owner common.Hash - Leaves []*leaf - Nodes map[string]*Node - updates int // the count of updated and inserted nodes - deletes int // the count of deleted nodes -} - -// NewNodeSet initializes a node set. The owner is zero for the account trie and -// the owning account address hash for storage tries. -func NewNodeSet(owner common.Hash) *NodeSet { - return &NodeSet{ - Owner: owner, - Nodes: make(map[string]*Node), - } -} - -// ForEachWithOrder iterates the nodes with the order from bottom to top, -// right to left, nodes with the longest path will be iterated first. -func (set *NodeSet) ForEachWithOrder(callback func(path string, n *Node)) { - var paths []string - for path := range set.Nodes { - paths = append(paths, path) - } - // Bottom-up, the longest path first - sort.Sort(sort.Reverse(sort.StringSlice(paths))) - for _, path := range paths { - callback(path, set.Nodes[path]) - } -} - -// AddNode adds the provided node into set. -func (set *NodeSet) AddNode(path []byte, n *Node) { - if n.IsDeleted() { - set.deletes += 1 - } else { - set.updates += 1 - } - set.Nodes[string(path)] = n -} - -// Merge adds a set of nodes into the set. -func (set *NodeSet) Merge(owner common.Hash, nodes map[string]*Node) error { - if set.Owner != owner { - return fmt.Errorf("nodesets belong to different owner are not mergeable %x-%x", set.Owner, owner) - } - for path, node := range nodes { - prev, ok := set.Nodes[path] - if ok { - // overwrite happens, revoke the counter - if prev.IsDeleted() { - set.deletes -= 1 - } else { - set.updates -= 1 - } - } - set.AddNode([]byte(path), node) - } - return nil -} - -// AddLeaf adds the provided leaf node into set. TODO(rjl493456442) how can -// we get rid of it? -func (set *NodeSet) AddLeaf(parent common.Hash, blob []byte) { - set.Leaves = append(set.Leaves, &leaf{Blob: blob, Parent: parent}) -} - -// Size returns the number of dirty nodes in set. -func (set *NodeSet) Size() (int, int) { - return set.updates, set.deletes -} - -// Hashes returns the hashes of all updated nodes. TODO(rjl493456442) how can -// we get rid of it? -func (set *NodeSet) Hashes() []common.Hash { - var ret []common.Hash - for _, node := range set.Nodes { - ret = append(ret, node.Hash) - } - return ret -} - -// Summary returns a string-representation of the NodeSet. -func (set *NodeSet) Summary() string { - var out = new(strings.Builder) - fmt.Fprintf(out, "nodeset owner: %v\n", set.Owner) - if set.Nodes != nil { - for path, n := range set.Nodes { - // Deletion - if n.IsDeleted() { - fmt.Fprintf(out, " [-]: %x\n", path) - continue - } - // Insertion or update - fmt.Fprintf(out, " [+/*]: %x -> %v \n", path, n.Hash) - } - } - for _, n := range set.Leaves { - fmt.Fprintf(out, "[leaf]: %v\n", n) - } - return out.String() -} - -// MergedNodeSet represents a merged node set for a group of tries. -type MergedNodeSet struct { - Sets map[common.Hash]*NodeSet -} - -// NewMergedNodeSet initializes an empty merged set. -func NewMergedNodeSet() *MergedNodeSet { - return &MergedNodeSet{Sets: make(map[common.Hash]*NodeSet)} -} - -// NewWithNodeSet constructs a merged nodeset with the provided single set. -func NewWithNodeSet(set *NodeSet) *MergedNodeSet { - merged := NewMergedNodeSet() - merged.Merge(set) - return merged -} - -// Merge merges the provided dirty nodes of a trie into the set. The assumption -// is held that no duplicated set belonging to the same trie will be merged twice. -func (set *MergedNodeSet) Merge(other *NodeSet) error { - subset, present := set.Sets[other.Owner] - if present { - return subset.Merge(other.Owner, other.Nodes) - } - set.Sets[other.Owner] = other - return nil -} - -// Flatten returns a two-dimensional map for internal nodes. -func (set *MergedNodeSet) Flatten() map[common.Hash]map[string]*Node { - nodes := make(map[common.Hash]map[string]*Node) - for owner, set := range set.Sets { - nodes[owner] = set.Nodes - } - return nodes -} diff --git a/trie/triestate/state.go b/trie/triestate/state.go deleted file mode 100644 index 75c4e0bd69..0000000000 --- a/trie/triestate/state.go +++ /dev/null @@ -1,286 +0,0 @@ -// (c) 2024, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see - -package triestate - -import ( - "errors" - "fmt" - "sync" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" -) - -// Trie is an Ethereum state trie, can be implemented by Ethereum Merkle Patricia -// tree or Verkle tree. -type Trie interface { - // Get returns the value for key stored in the trie. - Get(key []byte) ([]byte, error) - - // Update associates key with value in the trie. - Update(key, value []byte) error - - // Delete removes any existing value for key from the trie. - Delete(key []byte) error - - // Commit the trie and returns a set of dirty nodes generated along with - // the new root hash. - Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet, error) -} - -// TrieLoader wraps functions to load tries. -type TrieLoader interface { - // OpenTrie opens the main account trie. - OpenTrie(root common.Hash) (Trie, error) - - // OpenStorageTrie opens the storage trie of an account. - OpenStorageTrie(stateRoot common.Hash, addrHash, root common.Hash) (Trie, error) -} - -// Set represents a collection of mutated states during a state transition. -// The value refers to the original content of state before the transition -// is made. Nil means that the state was not present previously. -type Set struct { - Accounts map[common.Address][]byte // Mutated account set, nil means the account was not present - Storages map[common.Address]map[common.Hash][]byte // Mutated storage set, nil means the slot was not present - Incomplete map[common.Address]struct{} // Indicator whether the storage is incomplete due to large deletion - size common.StorageSize // Approximate size of set -} - -// New constructs the state set with provided data. -func New(accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, incomplete map[common.Address]struct{}) *Set { - return &Set{ - Accounts: accounts, - Storages: storages, - Incomplete: incomplete, - } -} - -// Size returns the approximate memory size occupied by the set. -func (s *Set) Size() common.StorageSize { - if s.size != 0 { - return s.size - } - for _, account := range s.Accounts { - s.size += common.StorageSize(common.AddressLength + len(account)) - } - for _, slots := range s.Storages { - for _, val := range slots { - s.size += common.StorageSize(common.HashLength + len(val)) - } - s.size += common.StorageSize(common.AddressLength) - } - s.size += common.StorageSize(common.AddressLength * len(s.Incomplete)) - return s.size -} - -// context wraps all fields for executing state diffs. -type context struct { - prevRoot common.Hash - postRoot common.Hash - accounts map[common.Address][]byte - storages map[common.Address]map[common.Hash][]byte - accountTrie Trie - nodes *trienode.MergedNodeSet -} - -// Apply traverses the provided state diffs, apply them in the associated -// post-state and return the generated dirty trie nodes. The state can be -// loaded via the provided trie loader. -func Apply(prevRoot common.Hash, postRoot common.Hash, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, loader TrieLoader) (map[common.Hash]map[string]*trienode.Node, error) { - tr, err := loader.OpenTrie(postRoot) - if err != nil { - return nil, err - } - ctx := &context{ - prevRoot: prevRoot, - postRoot: postRoot, - accounts: accounts, - storages: storages, - accountTrie: tr, - nodes: trienode.NewMergedNodeSet(), - } - for addr, account := range accounts { - var err error - if len(account) == 0 { - err = deleteAccount(ctx, loader, addr) - } else { - err = updateAccount(ctx, loader, addr) - } - if err != nil { - return nil, fmt.Errorf("failed to revert state, err: %w", err) - } - } - root, result, err := tr.Commit(false) - if err != nil { - return nil, err - } - if root != prevRoot { - return nil, fmt.Errorf("failed to revert state, want %#x, got %#x", prevRoot, root) - } - if err := ctx.nodes.Merge(result); err != nil { - return nil, err - } - return ctx.nodes.Flatten(), nil -} - -// updateAccount the account was present in prev-state, and may or may not -// existent in post-state. Apply the reverse diff and verify if the storage -// root matches the one in prev-state account. -func updateAccount(ctx *context, loader TrieLoader, addr common.Address) error { - // The account was present in prev-state, decode it from the - // 'slim-rlp' format bytes. - h := newHasher() - defer h.release() - - addrHash := h.hash(addr.Bytes()) - prev, err := types.FullAccount(ctx.accounts[addr]) - if err != nil { - return err - } - // The account may or may not existent in post-state, try to - // load it and decode if it's found. - blob, err := ctx.accountTrie.Get(addrHash.Bytes()) - if err != nil { - return err - } - post := types.NewEmptyStateAccount() - if len(blob) != 0 { - if err := rlp.DecodeBytes(blob, &post); err != nil { - return err - } - } - // Apply all storage changes into the post-state storage trie. - st, err := loader.OpenStorageTrie(ctx.postRoot, addrHash, post.Root) - if err != nil { - return err - } - for key, val := range ctx.storages[addr] { - var err error - if len(val) == 0 { - err = st.Delete(key.Bytes()) - } else { - err = st.Update(key.Bytes(), val) - } - if err != nil { - return err - } - } - root, result, err := st.Commit(false) - if err != nil { - return err - } - if root != prev.Root { - return errors.New("failed to reset storage trie") - } - // The returned set can be nil if storage trie is not changed - // at all. - if result != nil { - if err := ctx.nodes.Merge(result); err != nil { - return err - } - } - // Write the prev-state account into the main trie - full, err := rlp.EncodeToBytes(prev) - if err != nil { - return err - } - return ctx.accountTrie.Update(addrHash.Bytes(), full) -} - -// deleteAccount the account was not present in prev-state, and is expected -// to be existent in post-state. Apply the reverse diff and verify if the -// account and storage is wiped out correctly. -func deleteAccount(ctx *context, loader TrieLoader, addr common.Address) error { - // The account must be existent in post-state, load the account. - h := newHasher() - defer h.release() - - addrHash := h.hash(addr.Bytes()) - blob, err := ctx.accountTrie.Get(addrHash.Bytes()) - if err != nil { - return err - } - if len(blob) == 0 { - return fmt.Errorf("account is non-existent %#x", addrHash) - } - var post types.StateAccount - if err := rlp.DecodeBytes(blob, &post); err != nil { - return err - } - st, err := loader.OpenStorageTrie(ctx.postRoot, addrHash, post.Root) - if err != nil { - return err - } - for key, val := range ctx.storages[addr] { - if len(val) != 0 { - return errors.New("expect storage deletion") - } - if err := st.Delete(key.Bytes()); err != nil { - return err - } - } - root, result, err := st.Commit(false) - if err != nil { - return err - } - if root != types.EmptyRootHash { - return errors.New("failed to clear storage trie") - } - // The returned set can be nil if storage trie is not changed - // at all. - if result != nil { - if err := ctx.nodes.Merge(result); err != nil { - return err - } - } - // Delete the post-state account from the main trie. - return ctx.accountTrie.Delete(addrHash.Bytes()) -} - -// hasher is used to compute the sha256 hash of the provided data. -type hasher struct{ sha crypto.KeccakState } - -var hasherPool = sync.Pool{ - New: func() interface{} { return &hasher{sha: sha3.NewLegacyKeccak256().(crypto.KeccakState)} }, -} - -func newHasher() *hasher { - return hasherPool.Get().(*hasher) -} - -func (h *hasher) hash(data []byte) common.Hash { - return crypto.HashData(h.sha, data) -} - -func (h *hasher) release() { - hasherPool.Put(h) -} diff --git a/trie/utils/verkle.go b/trie/utils/verkle.go deleted file mode 100644 index ca733d1d7e..0000000000 --- a/trie/utils/verkle.go +++ /dev/null @@ -1,342 +0,0 @@ -// Copyright 2023 go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package utils - -import ( - "encoding/binary" - "sync" - - "github.com/ava-labs/libevm/metrics" - "github.com/crate-crypto/go-ipa/bandersnatch/fr" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/gballet/go-verkle" - "github.com/holiman/uint256" -) - -const ( - // The spec of verkle key encoding can be found here. - // https://notes.ethereum.org/@vbuterin/verkle_tree_eip#Tree-embedding - VersionLeafKey = 0 - BalanceLeafKey = 1 - NonceLeafKey = 2 - CodeKeccakLeafKey = 3 - CodeSizeLeafKey = 4 -) - -var ( - zero = uint256.NewInt(0) - verkleNodeWidthLog2 = 8 - headerStorageOffset = uint256.NewInt(64) - mainStorageOffsetLshVerkleNodeWidth = new(uint256.Int).Lsh(uint256.NewInt(256), 31-uint(verkleNodeWidthLog2)) - codeOffset = uint256.NewInt(128) - verkleNodeWidth = uint256.NewInt(256) - codeStorageDelta = uint256.NewInt(0).Sub(codeOffset, headerStorageOffset) - - index0Point *verkle.Point // pre-computed commitment of polynomial [2+256*64] - - // cacheHitGauge is the metric to track how many cache hit occurred. - cacheHitGauge = metrics.NewRegisteredGauge("trie/verkle/cache/hit", nil) - - // cacheMissGauge is the metric to track how many cache miss occurred. - cacheMissGauge = metrics.NewRegisteredGauge("trie/verkle/cache/miss", nil) -) - -func init() { - // The byte array is the Marshalled output of the point computed as such: - // - // var ( - // config = verkle.GetConfig() - // fr verkle.Fr - // ) - // verkle.FromLEBytes(&fr, []byte{2, 64}) - // point := config.CommitToPoly([]verkle.Fr{fr}, 1) - index0Point = new(verkle.Point) - err := index0Point.SetBytes([]byte{34, 25, 109, 242, 193, 5, 144, 224, 76, 52, 189, 92, 197, 126, 9, 145, 27, 152, 199, 130, 165, 3, 210, 27, 193, 131, 142, 28, 110, 26, 16, 191}) - if err != nil { - panic(err) - } -} - -// PointCache is the LRU cache for storing evaluated address commitment. -type PointCache struct { - lru lru.BasicLRU[string, *verkle.Point] - lock sync.RWMutex -} - -// NewPointCache returns the cache with specified size. -func NewPointCache(maxItems int) *PointCache { - return &PointCache{ - lru: lru.NewBasicLRU[string, *verkle.Point](maxItems), - } -} - -// Get returns the cached commitment for the specified address, or computing -// it on the flight. -func (c *PointCache) Get(addr []byte) *verkle.Point { - c.lock.Lock() - defer c.lock.Unlock() - - p, ok := c.lru.Get(string(addr)) - if ok { - cacheHitGauge.Inc(1) - return p - } - cacheMissGauge.Inc(1) - p = evaluateAddressPoint(addr) - c.lru.Add(string(addr), p) - return p -} - -// GetStem returns the first 31 bytes of the tree key as the tree stem. It only -// works for the account metadata whose treeIndex is 0. -func (c *PointCache) GetStem(addr []byte) []byte { - p := c.Get(addr) - return pointToHash(p, 0)[:31] -} - -// GetTreeKey performs both the work of the spec's get_tree_key function, and that -// of pedersen_hash: it builds the polynomial in pedersen_hash without having to -// create a mostly zero-filled buffer and "type cast" it to a 128-long 16-byte -// array. Since at most the first 5 coefficients of the polynomial will be non-zero, -// these 5 coefficients are created directly. -func GetTreeKey(address []byte, treeIndex *uint256.Int, subIndex byte) []byte { - if len(address) < 32 { - var aligned [32]byte - address = append(aligned[:32-len(address)], address...) - } - // poly = [2+256*64, address_le_low, address_le_high, tree_index_le_low, tree_index_le_high] - var poly [5]fr.Element - - // 32-byte address, interpreted as two little endian - // 16-byte numbers. - verkle.FromLEBytes(&poly[1], address[:16]) - verkle.FromLEBytes(&poly[2], address[16:]) - - // treeIndex must be interpreted as a 32-byte aligned little-endian integer. - // e.g: if treeIndex is 0xAABBCC, we need the byte representation to be 0xCCBBAA00...00. - // poly[3] = LE({CC,BB,AA,00...0}) (16 bytes), poly[4]=LE({00,00,...}) (16 bytes). - // - // To avoid unnecessary endianness conversions for go-ipa, we do some trick: - // - poly[3]'s byte representation is the same as the *top* 16 bytes (trieIndexBytes[16:]) of - // 32-byte aligned big-endian representation (BE({00,...,AA,BB,CC})). - // - poly[4]'s byte representation is the same as the *low* 16 bytes (trieIndexBytes[:16]) of - // the 32-byte aligned big-endian representation (BE({00,00,...}). - trieIndexBytes := treeIndex.Bytes32() - verkle.FromBytes(&poly[3], trieIndexBytes[16:]) - verkle.FromBytes(&poly[4], trieIndexBytes[:16]) - - cfg := verkle.GetConfig() - ret := cfg.CommitToPoly(poly[:], 0) - - // add a constant point corresponding to poly[0]=[2+256*64]. - ret.Add(ret, index0Point) - - return pointToHash(ret, subIndex) -} - -// GetTreeKeyWithEvaluatedAddress is basically identical to GetTreeKey, the only -// difference is a part of polynomial is already evaluated. -// -// Specifically, poly = [2+256*64, address_le_low, address_le_high] is already -// evaluated. -func GetTreeKeyWithEvaluatedAddress(evaluated *verkle.Point, treeIndex *uint256.Int, subIndex byte) []byte { - var poly [5]fr.Element - - poly[0].SetZero() - poly[1].SetZero() - poly[2].SetZero() - - // little-endian, 32-byte aligned treeIndex - var index [32]byte - for i := 0; i < len(treeIndex); i++ { - binary.LittleEndian.PutUint64(index[i*8:(i+1)*8], treeIndex[i]) - } - verkle.FromLEBytes(&poly[3], index[:16]) - verkle.FromLEBytes(&poly[4], index[16:]) - - cfg := verkle.GetConfig() - ret := cfg.CommitToPoly(poly[:], 0) - - // add the pre-evaluated address - ret.Add(ret, evaluated) - - return pointToHash(ret, subIndex) -} - -// VersionKey returns the verkle tree key of the version field for the specified account. -func VersionKey(address []byte) []byte { - return GetTreeKey(address, zero, VersionLeafKey) -} - -// BalanceKey returns the verkle tree key of the balance field for the specified account. -func BalanceKey(address []byte) []byte { - return GetTreeKey(address, zero, BalanceLeafKey) -} - -// NonceKey returns the verkle tree key of the nonce field for the specified account. -func NonceKey(address []byte) []byte { - return GetTreeKey(address, zero, NonceLeafKey) -} - -// CodeKeccakKey returns the verkle tree key of the code keccak field for -// the specified account. -func CodeKeccakKey(address []byte) []byte { - return GetTreeKey(address, zero, CodeKeccakLeafKey) -} - -// CodeSizeKey returns the verkle tree key of the code size field for the -// specified account. -func CodeSizeKey(address []byte) []byte { - return GetTreeKey(address, zero, CodeSizeLeafKey) -} - -func codeChunkIndex(chunk *uint256.Int) (*uint256.Int, byte) { - var ( - chunkOffset = new(uint256.Int).Add(codeOffset, chunk) - treeIndex = new(uint256.Int).Div(chunkOffset, verkleNodeWidth) - subIndexMod = new(uint256.Int).Mod(chunkOffset, verkleNodeWidth) - ) - var subIndex byte - if len(subIndexMod) != 0 { - subIndex = byte(subIndexMod[0]) - } - return treeIndex, subIndex -} - -// CodeChunkKey returns the verkle tree key of the code chunk for the -// specified account. -func CodeChunkKey(address []byte, chunk *uint256.Int) []byte { - treeIndex, subIndex := codeChunkIndex(chunk) - return GetTreeKey(address, treeIndex, subIndex) -} - -func storageIndex(bytes []byte) (*uint256.Int, byte) { - // If the storage slot is in the header, we need to add the header offset. - var key uint256.Int - key.SetBytes(bytes) - if key.Cmp(codeStorageDelta) < 0 { - // This addition is always safe; it can't ever overflow since pos - -package utils - -import ( - "bytes" - "testing" - - "github.com/gballet/go-verkle" - "github.com/holiman/uint256" -) - -func TestTreeKey(t *testing.T) { - var ( - address = []byte{0x01} - addressEval = evaluateAddressPoint(address) - smallIndex = uint256.NewInt(1) - largeIndex = uint256.NewInt(10000) - smallStorage = []byte{0x1} - largeStorage = bytes.Repeat([]byte{0xff}, 16) - ) - if !bytes.Equal(VersionKey(address), VersionKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched version key") - } - if !bytes.Equal(BalanceKey(address), BalanceKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched balance key") - } - if !bytes.Equal(NonceKey(address), NonceKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched nonce key") - } - if !bytes.Equal(CodeKeccakKey(address), CodeKeccakKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched code keccak key") - } - if !bytes.Equal(CodeSizeKey(address), CodeSizeKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched code size key") - } - if !bytes.Equal(CodeChunkKey(address, smallIndex), CodeChunkKeyWithEvaluatedAddress(addressEval, smallIndex)) { - t.Fatal("Unmatched code chunk key") - } - if !bytes.Equal(CodeChunkKey(address, largeIndex), CodeChunkKeyWithEvaluatedAddress(addressEval, largeIndex)) { - t.Fatal("Unmatched code chunk key") - } - if !bytes.Equal(StorageSlotKey(address, smallStorage), StorageSlotKeyWithEvaluatedAddress(addressEval, smallStorage)) { - t.Fatal("Unmatched storage slot key") - } - if !bytes.Equal(StorageSlotKey(address, largeStorage), StorageSlotKeyWithEvaluatedAddress(addressEval, largeStorage)) { - t.Fatal("Unmatched storage slot key") - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ava-labs/coreth/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkTreeKey -// BenchmarkTreeKey-8 398731 2961 ns/op 32 B/op 1 allocs/op -func BenchmarkTreeKey(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - b.ReportAllocs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - BalanceKey([]byte{0x01}) - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ava-labs/coreth/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkTreeKeyWithEvaluation -// BenchmarkTreeKeyWithEvaluation-8 513855 2324 ns/op 32 B/op 1 allocs/op -func BenchmarkTreeKeyWithEvaluation(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - addr := []byte{0x01} - eval := evaluateAddressPoint(addr) - - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - BalanceKeyWithEvaluatedAddress(eval) - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ava-labs/coreth/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkStorageKey -// BenchmarkStorageKey-8 230516 4584 ns/op 96 B/op 3 allocs/op -func BenchmarkStorageKey(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - b.ReportAllocs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - StorageSlotKey([]byte{0x01}, bytes.Repeat([]byte{0xff}, 32)) - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ava-labs/coreth/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkStorageKeyWithEvaluation -// BenchmarkStorageKeyWithEvaluation-8 320125 3753 ns/op 96 B/op 3 allocs/op -func BenchmarkStorageKeyWithEvaluation(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - addr := []byte{0x01} - eval := evaluateAddressPoint(addr) - - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - StorageSlotKeyWithEvaluatedAddress(eval, bytes.Repeat([]byte{0xff}, 32)) - } -} diff --git a/trie/verkle.go b/trie/verkle.go deleted file mode 100644 index 82cef89c0e..0000000000 --- a/trie/verkle.go +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright 2023 go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "encoding/binary" - "errors" - "fmt" - - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/utils" - "github.com/ava-labs/coreth/triedb/database" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/gballet/go-verkle" - "github.com/holiman/uint256" -) - -var ( - zero [32]byte - errInvalidRootType = errors.New("invalid node type for root") -) - -// VerkleTrie is a wrapper around VerkleNode that implements the trie.Trie -// interface so that Verkle trees can be reused verbatim. -type VerkleTrie struct { - root verkle.VerkleNode - cache *utils.PointCache - reader *trieReader -} - -// NewVerkleTrie constructs a verkle tree based on the specified root hash. -func NewVerkleTrie(root common.Hash, db database.Database, cache *utils.PointCache) (*VerkleTrie, error) { - reader, err := newTrieReader(root, common.Hash{}, db) - if err != nil { - return nil, err - } - // Parse the root verkle node if it's not empty. - node := verkle.New() - if root != types.EmptyVerkleHash && root != types.EmptyRootHash { - blob, err := reader.node(nil, common.Hash{}) - if err != nil { - return nil, err - } - node, err = verkle.ParseNode(blob, 0) - if err != nil { - return nil, err - } - } - return &VerkleTrie{ - root: node, - cache: cache, - reader: reader, - }, nil -} - -// GetKey returns the sha3 preimage of a hashed key that was previously used -// to store a value. -func (t *VerkleTrie) GetKey(key []byte) []byte { - return key -} - -// GetAccount implements state.Trie, retrieving the account with the specified -// account address. If the specified account is not in the verkle tree, nil will -// be returned. If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) GetAccount(addr common.Address) (*types.StateAccount, error) { - var ( - acc = &types.StateAccount{} - values [][]byte - err error - ) - switch n := t.root.(type) { - case *verkle.InternalNode: - values, err = n.GetValuesAtStem(t.cache.GetStem(addr[:]), t.nodeResolver) - if err != nil { - return nil, fmt.Errorf("GetAccount (%x) error: %v", addr, err) - } - default: - return nil, errInvalidRootType - } - if values == nil { - return nil, nil - } - // Decode nonce in little-endian - if len(values[utils.NonceLeafKey]) > 0 { - acc.Nonce = binary.LittleEndian.Uint64(values[utils.NonceLeafKey]) - } - // Decode balance in little-endian - var balance [32]byte - copy(balance[:], values[utils.BalanceLeafKey]) - for i := 0; i < len(balance)/2; i++ { - balance[len(balance)-i-1], balance[i] = balance[i], balance[len(balance)-i-1] - } - acc.Balance = new(uint256.Int).SetBytes32(balance[:]) - - // Decode codehash - acc.CodeHash = values[utils.CodeKeccakLeafKey] - - // TODO account.Root is leave as empty. How should we handle the legacy account? - return acc, nil -} - -// GetStorage implements state.Trie, retrieving the storage slot with the specified -// account address and storage key. If the specified slot is not in the verkle tree, -// nil will be returned. If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) GetStorage(addr common.Address, key []byte) ([]byte, error) { - k := utils.StorageSlotKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes()), key) - val, err := t.root.Get(k, t.nodeResolver) - if err != nil { - return nil, err - } - return common.TrimLeftZeroes(val), nil -} - -// UpdateAccount implements state.Trie, writing the provided account into the tree. -// If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount) error { - var ( - err error - nonce, balance [32]byte - values = make([][]byte, verkle.NodeWidth) - ) - values[utils.VersionLeafKey] = zero[:] - values[utils.CodeKeccakLeafKey] = acc.CodeHash[:] - - // Encode nonce in little-endian - binary.LittleEndian.PutUint64(nonce[:], acc.Nonce) - values[utils.NonceLeafKey] = nonce[:] - - // Encode balance in little-endian - bytes := acc.Balance.Bytes() - if len(bytes) > 0 { - for i, b := range bytes { - balance[len(bytes)-i-1] = b - } - } - values[utils.BalanceLeafKey] = balance[:] - - switch n := t.root.(type) { - case *verkle.InternalNode: - err = n.InsertValuesAtStem(t.cache.GetStem(addr[:]), values, t.nodeResolver) - if err != nil { - return fmt.Errorf("UpdateAccount (%x) error: %v", addr, err) - } - default: - return errInvalidRootType - } - // TODO figure out if the code size needs to be updated, too - return nil -} - -// UpdateStorage implements state.Trie, writing the provided storage slot into -// the tree. If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) UpdateStorage(address common.Address, key, value []byte) error { - // Left padding the slot value to 32 bytes. - var v [32]byte - if len(value) >= 32 { - copy(v[:], value[:32]) - } else { - copy(v[32-len(value):], value[:]) - } - k := utils.StorageSlotKeyWithEvaluatedAddress(t.cache.Get(address.Bytes()), key) - return t.root.Insert(k, v[:], t.nodeResolver) -} - -// DeleteAccount implements state.Trie, deleting the specified account from the -// trie. If the account was not existent in the trie, no error will be returned. -// If the trie is corrupted, an error will be returned. -func (t *VerkleTrie) DeleteAccount(addr common.Address) error { - var ( - err error - values = make([][]byte, verkle.NodeWidth) - ) - for i := 0; i < verkle.NodeWidth; i++ { - values[i] = zero[:] - } - switch n := t.root.(type) { - case *verkle.InternalNode: - err = n.InsertValuesAtStem(t.cache.GetStem(addr.Bytes()), values, t.nodeResolver) - if err != nil { - return fmt.Errorf("DeleteAccount (%x) error: %v", addr, err) - } - default: - return errInvalidRootType - } - return nil -} - -// DeleteStorage implements state.Trie, deleting the specified storage slot from -// the trie. If the storage slot was not existent in the trie, no error will be -// returned. If the trie is corrupted, an error will be returned. -func (t *VerkleTrie) DeleteStorage(addr common.Address, key []byte) error { - var zero [32]byte - k := utils.StorageSlotKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes()), key) - return t.root.Insert(k, zero[:], t.nodeResolver) -} - -// Hash returns the root hash of the tree. It does not write to the database and -// can be used even if the tree doesn't have one. -func (t *VerkleTrie) Hash() common.Hash { - return t.root.Commit().Bytes() -} - -// Commit writes all nodes to the tree's memory database. -func (t *VerkleTrie) Commit(_ bool) (common.Hash, *trienode.NodeSet, error) { - root, ok := t.root.(*verkle.InternalNode) - if !ok { - return common.Hash{}, nil, errors.New("unexpected root node type") - } - nodes, err := root.BatchSerialize() - if err != nil { - return common.Hash{}, nil, fmt.Errorf("serializing tree nodes: %s", err) - } - nodeset := trienode.NewNodeSet(common.Hash{}) - for _, node := range nodes { - // hash parameter is not used in pathdb - nodeset.AddNode(node.Path, trienode.New(common.Hash{}, node.SerializedBytes)) - } - // Serialize root commitment form - return t.Hash(), nodeset, nil -} - -// NodeIterator implements state.Trie, returning an iterator that returns -// nodes of the trie. Iteration starts at the key after the given start key. -// -// TODO(gballet, rjl493456442) implement it. -func (t *VerkleTrie) NodeIterator(startKey []byte) (NodeIterator, error) { - panic("not implemented") -} - -// Prove implements state.Trie, constructing a Merkle proof for key. The result -// contains all encoded nodes on the path to the value at key. The value itself -// is also included in the last node and can be retrieved by verifying the proof. -// -// If the trie does not contain a value for key, the returned proof contains all -// nodes of the longest existing prefix of the key (at least the root), ending -// with the node that proves the absence of the key. -// -// TODO(gballet, rjl493456442) implement it. -func (t *VerkleTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { - panic("not implemented") -} - -// Copy returns a deep-copied verkle tree. -func (t *VerkleTrie) Copy() *VerkleTrie { - return &VerkleTrie{ - root: t.root.Copy(), - cache: t.cache, - reader: t.reader, - } -} - -// IsVerkle indicates if the trie is a Verkle trie. -func (t *VerkleTrie) IsVerkle() bool { - return true -} - -// ChunkedCode represents a sequence of 32-bytes chunks of code (31 bytes of which -// are actual code, and 1 byte is the pushdata offset). -type ChunkedCode []byte - -// Copy the values here so as to avoid an import cycle -const ( - PUSH1 = byte(0x60) - PUSH32 = byte(0x7f) -) - -// ChunkifyCode generates the chunked version of an array representing EVM bytecode -func ChunkifyCode(code []byte) ChunkedCode { - var ( - chunkOffset = 0 // offset in the chunk - chunkCount = len(code) / 31 - codeOffset = 0 // offset in the code - ) - if len(code)%31 != 0 { - chunkCount++ - } - chunks := make([]byte, chunkCount*32) - for i := 0; i < chunkCount; i++ { - // number of bytes to copy, 31 unless the end of the code has been reached. - end := 31 * (i + 1) - if len(code) < end { - end = len(code) - } - copy(chunks[i*32+1:], code[31*i:end]) // copy the code itself - - // chunk offset = taken from the last chunk. - if chunkOffset > 31 { - // skip offset calculation if push data covers the whole chunk - chunks[i*32] = 31 - chunkOffset = 1 - continue - } - chunks[32*i] = byte(chunkOffset) - chunkOffset = 0 - - // Check each instruction and update the offset it should be 0 unless - // a PUSH-N overflows. - for ; codeOffset < end; codeOffset++ { - if code[codeOffset] >= PUSH1 && code[codeOffset] <= PUSH32 { - codeOffset += int(code[codeOffset] - PUSH1 + 1) - if codeOffset+1 >= 31*(i+1) { - codeOffset++ - chunkOffset = codeOffset - 31*(i+1) - break - } - } - } - } - return chunks -} - -// UpdateContractCode implements state.Trie, writing the provided contract code -// into the trie. -func (t *VerkleTrie) UpdateContractCode(addr common.Address, codeHash common.Hash, code []byte) error { - var ( - chunks = ChunkifyCode(code) - values [][]byte - key []byte - err error - ) - for i, chunknr := 0, uint64(0); i < len(chunks); i, chunknr = i+32, chunknr+1 { - groupOffset := (chunknr + 128) % 256 - if groupOffset == 0 /* start of new group */ || chunknr == 0 /* first chunk in header group */ { - values = make([][]byte, verkle.NodeWidth) - key = utils.CodeChunkKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes()), uint256.NewInt(chunknr)) - } - values[groupOffset] = chunks[i : i+32] - - // Reuse the calculated key to also update the code size. - if i == 0 { - cs := make([]byte, 32) - binary.LittleEndian.PutUint64(cs, uint64(len(code))) - values[utils.CodeSizeLeafKey] = cs - } - if groupOffset == 255 || len(chunks)-i <= 32 { - switch root := t.root.(type) { - case *verkle.InternalNode: - err = root.InsertValuesAtStem(key[:31], values, t.nodeResolver) - if err != nil { - return fmt.Errorf("UpdateContractCode (addr=%x) error: %w", addr[:], err) - } - default: - return errInvalidRootType - } - } - } - return nil -} - -func (t *VerkleTrie) ToDot() string { - return verkle.ToDot(t.root) -} - -func (t *VerkleTrie) nodeResolver(path []byte) ([]byte, error) { - return t.reader.node(path, common.Hash{}) -} diff --git a/trie/verkle_test.go b/trie/verkle_test.go deleted file mode 100644 index 2f45a8ef9a..0000000000 --- a/trie/verkle_test.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2023 go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "reflect" - "testing" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/holiman/uint256" -) - -var ( - accounts = map[common.Address]*types.StateAccount{ - {1}: { - Nonce: 100, - Balance: uint256.NewInt(100), - CodeHash: common.Hash{0x1}.Bytes(), - }, - {2}: { - Nonce: 200, - Balance: uint256.NewInt(200), - CodeHash: common.Hash{0x2}.Bytes(), - }, - } - storages = map[common.Address]map[common.Hash][]byte{ - {1}: { - common.Hash{10}: []byte{10}, - common.Hash{11}: []byte{11}, - common.MaxHash: []byte{0xff}, - }, - {2}: { - common.Hash{20}: []byte{20}, - common.Hash{21}: []byte{21}, - common.MaxHash: []byte{0xff}, - }, - } -) - -func TestVerkleTreeReadWrite(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.PathScheme) - tr, _ := NewVerkleTrie(types.EmptyVerkleHash, db, utils.NewPointCache(100)) - - for addr, acct := range accounts { - if err := tr.UpdateAccount(addr, acct); err != nil { - t.Fatalf("Failed to update account, %v", err) - } - for key, val := range storages[addr] { - if err := tr.UpdateStorage(addr, key.Bytes(), val); err != nil { - t.Fatalf("Failed to update account, %v", err) - } - } - } - - for addr, acct := range accounts { - stored, err := tr.GetAccount(addr) - if err != nil { - t.Fatalf("Failed to get account, %v", err) - } - if !reflect.DeepEqual(stored, acct) { - t.Fatal("account is not matched") - } - for key, val := range storages[addr] { - stored, err := tr.GetStorage(addr, key.Bytes()) - if err != nil { - t.Fatalf("Failed to get storage, %v", err) - } - if !bytes.Equal(stored, val) { - t.Fatal("storage is not matched") - } - } - } -} diff --git a/triedb/database.go b/triedb/database.go deleted file mode 100644 index 7421b74cf0..0000000000 --- a/triedb/database.go +++ /dev/null @@ -1,338 +0,0 @@ -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package triedb - -import ( - "errors" - - "github.com/ava-labs/coreth/trie" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ava-labs/coreth/triedb/database" - "github.com/ava-labs/coreth/triedb/hashdb" - "github.com/ava-labs/coreth/triedb/pathdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" -) - -// Config defines all necessary options for database. -type Config struct { - Preimages bool // Flag whether the preimage of node key is recorded - IsVerkle bool // Flag whether the db is holding a verkle tree - HashDB *hashdb.Config // Configs for hash-based scheme - PathDB *pathdb.Config // Configs for experimental path-based scheme -} - -// HashDefaults represents a config for using hash-based scheme with -// default settings. -var HashDefaults = &Config{ - Preimages: false, - HashDB: hashdb.Defaults, -} - -// backend defines the methods needed to access/update trie nodes in different -// state scheme. -type backend interface { - // Scheme returns the identifier of used storage scheme. - Scheme() string - - // Initialized returns an indicator if the state data is already initialized - // according to the state scheme. - Initialized(genesisRoot common.Hash) bool - - // Size returns the current storage size of the diff layers on top of the - // disk layer and the storage size of the nodes cached in the disk layer. - // - // For hash scheme, there is no differentiation between diff layer nodes - // and dirty disk layer nodes, so both are merged into the second return. - Size() (common.StorageSize, common.StorageSize) - - // Update performs a state transition by committing dirty nodes contained - // in the given set in order to update state from the specified parent to - // the specified root. - // - // The passed in maps(nodes, states) will be retained to avoid copying - // everything. Therefore, these maps must not be changed afterwards. - Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *triestate.Set) error - - // Commit writes all relevant trie nodes belonging to the specified state - // to disk. Report specifies whether logs will be displayed in info level. - Commit(root common.Hash, report bool) error - - // Close closes the trie database backend and releases all held resources. - Close() error -} - -// Database is the wrapper of the underlying backend which is shared by different -// types of node backend as an entrypoint. It's responsible for all interactions -// relevant with trie nodes and node preimages. -type Database struct { - config *Config // Configuration for trie database - diskdb ethdb.Database // Persistent database to store the snapshot - preimages *preimageStore // The store for caching preimages - backend backend // The backend for managing trie nodes -} - -// NewDatabase initializes the trie database with default settings, note -// the legacy hash-based scheme is used by default. -func NewDatabase(diskdb ethdb.Database, config *Config) *Database { - // Sanitize the config and use the default one if it's not specified. - if config == nil { - config = HashDefaults - } - var preimages *preimageStore - if config.Preimages { - preimages = newPreimageStore(diskdb) - } - db := &Database{ - config: config, - diskdb: diskdb, - preimages: preimages, - } - if config.HashDB != nil && config.PathDB != nil { - log.Crit("Both 'hash' and 'path' mode are configured") - } - if config.PathDB != nil { - db.backend = pathdb.New(diskdb, config.PathDB) - } else { - var resolver hashdb.ChildResolver - if config.IsVerkle { - // TODO define verkle resolver - log.Crit("Verkle node resolver is not defined") - } else { - resolver = trie.MerkleResolver{} - } - db.backend = hashdb.New(diskdb, config.HashDB, resolver) - } - return db -} - -// Reader returns a reader for accessing all trie nodes with provided state root. -// An error will be returned if the requested state is not available. -func (db *Database) Reader(blockRoot common.Hash) (database.Reader, error) { - switch b := db.backend.(type) { - case *hashdb.Database: - return b.Reader(blockRoot) - case *pathdb.Database: - return b.Reader(blockRoot) - } - return nil, errors.New("unknown backend") -} - -// Update performs a state transition by committing dirty nodes contained in the -// given set in order to update state from the specified parent to the specified -// root. The held pre-images accumulated up to this point will be flushed in case -// the size exceeds the threshold. -// -// The passed in maps(nodes, states) will be retained to avoid copying everything. -// Therefore, these maps must not be changed afterwards. -func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *triestate.Set) error { - if db.preimages != nil { - db.preimages.commit(false) - } - return db.backend.Update(root, parent, block, nodes, states) -} - -// Commit iterates over all the children of a particular node, writes them out -// to disk. As a side effect, all pre-images accumulated up to this point are -// also written. -func (db *Database) Commit(root common.Hash, report bool) error { - if db.preimages != nil { - db.preimages.commit(true) - } - return db.backend.Commit(root, report) -} - -// Size returns the storage size of diff layer nodes above the persistent disk -// layer, the dirty nodes buffered within the disk layer, and the size of cached -// preimages. -func (db *Database) Size() (common.StorageSize, common.StorageSize, common.StorageSize) { - var ( - diffs, nodes common.StorageSize - preimages common.StorageSize - ) - diffs, nodes = db.backend.Size() - if db.preimages != nil { - preimages = db.preimages.size() - } - return diffs, nodes, preimages -} - -// Initialized returns an indicator if the state data is already initialized -// according to the state scheme. -func (db *Database) Initialized(genesisRoot common.Hash) bool { - return db.backend.Initialized(genesisRoot) -} - -// Scheme returns the node scheme used in the database. -func (db *Database) Scheme() string { - return db.backend.Scheme() -} - -// Close flushes the dangling preimages to disk and closes the trie database. -// It is meant to be called when closing the blockchain object, so that all -// resources held can be released correctly. -func (db *Database) Close() error { - db.WritePreimages() - return db.backend.Close() -} - -// WritePreimages flushes all accumulated preimages to disk forcibly. -func (db *Database) WritePreimages() { - if db.preimages != nil { - db.preimages.commit(true) - } -} - -// Preimage retrieves a cached trie node pre-image from preimage store. -func (db *Database) Preimage(hash common.Hash) []byte { - if db.preimages == nil { - return nil - } - return db.preimages.preimage(hash) -} - -// InsertPreimage writes pre-images of trie node to the preimage store. -func (db *Database) InsertPreimage(preimages map[common.Hash][]byte) { - if db.preimages == nil { - return - } - db.preimages.insertPreimage(preimages) -} - -// Cap iteratively flushes old but still referenced trie nodes until the total -// memory usage goes below the given threshold. The held pre-images accumulated -// up to this point will be flushed in case the size exceeds the threshold. -// -// It's only supported by hash-based database and will return an error for others. -func (db *Database) Cap(limit common.StorageSize) error { - hdb, ok := db.backend.(*hashdb.Database) - if !ok { - return errors.New("not supported") - } - if db.preimages != nil { - db.preimages.commit(false) - } - return hdb.Cap(limit) -} - -// Reference adds a new reference from a parent node to a child node. This function -// is used to add reference between internal trie node and external node(e.g. storage -// trie root), all internal trie nodes are referenced together by database itself. -// -// It's only supported by hash-based database and will return an error for others. -func (db *Database) Reference(root common.Hash, parent common.Hash) error { - hdb, ok := db.backend.(*hashdb.Database) - if !ok { - return errors.New("not supported") - } - hdb.Reference(root, parent) - return nil -} - -// Dereference removes an existing reference from a root node. It's only -// supported by hash-based database and will return an error for others. -func (db *Database) Dereference(root common.Hash) error { - hdb, ok := db.backend.(*hashdb.Database) - if !ok { - return errors.New("not supported") - } - hdb.Dereference(root) - return nil -} - -// Recover rollbacks the database to a specified historical point. The state is -// supported as the rollback destination only if it's canonical state and the -// corresponding trie histories are existent. It's only supported by path-based -// database and will return an error for others. -func (db *Database) Recover(target common.Hash) error { - pdb, ok := db.backend.(*pathdb.Database) - if !ok { - return errors.New("not supported") - } - var loader triestate.TrieLoader - if db.config.IsVerkle { - // TODO define verkle loader - log.Crit("Verkle loader is not defined") - } else { - loader = trie.NewMerkleLoader(db) - } - return pdb.Recover(target, loader) -} - -// Recoverable returns the indicator if the specified state is enabled to be -// recovered. It's only supported by path-based database and will return an -// error for others. -func (db *Database) Recoverable(root common.Hash) (bool, error) { - pdb, ok := db.backend.(*pathdb.Database) - if !ok { - return false, errors.New("not supported") - } - return pdb.Recoverable(root), nil -} - -// Disable deactivates the database and invalidates all available state layers -// as stale to prevent access to the persistent state, which is in the syncing -// stage. -// -// It's only supported by path-based database and will return an error for others. -func (db *Database) Disable() error { - pdb, ok := db.backend.(*pathdb.Database) - if !ok { - return errors.New("not supported") - } - return pdb.Disable() -} - -// Enable activates database and resets the state tree with the provided persistent -// state root once the state sync is finished. -func (db *Database) Enable(root common.Hash) error { - pdb, ok := db.backend.(*pathdb.Database) - if !ok { - return errors.New("not supported") - } - return pdb.Enable(root) -} - -// Journal commits an entire diff hierarchy to disk into a single journal entry. -// This is meant to be used during shutdown to persist the snapshot without -// flattening everything down (bad for reorgs). It's only supported by path-based -// database and will return an error for others. -func (db *Database) Journal(root common.Hash) error { - pdb, ok := db.backend.(*pathdb.Database) - if !ok { - return errors.New("not supported") - } - return pdb.Journal(root) -} - -// SetBufferSize sets the node buffer size to the provided value(in bytes). -// It's only supported by path-based database and will return an error for -// others. -func (db *Database) SetBufferSize(size int) error { - pdb, ok := db.backend.(*pathdb.Database) - if !ok { - return errors.New("not supported") - } - return pdb.SetBufferSize(size) -} - -// IsVerkle returns the indicator if the database is holding a verkle tree. -func (db *Database) IsVerkle() bool { - return db.config.IsVerkle -} diff --git a/triedb/database/database.go b/triedb/database/database.go deleted file mode 100644 index 18a8f454e2..0000000000 --- a/triedb/database/database.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2024 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package database - -import ( - "github.com/ethereum/go-ethereum/common" -) - -// Reader wraps the Node method of a backing trie reader. -type Reader interface { - // Node retrieves the trie node blob with the provided trie identifier, - // node path and the corresponding node hash. No error will be returned - // if the node is not found. - Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) -} - -// PreimageStore wraps the methods of a backing store for reading and writing -// trie node preimages. -type PreimageStore interface { - // Preimage retrieves the preimage of the specified hash. - Preimage(hash common.Hash) []byte - - // InsertPreimage commits a set of preimages along with their hashes. - InsertPreimage(preimages map[common.Hash][]byte) -} - -// Database wraps the methods of a backing trie store. -type Database interface { - PreimageStore - - // Reader returns a node reader associated with the specific state. - // An error will be returned if the specified state is not available. - Reader(stateRoot common.Hash) (Reader, error) -} diff --git a/triedb/hashdb/database.go b/triedb/hashdb/database.go index 92053ad583..37947aac89 100644 --- a/triedb/hashdb/database.go +++ b/triedb/hashdb/database.go @@ -33,52 +33,64 @@ import ( "sync" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" "github.com/ava-labs/coreth/utils" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/libevm/metrics" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" + "github.com/ava-labs/libevm/triedb" + "github.com/ava-labs/libevm/triedb/database" + + // Force libevm metrics of the same name to be registered first. + _ "github.com/ava-labs/libevm/triedb/hashdb" ) const ( cacheStatsUpdateFrequency = 1000 // update trie cache stats once per 1000 ops ) +// ====== If resolving merge conflicts ====== +// +// All calls to metrics.NewRegistered*() for metrics also defined in libevm/triedb/hashdb +// have been replaced with metrics.GetOrRegister*() to get metrics already registered in +// libevm/triedb/hashdb or register them here otherwise. These replacements ensure the same +// metrics are shared between the two packages. var ( - memcacheCleanHitMeter = metrics.NewRegisteredMeter("hashdb/memcache/clean/hit", nil) - memcacheCleanMissMeter = metrics.NewRegisteredMeter("hashdb/memcache/clean/miss", nil) - memcacheCleanReadMeter = metrics.NewRegisteredMeter("hashdb/memcache/clean/read", nil) - memcacheCleanWriteMeter = metrics.NewRegisteredMeter("hashdb/memcache/clean/write", nil) - - memcacheDirtyHitMeter = metrics.NewRegisteredMeter("hashdb/memcache/dirty/hit", nil) - memcacheDirtyMissMeter = metrics.NewRegisteredMeter("hashdb/memcache/dirty/miss", nil) - memcacheDirtyReadMeter = metrics.NewRegisteredMeter("hashdb/memcache/dirty/read", nil) - memcacheDirtyWriteMeter = metrics.NewRegisteredMeter("hashdb/memcache/dirty/write", nil) - - memcacheDirtySizeGauge = metrics.NewRegisteredGaugeFloat64("hashdb/memcache/dirty/size", nil) - memcacheDirtyChildSizeGauge = metrics.NewRegisteredGaugeFloat64("hashdb/memcache/dirty/childsize", nil) - memcacheDirtyNodesGauge = metrics.NewRegisteredGauge("hashdb/memcache/dirty/nodes", nil) - - memcacheFlushMeter = metrics.NewRegisteredMeter("hashdb/memcache/flush/count", nil) - memcacheFlushTimeTimer = metrics.NewRegisteredResettingTimer("hashdb/memcache/flush/time", nil) - memcacheFlushLockTimeTimer = metrics.NewRegisteredResettingTimer("hashdb/memcache/flush/locktime", nil) - memcacheFlushNodesMeter = metrics.NewRegisteredMeter("hashdb/memcache/flush/nodes", nil) - memcacheFlushBytesMeter = metrics.NewRegisteredMeter("hashdb/memcache/flush/bytes", nil) - - memcacheGCTimeTimer = metrics.NewRegisteredResettingTimer("hashdb/memcache/gc/time", nil) - memcacheGCNodesMeter = metrics.NewRegisteredMeter("hashdb/memcache/gc/nodes", nil) - memcacheGCBytesMeter = metrics.NewRegisteredMeter("hashdb/memcache/gc/bytes", nil) - - memcacheCommitMeter = metrics.NewRegisteredMeter("hashdb/memcache/commit/count", nil) - memcacheCommitTimeTimer = metrics.NewRegisteredResettingTimer("hashdb/memcache/commit/time", nil) - memcacheCommitLockTimeTimer = metrics.NewRegisteredResettingTimer("hashdb/memcache/commit/locktime", nil) - memcacheCommitNodesMeter = metrics.NewRegisteredMeter("hashdb/memcache/commit/nodes", nil) - memcacheCommitBytesMeter = metrics.NewRegisteredMeter("hashdb/memcache/commit/bytes", nil) + memcacheCleanHitMeter = metrics.GetOrRegisterMeter("hashdb/memcache/clean/hit", nil) + memcacheCleanMissMeter = metrics.GetOrRegisterMeter("hashdb/memcache/clean/miss", nil) + memcacheCleanReadMeter = metrics.GetOrRegisterMeter("hashdb/memcache/clean/read", nil) + memcacheCleanWriteMeter = metrics.GetOrRegisterMeter("hashdb/memcache/clean/write", nil) + + memcacheDirtyHitMeter = metrics.GetOrRegisterMeter("hashdb/memcache/dirty/hit", nil) + memcacheDirtyMissMeter = metrics.GetOrRegisterMeter("hashdb/memcache/dirty/miss", nil) + memcacheDirtyReadMeter = metrics.GetOrRegisterMeter("hashdb/memcache/dirty/read", nil) + memcacheDirtyWriteMeter = metrics.GetOrRegisterMeter("hashdb/memcache/dirty/write", nil) + + memcacheDirtySizeGauge = metrics.GetOrRegisterGaugeFloat64("hashdb/memcache/dirty/size", nil) + memcacheDirtyChildSizeGauge = metrics.GetOrRegisterGaugeFloat64("hashdb/memcache/dirty/childsize", nil) + memcacheDirtyNodesGauge = metrics.GetOrRegisterGauge("hashdb/memcache/dirty/nodes", nil) + + memcacheFlushMeter = metrics.GetOrRegisterMeter("hashdb/memcache/flush/count", nil) + memcacheFlushTimeTimer = metrics.GetOrRegisterResettingTimer("hashdb/memcache/flush/time", nil) + memcacheFlushLockTimeTimer = metrics.GetOrRegisterResettingTimer("hashdb/memcache/flush/locktime", nil) + memcacheFlushNodesMeter = metrics.GetOrRegisterMeter("hashdb/memcache/flush/nodes", nil) + memcacheFlushBytesMeter = metrics.GetOrRegisterMeter("hashdb/memcache/flush/bytes", nil) + + memcacheGCTimeTimer = metrics.GetOrRegisterResettingTimer("hashdb/memcache/gc/time", nil) + memcacheGCNodesMeter = metrics.GetOrRegisterMeter("hashdb/memcache/gc/nodes", nil) + memcacheGCBytesMeter = metrics.GetOrRegisterMeter("hashdb/memcache/gc/bytes", nil) + + memcacheCommitMeter = metrics.GetOrRegisterMeter("hashdb/memcache/commit/count", nil) + memcacheCommitTimeTimer = metrics.GetOrRegisterResettingTimer("hashdb/memcache/commit/time", nil) + memcacheCommitLockTimeTimer = metrics.GetOrRegisterResettingTimer("hashdb/memcache/commit/locktime", nil) + memcacheCommitNodesMeter = metrics.GetOrRegisterMeter("hashdb/memcache/commit/nodes", nil) + memcacheCommitBytesMeter = metrics.GetOrRegisterMeter("hashdb/memcache/commit/bytes", nil) ) // ChildResolver defines the required method to decode the provided @@ -102,6 +114,10 @@ type Config struct { ReferenceRootAtomicallyOnUpdate bool // Whether to reference the root node on update } +func (c Config) BackendConstructor(diskdb ethdb.Database) triedb.DBOverride { + return New(diskdb, &c, trie.MerkleResolver{}) +} + // Defaults is the default setting for database if it's not specified. // Notably, clean cache is disabled explicitly, var Defaults = &Config{ @@ -726,7 +742,7 @@ func (db *Database) Scheme() string { // Reader retrieves a node reader belonging to the given state root. // An error will be returned if the requested state is not available. -func (db *Database) Reader(root common.Hash) (*reader, error) { +func (db *Database) Reader(root common.Hash) (database.Reader, error) { if _, err := db.node(root); err != nil { return nil, fmt.Errorf("state %#x is not available, %v", root, err) } diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index c4dd69cfcb..f20a1f6298 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -32,14 +32,16 @@ import ( "io" "sync" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" "github.com/ava-labs/coreth/params" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" + "github.com/ava-labs/libevm/triedb" + "github.com/ava-labs/libevm/triedb/database" ) const ( @@ -101,6 +103,10 @@ type Config struct { ReadOnly bool // Flag whether the database is opened in read only mode. } +func (c Config) BackendConstructor(diskdb ethdb.Database) triedb.DBOverride { + return New(diskdb, &c) +} + // sanitize checks the provided user configurations and changes anything that's // unreasonable or unworkable. func (c *Config) sanitize() *Config { @@ -220,7 +226,7 @@ func New(diskdb ethdb.Database, config *Config) *Database { } // Reader retrieves a layer belonging to the given state root. -func (db *Database) Reader(root common.Hash) (layer, error) { +func (db *Database) Reader(root common.Hash) (database.Reader, error) { l := db.tree.get(root) if l == nil { return nil, fmt.Errorf("state %#x is not available", root) diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index 477cc86625..8479d05b83 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -33,14 +33,14 @@ import ( "math/rand" "testing" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/testutil" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie/testutil" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" "github.com/holiman/uint256" "github.com/stretchr/testify/require" ) diff --git a/triedb/pathdb/difflayer.go b/triedb/pathdb/difflayer.go index 5294ef3fb9..eea8dc4126 100644 --- a/triedb/pathdb/difflayer.go +++ b/triedb/pathdb/difflayer.go @@ -30,10 +30,10 @@ import ( "fmt" "sync" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" ) // diffLayer represents a collection of modifications made to the in-memory tries diff --git a/triedb/pathdb/difflayer_test.go b/triedb/pathdb/difflayer_test.go index 9d4022aa95..08f20084eb 100644 --- a/triedb/pathdb/difflayer_test.go +++ b/triedb/pathdb/difflayer_test.go @@ -30,10 +30,10 @@ import ( "bytes" "testing" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/trie/testutil" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/trie/testutil" + "github.com/ava-labs/libevm/trie/trienode" ) func emptyLayer() *diskLayer { diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index b20e2118f1..ab8e19d10e 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -32,12 +32,12 @@ import ( "sync" "github.com/VictoriaMetrics/fastcache" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" "golang.org/x/crypto/sha3" ) diff --git a/triedb/pathdb/errors.go b/triedb/pathdb/errors.go index af6e3464d2..6186091e30 100644 --- a/triedb/pathdb/errors.go +++ b/triedb/pathdb/errors.go @@ -30,8 +30,8 @@ import ( "errors" "fmt" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/common/hexutil" ) var ( diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index 368bfeb869..14e53383a3 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -32,8 +32,8 @@ import ( "errors" "fmt" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/trie/triestate" "golang.org/x/exp/slices" ) diff --git a/triedb/pathdb/history_test.go b/triedb/pathdb/history_test.go index a2fe352187..b034326b68 100644 --- a/triedb/pathdb/history_test.go +++ b/triedb/pathdb/history_test.go @@ -31,11 +31,11 @@ import ( "reflect" "testing" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/testutil" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie/testutil" + "github.com/ava-labs/libevm/trie/triestate" ) // randomStateSet generates a random state change set. diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 13f368cac4..3d4d4ae6c7 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -33,14 +33,14 @@ import ( "io" "time" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/rlp" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/rlp" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" ) var ( diff --git a/triedb/pathdb/layertree.go b/triedb/pathdb/layertree.go index 4ba9a8d0c1..3fc904cdcf 100644 --- a/triedb/pathdb/layertree.go +++ b/triedb/pathdb/layertree.go @@ -31,10 +31,10 @@ import ( "fmt" "sync" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" ) // layerTree is a group of state layers identified by the state root. diff --git a/triedb/pathdb/metrics.go b/triedb/pathdb/metrics.go index 21038ecfc6..fbc37c786b 100644 --- a/triedb/pathdb/metrics.go +++ b/triedb/pathdb/metrics.go @@ -26,36 +26,48 @@ package pathdb -import "github.com/ava-labs/libevm/metrics" +import ( + "github.com/ava-labs/libevm/metrics" -// nolint: unused + // Force libevm metrics of the same name to be registered first. + _ "github.com/ava-labs/libevm/triedb/pathdb" +) + +// ====== If resolving merge conflicts ====== +// +// All calls to metrics.NewRegistered*() for metrics also defined in libevm/triedb/pathdb +// have been replaced with metrics.GetOrRegister*() to get metrics already registered in +// libevm/triedb/pathdb or register them here otherwise. These replacements ensure the same +// metrics are shared between the two packages. +// +//nolint:unused var ( - cleanHitMeter = metrics.NewRegisteredMeter("pathdb/clean/hit", nil) - cleanMissMeter = metrics.NewRegisteredMeter("pathdb/clean/miss", nil) - cleanReadMeter = metrics.NewRegisteredMeter("pathdb/clean/read", nil) - cleanWriteMeter = metrics.NewRegisteredMeter("pathdb/clean/write", nil) - - dirtyHitMeter = metrics.NewRegisteredMeter("pathdb/dirty/hit", nil) - dirtyMissMeter = metrics.NewRegisteredMeter("pathdb/dirty/miss", nil) - dirtyReadMeter = metrics.NewRegisteredMeter("pathdb/dirty/read", nil) - dirtyWriteMeter = metrics.NewRegisteredMeter("pathdb/dirty/write", nil) - dirtyNodeHitDepthHist = metrics.NewRegisteredHistogram("pathdb/dirty/depth", nil, metrics.NewExpDecaySample(1028, 0.015)) - - cleanFalseMeter = metrics.NewRegisteredMeter("pathdb/clean/false", nil) - dirtyFalseMeter = metrics.NewRegisteredMeter("pathdb/dirty/false", nil) - diskFalseMeter = metrics.NewRegisteredMeter("pathdb/disk/false", nil) - - commitTimeTimer = metrics.NewRegisteredTimer("pathdb/commit/time", nil) - commitNodesMeter = metrics.NewRegisteredMeter("pathdb/commit/nodes", nil) - commitBytesMeter = metrics.NewRegisteredMeter("pathdb/commit/bytes", nil) - - gcNodesMeter = metrics.NewRegisteredMeter("pathdb/gc/nodes", nil) - gcBytesMeter = metrics.NewRegisteredMeter("pathdb/gc/bytes", nil) - - diffLayerBytesMeter = metrics.NewRegisteredMeter("pathdb/diff/bytes", nil) - diffLayerNodesMeter = metrics.NewRegisteredMeter("pathdb/diff/nodes", nil) - - historyBuildTimeMeter = metrics.NewRegisteredTimer("pathdb/history/time", nil) - historyDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/data", nil) - historyIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/index", nil) + cleanHitMeter = metrics.GetOrRegisterMeter("pathdb/clean/hit", nil) + cleanMissMeter = metrics.GetOrRegisterMeter("pathdb/clean/miss", nil) + cleanReadMeter = metrics.GetOrRegisterMeter("pathdb/clean/read", nil) + cleanWriteMeter = metrics.GetOrRegisterMeter("pathdb/clean/write", nil) + + dirtyHitMeter = metrics.GetOrRegisterMeter("pathdb/dirty/hit", nil) + dirtyMissMeter = metrics.GetOrRegisterMeter("pathdb/dirty/miss", nil) + dirtyReadMeter = metrics.GetOrRegisterMeter("pathdb/dirty/read", nil) + dirtyWriteMeter = metrics.GetOrRegisterMeter("pathdb/dirty/write", nil) + dirtyNodeHitDepthHist = metrics.GetOrRegisterHistogram("pathdb/dirty/depth", nil, metrics.NewExpDecaySample(1028, 0.015)) + + cleanFalseMeter = metrics.GetOrRegisterMeter("pathdb/clean/false", nil) + dirtyFalseMeter = metrics.GetOrRegisterMeter("pathdb/dirty/false", nil) + diskFalseMeter = metrics.GetOrRegisterMeter("pathdb/disk/false", nil) + + commitTimeTimer = metrics.GetOrRegisterTimer("pathdb/commit/time", nil) + commitNodesMeter = metrics.GetOrRegisterMeter("pathdb/commit/nodes", nil) + commitBytesMeter = metrics.GetOrRegisterMeter("pathdb/commit/bytes", nil) + + gcNodesMeter = metrics.GetOrRegisterMeter("pathdb/gc/nodes", nil) + gcBytesMeter = metrics.GetOrRegisterMeter("pathdb/gc/bytes", nil) + + diffLayerBytesMeter = metrics.GetOrRegisterMeter("pathdb/diff/bytes", nil) + diffLayerNodesMeter = metrics.GetOrRegisterMeter("pathdb/diff/nodes", nil) + + historyBuildTimeMeter = metrics.GetOrRegisterTimer("pathdb/history/time", nil) + historyDataBytesMeter = metrics.GetOrRegisterMeter("pathdb/history/bytes/data", nil) + historyIndexBytesMeter = metrics.GetOrRegisterMeter("pathdb/history/bytes/index", nil) ) diff --git a/triedb/pathdb/nodebuffer.go b/triedb/pathdb/nodebuffer.go index 178e40821e..54466cc51f 100644 --- a/triedb/pathdb/nodebuffer.go +++ b/triedb/pathdb/nodebuffer.go @@ -31,12 +31,12 @@ import ( "time" "github.com/VictoriaMetrics/fastcache" - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/rawdb" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/ethdb" + "github.com/ava-labs/libevm/log" + "github.com/ava-labs/libevm/trie/trienode" ) // nodebuffer is a collection of modified trie nodes to aggregate the disk diff --git a/triedb/pathdb/testutils.go b/triedb/pathdb/testutils.go index 395e250f7d..2e2ef3f96c 100644 --- a/triedb/pathdb/testutils.go +++ b/triedb/pathdb/testutils.go @@ -30,11 +30,11 @@ import ( "bytes" "fmt" - "github.com/ava-labs/coreth/core/types" - "github.com/ava-labs/coreth/trie/trienode" - "github.com/ava-labs/coreth/trie/triestate" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/core/types" + "github.com/ava-labs/libevm/crypto" + "github.com/ava-labs/libevm/trie/trienode" + "github.com/ava-labs/libevm/trie/triestate" "golang.org/x/exp/slices" ) diff --git a/triedb/preimages.go b/triedb/preimages.go deleted file mode 100644 index adb3857ab3..0000000000 --- a/triedb/preimages.go +++ /dev/null @@ -1,107 +0,0 @@ -// (c) 2022, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2022 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package triedb - -import ( - "sync" - - "github.com/ava-labs/coreth/core/rawdb" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/ethdb" -) - -const defaultPreimagesLimit = 4 * 1024 * 1024 // 4 MB - -// preimageStore is the store for caching preimages of node key. -type preimageStore struct { - lock sync.RWMutex - disk ethdb.KeyValueStore - preimages map[common.Hash][]byte // Preimages of nodes from the secure trie - preimagesSize common.StorageSize // Storage size of the preimages cache -} - -// newPreimageStore initializes the store for caching preimages. -func newPreimageStore(disk ethdb.KeyValueStore) *preimageStore { - return &preimageStore{ - disk: disk, - preimages: make(map[common.Hash][]byte), - } -} - -// insertPreimage writes a new trie node pre-image to the memory database if it's -// yet unknown. The method will NOT make a copy of the slice, only use if the -// preimage will NOT be changed later on. -func (store *preimageStore) insertPreimage(preimages map[common.Hash][]byte) { - store.lock.Lock() - defer store.lock.Unlock() - - for hash, preimage := range preimages { - if _, ok := store.preimages[hash]; ok { - continue - } - store.preimages[hash] = preimage - store.preimagesSize += common.StorageSize(common.HashLength + len(preimage)) - } -} - -// preimage retrieves a cached trie node pre-image from memory. If it cannot be -// found cached, the method queries the persistent database for the content. -func (store *preimageStore) preimage(hash common.Hash) []byte { - store.lock.RLock() - preimage := store.preimages[hash] - store.lock.RUnlock() - - if preimage != nil { - return preimage - } - return rawdb.ReadPreimage(store.disk, hash) -} - -// commit flushes the cached preimages into the disk. -func (store *preimageStore) commit(force bool) error { - store.lock.Lock() - defer store.lock.Unlock() - - if store.preimagesSize <= defaultPreimagesLimit && !force { - return nil - } - batch := store.disk.NewBatch() - rawdb.WritePreimages(batch, store.preimages) - if err := batch.Write(); err != nil { - return err - } - store.preimages, store.preimagesSize = make(map[common.Hash][]byte), 0 - return nil -} - -// size returns the current storage size of accumulated preimages. -func (store *preimageStore) size() common.StorageSize { - store.lock.RLock() - defer store.lock.RUnlock() - - return store.preimagesSize -} diff --git a/utils/address_range.go b/utils/address_range.go index 940c39e8a1..a10794f03d 100644 --- a/utils/address_range.go +++ b/utils/address_range.go @@ -6,7 +6,7 @@ package utils import ( "bytes" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" ) // AddressRange represents a continuous range of addresses diff --git a/utils/bytes.go b/utils/bytes.go index 54258b20f4..86382cf156 100644 --- a/utils/bytes.go +++ b/utils/bytes.go @@ -3,7 +3,7 @@ package utils -import "github.com/ethereum/go-ethereum/common" +import "github.com/ava-labs/libevm/common" // IncrOne increments bytes value by one func IncrOne(bytes []byte) { diff --git a/utils/bytes_test.go b/utils/bytes_test.go index b1bbc8fa6b..7b4fc9d05c 100644 --- a/utils/bytes_test.go +++ b/utils/bytes_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/ava-labs/avalanchego/utils" - "github.com/ethereum/go-ethereum/common" + "github.com/ava-labs/libevm/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) diff --git a/utils/key.go b/utils/key.go new file mode 100644 index 0000000000..cc4efa6751 --- /dev/null +++ b/utils/key.go @@ -0,0 +1,32 @@ +// (c) 2024, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package utils + +import ( + "crypto/ecdsa" + "crypto/rand" + "testing" + + "github.com/ava-labs/libevm/common" + "github.com/ava-labs/libevm/crypto" + "github.com/stretchr/testify/require" +) + +// Key contains an ecdsa private key field as well as an address field +// obtained from converting the ecdsa public key. +type Key struct { + Address common.Address + PrivateKey *ecdsa.PrivateKey +} + +// NewKey generates a new key pair and returns a pointer to a [Key]. +func NewKey(t *testing.T) *Key { + t.Helper() + privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) + require.NoError(t, err) + return &Key{ + Address: crypto.PubkeyToAddress(privateKeyECDSA.PublicKey), + PrivateKey: privateKeyECDSA, + } +} diff --git a/vmerrs/vmerrs.go b/vmerrs/vmerrs.go deleted file mode 100644 index 4a7afcfd1f..0000000000 --- a/vmerrs/vmerrs.go +++ /dev/null @@ -1,50 +0,0 @@ -// (c) 2019-2020, Ava Labs, Inc. -// -// This file is a derived work, based on the go-ethereum library whose original -// notices appear below. -// -// It is distributed under a license compatible with the licensing terms of the -// original code from which it is derived. -// -// Much love to the original authors for their work. -// ********** -// Copyright 2014 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package vmerrs - -import ( - "errors" -) - -// List evm execution errors -var ( - ErrOutOfGas = errors.New("out of gas") - ErrCodeStoreOutOfGas = errors.New("contract creation code storage out of gas") - ErrDepth = errors.New("max call depth exceeded") - ErrInsufficientBalance = errors.New("insufficient balance for transfer") - ErrContractAddressCollision = errors.New("contract address collision") - ErrExecutionReverted = errors.New("execution reverted") - ErrMaxInitCodeSizeExceeded = errors.New("max initcode size exceeded") - ErrMaxCodeSizeExceeded = errors.New("max code size exceeded") - ErrInvalidJump = errors.New("invalid jump destination") - ErrWriteProtection = errors.New("write protection") - ErrReturnDataOutOfBounds = errors.New("return data out of bounds") - ErrGasUintOverflow = errors.New("gas uint64 overflow") - ErrInvalidCode = errors.New("invalid code: must not begin with 0xef") - ErrNonceUintOverflow = errors.New("nonce uint64 overflow") - ErrAddrProhibited = errors.New("prohibited address cannot be sender or created contract address") -) diff --git a/warp/aggregator/aggregator.go b/warp/aggregator/aggregator.go index 9c6c3aa322..9cc66fae38 100644 --- a/warp/aggregator/aggregator.go +++ b/warp/aggregator/aggregator.go @@ -7,7 +7,7 @@ import ( "context" "fmt" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/avalanchego/utils/set" diff --git a/warp/backend.go b/warp/backend.go index d35c96b8fb..77167f3fd8 100644 --- a/warp/backend.go +++ b/warp/backend.go @@ -15,7 +15,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" avalancheWarp "github.com/ava-labs/avalanchego/vms/platformvm/warp" "github.com/ava-labs/avalanchego/vms/platformvm/warp/payload" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) var ( diff --git a/warp/client.go b/warp/client.go index 90633d6b47..55d99621a4 100644 --- a/warp/client.go +++ b/warp/client.go @@ -9,7 +9,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/coreth/rpc" - "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ava-labs/libevm/common/hexutil" ) var _ Client = (*client)(nil) diff --git a/warp/handlers/signature_request.go b/warp/handlers/signature_request.go index bb9c2c7855..9a5dbfd77f 100644 --- a/warp/handlers/signature_request.go +++ b/warp/handlers/signature_request.go @@ -12,7 +12,7 @@ import ( "github.com/ava-labs/avalanchego/utils/crypto/bls" "github.com/ava-labs/coreth/plugin/evm/message" "github.com/ava-labs/coreth/warp" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/log" ) // SignatureRequestHandler serves warp signature requests. It is a peer.RequestHandler for message.MessageSignatureRequest. diff --git a/warp/service.go b/warp/service.go index 01123950ff..6b16354a70 100644 --- a/warp/service.go +++ b/warp/service.go @@ -15,8 +15,8 @@ import ( "github.com/ava-labs/coreth/peer" "github.com/ava-labs/coreth/warp/aggregator" warpValidators "github.com/ava-labs/coreth/warp/validators" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/log" + "github.com/ava-labs/libevm/common/hexutil" + "github.com/ava-labs/libevm/log" ) var errNoValidators = errors.New("cannot aggregate signatures from subnet with no validators")