diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go index d13b919641..34530a6455 100644 --- a/accounts/abi/bind/backend.go +++ b/accounts/abi/bind/backend.go @@ -36,10 +36,6 @@ var ( // on a backend that doesn't implement PendingContractCaller. ErrNoPendingState = errors.New("backend does not support pending state") - // ErrNoBlockHashState is raised when attempting to perform a block hash action - // on a backend that doesn't implement BlockHashContractCaller. - ErrNoBlockHashState = errors.New("backend does not support block hash state") - // ErrNoCodeAfterDeploy is returned by WaitDeployed if contract creation leaves // an empty contract behind. ErrNoCodeAfterDeploy = errors.New("no contract code after deployment") @@ -68,17 +64,6 @@ type PendingContractCaller interface { PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) } -// BlockHashContractCaller defines methods to perform contract calls on a specific block hash. -// Call will try to discover this interface when access to a block by hash is requested. -// If the backend does not support the block hash state, Call returns ErrNoBlockHashState. -type BlockHashContractCaller interface { - // CodeAtHash returns the code of the given account in the state at the specified block hash. - CodeAtHash(ctx context.Context, contract common.Address, blockHash common.Hash) ([]byte, error) - - // CallContractAtHash executes an Ethereum contract all against the state at the specified block hash. - CallContractAtHash(ctx context.Context, call ethereum.CallMsg, blockHash common.Hash) ([]byte, error) -} - // ContractTransactor defines the methods needed to allow operating with a contract // on a write only basis. Besides the transacting method, the remainder are helpers // used when the user does not provide some needed values, but rather leaves it up diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index a26ee12e0a..6892668cbe 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -50,7 +50,6 @@ var _ bind.ContractBackend = (*SimulatedBackend)(nil) var ( errBlockNumberUnsupported = errors.New("simulatedBackend cannot access blocks other than the latest block") - errBlockHashUnsupported = errors.New("simulatedBackend cannot access blocks by hash other than the latest block") errBlockDoesNotExist = errors.New("block does not exist in blockchain") errTransactionDoesNotExist = errors.New("transaction does not exist") ) @@ -203,24 +202,6 @@ func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, return stateDB.GetCode(contract), nil } -// CodeAtHash returns the code associated with a certain account in the blockchain. -func (b *SimulatedBackend) CodeAtHash(ctx context.Context, contract common.Address, blockHash common.Hash) ([]byte, error) { - b.mu.Lock() - defer b.mu.Unlock() - - header, err := b.headerByHash(blockHash) - if err != nil { - return nil, err - } - - stateDB, err := b.blockchain.StateAt(header.Root) - if err != nil { - return nil, err - } - - return stateDB.GetCode(contract), nil -} - // BalanceAt returns the wei balance of a certain account in the blockchain. func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (*big.Int, error) { b.mu.Lock() @@ -339,11 +320,7 @@ func (b *SimulatedBackend) blockByNumber(ctx context.Context, number *big.Int) ( func (b *SimulatedBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { b.mu.Lock() defer b.mu.Unlock() - return b.headerByHash(hash) -} -// headerByHash retrieves a header from the database by hash without Lock. -func (b *SimulatedBackend) headerByHash(hash common.Hash) (*types.Header, error) { if hash == b.pendingBlock.Hash() { return b.pendingBlock.Header(), nil } @@ -459,22 +436,6 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallM if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number) != 0 { return nil, errBlockNumberUnsupported } - return b.callContractAtHead(ctx, call) -} - -// CallContractAtHash executes a contract call on a specific block hash. -func (b *SimulatedBackend) CallContractAtHash(ctx context.Context, call ethereum.CallMsg, blockHash common.Hash) ([]byte, error) { - b.mu.Lock() - defer b.mu.Unlock() - - if blockHash != b.blockchain.CurrentBlock().Hash() { - return nil, errBlockHashUnsupported - } - return b.callContractAtHead(ctx, call) -} - -// callContractAtHead executes a contract call against the latest block state. -func (b *SimulatedBackend) callContractAtHead(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { stateDB, err := b.blockchain.State() if err != nil { return nil, err diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index a41d168411..11900a6cf5 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -996,43 +996,6 @@ func TestCodeAt(t *testing.T) { } } -func TestCodeAtHash(t *testing.T) { - testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - sim := simTestBackend(testAddr) - defer sim.Close() - bgCtx := context.Background() - code, err := sim.CodeAtHash(bgCtx, testAddr, sim.Blockchain().CurrentHeader().Hash()) - if err != nil { - t.Errorf("could not get code at test addr: %v", err) - } - if len(code) != 0 { - t.Errorf("got code for account that does not have contract code") - } - - parsed, err := abi.JSON(strings.NewReader(abiJSON)) - if err != nil { - t.Errorf("could not get code at test addr: %v", err) - } - auth, _ := bind.NewKeyedTransactorWithChainID(testKey, big.NewInt(1337)) - contractAddr, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(abiBin), sim) - if err != nil { - t.Errorf("could not deploy contract: %v tx: %v contract: %v", err, tx, contract) - } - - blockHash := sim.Commit() - code, err = sim.CodeAtHash(bgCtx, contractAddr, blockHash) - if err != nil { - t.Errorf("could not get code at test addr: %v", err) - } - if len(code) == 0 { - t.Errorf("did not get code for account that has contract code") - } - // ensure code received equals code deployed - if !bytes.Equal(code, common.FromHex(deployedCode)) { - t.Errorf("code received did not match expected deployed code:\n expected %v\n actual %v", common.FromHex(deployedCode), code) - } -} - // When receive("X") is called with sender 0x00... and value 1, it produces this tx receipt: // // receipt{status=1 cgas=23949 bloom=00000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000040200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 logs=[log: b6818c8064f645cd82d99b59a1a267d6d61117ef [75fd880d39c1daf53b6547ab6cb59451fc6452d27caa90e5b6649dd8293b9eed] 000000000000000000000000376c47978271565f56deb45495afa69e59c16ab200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000158 9ae378b6d4409eada347a5dc0c180f186cb62dc68fcc0f043425eb917335aa28 0 95d429d309bb9d753954195fe2d69bd140b4ae731b9b5b605c34323de162cf00 0]} @@ -1075,7 +1038,7 @@ func TestPendingAndCallContract(t *testing.T) { t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) } - blockHash := sim.Commit() + sim.Commit() // make sure you can call the contract res, err = sim.CallContract(bgCtx, ethereum.CallMsg{ @@ -1093,23 +1056,6 @@ func TestPendingAndCallContract(t *testing.T) { if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) } - - // make sure you can call the contract by hash - res, err = sim.CallContractAtHash(bgCtx, ethereum.CallMsg{ - From: testAddr, - To: &addr, - Data: input, - }, blockHash) - if err != nil { - t.Errorf("could not call receive method on contract: %v", err) - } - if len(res) == 0 { - t.Errorf("result of contract call was empty: %v", res) - } - - if !bytes.Equal(res, expectedReturn) || !strings.Contains(string(res), "hello world") { - t.Errorf("response from calling contract was expected to be 'hello world' instead received %v", string(res)) - } } // This test is based on the following contract: diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go index 6da15f147c..b03f431f77 100644 --- a/accounts/abi/bind/base.go +++ b/accounts/abi/bind/base.go @@ -48,7 +48,6 @@ type CallOpts struct { Pending bool // Whether to operate on the pending state or the last known one From common.Address // Optional the sender address, otherwise the first account is used BlockNumber *big.Int // Optional the block number on which the call should be performed - BlockHash common.Hash // Optional the block hash on which the call should be performed Context context.Context // Network context to support cancellation and timeouts (nil = no timeout) } @@ -190,23 +189,6 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri return ErrNoCode } } - } else if opts.BlockHash != (common.Hash{}) { - bh, ok := c.caller.(BlockHashContractCaller) - if !ok { - return ErrNoBlockHashState - } - output, err = bh.CallContractAtHash(ctx, msg, opts.BlockHash) - if err != nil { - return err - } - if len(output) == 0 { - // Make sure we have a contract to operate on, and bail out otherwise. - if code, err = bh.CodeAtHash(ctx, c.address, opts.BlockHash); err != nil { - return err - } else if len(code) == 0 { - return ErrNoCode - } - } } else { output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber) if err != nil { diff --git a/accounts/abi/bind/base_test.go b/accounts/abi/bind/base_test.go index 44552ab121..ca0128148f 100644 --- a/accounts/abi/bind/base_test.go +++ b/accounts/abi/bind/base_test.go @@ -114,26 +114,6 @@ func (mc *mockPendingCaller) PendingCallContract(ctx context.Context, call ether return mc.pendingCallContractBytes, mc.pendingCallContractErr } -type mockBlockHashCaller struct { - *mockCaller - codeAtHashBytes []byte - codeAtHashErr error - codeAtHashCalled bool - callContractAtHashCalled bool - callContractAtHashBytes []byte - callContractAtHashErr error -} - -func (mc *mockBlockHashCaller) CodeAtHash(ctx context.Context, contract common.Address, hash common.Hash) ([]byte, error) { - mc.codeAtHashCalled = true - return mc.codeAtHashBytes, mc.codeAtHashErr -} - -func (mc *mockBlockHashCaller) CallContractAtHash(ctx context.Context, call ethereum.CallMsg, hash common.Hash) ([]byte, error) { - mc.callContractAtHashCalled = true - return mc.callContractAtHashBytes, mc.callContractAtHashErr -} - func TestPassingBlockNumber(t *testing.T) { mc := &mockPendingCaller{ mockCaller: &mockCaller{ @@ -420,15 +400,6 @@ func TestCall(t *testing.T) { Pending: true, }, method: method, - }, { - name: "ok hash", - mc: &mockBlockHashCaller{ - codeAtHashBytes: []byte{0}, - }, - opts: &bind.CallOpts{ - BlockHash: common.Hash{0xaa}, - }, - method: method, }, { name: "pack error, no method", mc: new(mockCaller), @@ -442,14 +413,6 @@ func TestCall(t *testing.T) { }, method: method, wantErrExact: bind.ErrNoPendingState, - }, { - name: "interface error, blockHash but not a BlockHashContractCaller", - mc: new(mockCaller), - opts: &bind.CallOpts{ - BlockHash: common.Hash{0xaa}, - }, - method: method, - wantErrExact: bind.ErrNoBlockHashState, }, { name: "pending call canceled", mc: &mockPendingCaller{ @@ -497,34 +460,6 @@ func TestCall(t *testing.T) { mc: new(mockCaller), method: method, wantErrExact: bind.ErrNoCode, - }, { - name: "call contract at hash error", - mc: &mockBlockHashCaller{ - callContractAtHashErr: context.DeadlineExceeded, - }, - opts: &bind.CallOpts{ - BlockHash: common.Hash{0xaa}, - }, - method: method, - wantErrExact: context.DeadlineExceeded, - }, { - name: "code at error", - mc: &mockBlockHashCaller{ - codeAtHashErr: errors.New(""), - }, - opts: &bind.CallOpts{ - BlockHash: common.Hash{0xaa}, - }, - method: method, - wantErr: true, - }, { - name: "no code at hash", - mc: new(mockBlockHashCaller), - opts: &bind.CallOpts{ - BlockHash: common.Hash{0xaa}, - }, - method: method, - wantErrExact: bind.ErrNoCode, }, { name: "unpack error missing arg", mc: &mockCaller{ diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 83c89a2fd4..af373b9938 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -370,13 +370,6 @@ func (ec *Client) BalanceAt(ctx context.Context, account common.Address, blockNu return (*big.Int)(&result), err } -// BalanceAtHash returns the wei balance of the given account. -func (ec *Client) BalanceAtHash(ctx context.Context, account common.Address, blockHash common.Hash) (*big.Int, error) { - var result hexutil.Big - err := ec.c.CallContext(ctx, &result, "eth_getBalance", account, rpc.BlockNumberOrHashWithHash(blockHash, false)) - return (*big.Int)(&result), err -} - // StorageAt returns the value of key in the contract storage of the given account. // The block number can be nil, in which case the value is taken from the latest known block. func (ec *Client) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { @@ -385,13 +378,6 @@ func (ec *Client) StorageAt(ctx context.Context, account common.Address, key com return result, err } -// StorageAtHash returns the value of key in the contract storage of the given account. -func (ec *Client) StorageAtHash(ctx context.Context, account common.Address, key common.Hash, blockHash common.Hash) ([]byte, error) { - var result hexutil.Bytes - err := ec.c.CallContext(ctx, &result, "eth_getStorageAt", account, key, rpc.BlockNumberOrHashWithHash(blockHash, false)) - return result, err -} - // CodeAt returns the contract code of the given account. // The block number can be nil, in which case the code is taken from the latest known block. func (ec *Client) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { @@ -400,13 +386,6 @@ func (ec *Client) CodeAt(ctx context.Context, account common.Address, blockNumbe return result, err } -// CodeAtHash returns the contract code of the given account. -func (ec *Client) CodeAtHash(ctx context.Context, account common.Address, blockHash common.Hash) ([]byte, error) { - var result hexutil.Bytes - err := ec.c.CallContext(ctx, &result, "eth_getCode", account, rpc.BlockNumberOrHashWithHash(blockHash, false)) - return result, err -} - // NonceAt returns the account nonce of the given account. // The block number can be nil, in which case the nonce is taken from the latest known block. func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { @@ -415,13 +394,6 @@ func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumb return uint64(result), err } -// NonceAtHash returns the account nonce of the given account. -func (ec *Client) NonceAtHash(ctx context.Context, account common.Address, blockHash common.Hash) (uint64, error) { - var result hexutil.Uint64 - err := ec.c.CallContext(ctx, &result, "eth_getTransactionCount", account, rpc.BlockNumberOrHashWithHash(blockHash, false)) - return uint64(result), err -} - // Filters // FilterLogs executes a filter query. diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 4aa25759fb..beaa4240a0 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -584,11 +584,6 @@ func testCallContract(t *testing.T, client *rpc.Client) { func testAtFunctions(t *testing.T, client *rpc.Client) { ec := NewClient(client) - block, err := ec.HeaderByNumber(context.Background(), big.NewInt(1)) - if err != nil { - t.Fatalf("BlockByNumber error: %v", err) - } - // send a transaction for some interesting pending status sendTransaction(ec) time.Sleep(100 * time.Millisecond) @@ -606,13 +601,6 @@ func testAtFunctions(t *testing.T, client *rpc.Client) { if err != nil { t.Fatalf("unexpected error: %v", err) } - hashBalance, err := ec.BalanceAtHash(context.Background(), testAddr, block.Hash()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if balance.Cmp(hashBalance) == 0 { - t.Fatalf("unexpected balance at hash: %v %v", balance, hashBalance) - } penBalance, err := ec.PendingBalanceAt(context.Background(), testAddr) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -625,13 +613,6 @@ func testAtFunctions(t *testing.T, client *rpc.Client) { if err != nil { t.Fatalf("unexpected error: %v", err) } - hashNonce, err := ec.NonceAtHash(context.Background(), testAddr, block.Hash()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if hashNonce == nonce { - t.Fatalf("unexpected nonce at hash: %v %v", nonce, hashNonce) - } penNonce, err := ec.PendingNonceAt(context.Background(), testAddr) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -644,13 +625,6 @@ func testAtFunctions(t *testing.T, client *rpc.Client) { if err != nil { t.Fatalf("unexpected error: %v", err) } - hashStorage, err := ec.StorageAtHash(context.Background(), testAddr, common.Hash{}, block.Hash()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if !bytes.Equal(storage, hashStorage) { - t.Fatalf("unexpected storage at hash: %v %v", storage, hashStorage) - } penStorage, err := ec.PendingStorageAt(context.Background(), testAddr, common.Hash{}) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -663,13 +637,6 @@ func testAtFunctions(t *testing.T, client *rpc.Client) { if err != nil { t.Fatalf("unexpected error: %v", err) } - hashCode, err := ec.CodeAtHash(context.Background(), common.Address{}, block.Hash()) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if !bytes.Equal(code, hashCode) { - t.Fatalf("unexpected code at hash: %v %v", code, hashCode) - } penCode, err := ec.PendingCodeAt(context.Background(), testAddr) if err != nil { t.Fatalf("unexpected error: %v", err)