mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-23 23:24:30 +00:00
accounts/abi/bind/backends: add TransactionByHash to SimulatedBackend (#19026)
This commit is contained in:
parent
43e6c8ecdc
commit
99092ac54f
2 changed files with 87 additions and 17 deletions
|
|
@ -26,7 +26,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain"
|
||||
ethereum "github.com/XinFinOrg/XDPoSChain"
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCx"
|
||||
"github.com/XinFinOrg/XDPoSChain/XDCxlending"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts"
|
||||
|
|
@ -265,6 +265,24 @@ func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common
|
|||
return receipt, nil
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, isPending bool, err error) {
|
||||
tx = b.pendingBlock.Transaction(txHash)
|
||||
if tx != nil {
|
||||
return tx, true, nil
|
||||
}
|
||||
|
||||
tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash)
|
||||
if tx != nil {
|
||||
return tx, false, nil
|
||||
}
|
||||
|
||||
return nil, false, ethereum.ErrNotFound
|
||||
}
|
||||
|
||||
// HeaderByNumber returns a block header from the current canonical chain. If number is
|
||||
// nil, the latest known header is returned.
|
||||
func (b *SimulatedBackend) HeaderByNumber(ctx context.Context, block *big.Int) (*types.Header, error) {
|
||||
|
|
@ -287,7 +305,7 @@ func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Ad
|
|||
}
|
||||
|
||||
// CallContract executes a contract call.
|
||||
func (b *SimulatedBackend) CallContract(ctx context.Context, call XDPoSChain.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
|
|
@ -306,7 +324,7 @@ func (b *SimulatedBackend) CallContract(ctx context.Context, call XDPoSChain.Cal
|
|||
}
|
||||
|
||||
// PendingCallContract executes a contract call on the pending state.
|
||||
func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call XDPoSChain.CallMsg) ([]byte, error) {
|
||||
func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot())
|
||||
|
|
@ -344,7 +362,7 @@ func (b *SimulatedBackend) SuggestGasTipCap(ctx context.Context) (*big.Int, erro
|
|||
|
||||
// EstimateGas executes the requested code against the currently pending block/state and
|
||||
// returns the used amount of gas.
|
||||
func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.CallMsg) (uint64, error) {
|
||||
func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
|
|
@ -422,7 +440,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call XDPoSChain.Call
|
|||
|
||||
// callContract implements common code between normal and pending contract calls.
|
||||
// state is modified during execution, make sure to copy it if necessary.
|
||||
func (b *SimulatedBackend) callContract(ctx context.Context, call XDPoSChain.CallMsg, block *types.Block, statedb *state.StateDB) (*core.ExecutionResult, error) {
|
||||
func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) (*core.ExecutionResult, error) {
|
||||
// Gas prices post 1559 need to be initialized
|
||||
if call.GasPrice != nil && (call.GasFeeCap != nil || call.GasTipCap != nil) {
|
||||
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
|
||||
|
|
@ -523,7 +541,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transa
|
|||
// returning all the results in one batch.
|
||||
//
|
||||
// TODO(karalabe): Deprecate when the subscription one can return past data too.
|
||||
func (b *SimulatedBackend) FilterLogs(ctx context.Context, query XDPoSChain.FilterQuery) ([]types.Log, error) {
|
||||
func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) {
|
||||
var filter *filters.Filter
|
||||
if query.BlockHash != nil {
|
||||
// Block filter requested, construct a single-shot filter
|
||||
|
|
@ -555,7 +573,7 @@ func (b *SimulatedBackend) FilterLogs(ctx context.Context, query XDPoSChain.Filt
|
|||
|
||||
// SubscribeFilterLogs creates a background log filtering operation, returning a
|
||||
// subscription immediately, which can be used to stream the found events.
|
||||
func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query XDPoSChain.FilterQuery, ch chan<- types.Log) (XDPoSChain.Subscription, error) {
|
||||
func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) {
|
||||
// Subscribe to contract events
|
||||
sink := make(chan []*types.Log)
|
||||
|
||||
|
|
@ -612,7 +630,7 @@ func (b *SimulatedBackend) GetBlockChain() *core.BlockChain {
|
|||
|
||||
// callMsg implements core.Message to allow passing it as a transaction simulator.
|
||||
type callMsg struct {
|
||||
XDPoSChain.CallMsg
|
||||
ethereum.CallMsg
|
||||
}
|
||||
|
||||
func (m callMsg) From() common.Address { return m.CallMsg.From }
|
||||
|
|
|
|||
|
|
@ -23,15 +23,67 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain"
|
||||
ethereum "github.com/XinFinOrg/XDPoSChain"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi"
|
||||
"github.com/XinFinOrg/XDPoSChain/accounts/abi/bind"
|
||||
"github.com/XinFinOrg/XDPoSChain/common"
|
||||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/types"
|
||||
"github.com/XinFinOrg/XDPoSChain/crypto"
|
||||
"github.com/XinFinOrg/XDPoSChain/params"
|
||||
)
|
||||
|
||||
func TestSimulatedBackend(t *testing.T) {
|
||||
var gasLimit uint64 = 8000029
|
||||
key, _ := crypto.GenerateKey() // nolint: gosec
|
||||
auth := bind.NewKeyedTransactor(key)
|
||||
genAlloc := make(core.GenesisAlloc)
|
||||
genAlloc[auth.From] = core.GenesisAccount{Balance: big.NewInt(9223372036854775807)}
|
||||
|
||||
sim := NewSimulatedBackend(genAlloc, gasLimit)
|
||||
|
||||
// should return an error if the tx is not found
|
||||
txHash := common.HexToHash("2")
|
||||
_, isPending, err := sim.TransactionByHash(context.Background(), txHash)
|
||||
|
||||
if isPending {
|
||||
t.Fatal("transaction should not be pending")
|
||||
}
|
||||
if err != ethereum.ErrNotFound {
|
||||
t.Fatalf("err should be `ethereum.ErrNotFound` but received %v", err)
|
||||
}
|
||||
|
||||
// generate a transaction and confirm you can retrieve it
|
||||
code := `6060604052600a8060106000396000f360606040526008565b00`
|
||||
var gas uint64 = 3000000
|
||||
tx := types.NewContractCreation(0, big.NewInt(0), gas, big.NewInt(1), common.FromHex(code))
|
||||
tx, _ = types.SignTx(tx, types.HomesteadSigner{}, key)
|
||||
|
||||
err = sim.SendTransaction(context.Background(), tx)
|
||||
if err != nil {
|
||||
t.Fatal("error sending transaction")
|
||||
}
|
||||
|
||||
txHash = tx.Hash()
|
||||
_, isPending, err = sim.TransactionByHash(context.Background(), txHash)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting transaction with hash: %v", txHash.String())
|
||||
}
|
||||
if !isPending {
|
||||
t.Fatal("transaction should have pending status")
|
||||
}
|
||||
|
||||
sim.Commit()
|
||||
tx, isPending, err = sim.TransactionByHash(context.Background(), txHash)
|
||||
if err != nil {
|
||||
t.Fatalf("error getting transaction with hash: %v", txHash.String())
|
||||
}
|
||||
if isPending {
|
||||
t.Fatal("transaction should not have pending status")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
||||
/*
|
||||
pragma solidity ^0.6.4;
|
||||
|
|
@ -69,11 +121,11 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
|
||||
var cases = []struct {
|
||||
name string
|
||||
message XDPoSChain.CallMsg
|
||||
message ethereum.CallMsg
|
||||
expect uint64
|
||||
expectError error
|
||||
}{
|
||||
{"plain transfer(valid)", XDPoSChain.CallMsg{
|
||||
{"plain transfer(valid)", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &addr,
|
||||
Gas: 0,
|
||||
|
|
@ -82,7 +134,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
Data: nil,
|
||||
}, params.TxGas, nil},
|
||||
|
||||
{"plain transfer(invalid)", XDPoSChain.CallMsg{
|
||||
{"plain transfer(invalid)", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &contractAddr,
|
||||
Gas: 0,
|
||||
|
|
@ -91,7 +143,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
Data: nil,
|
||||
}, 0, errors.New("always failing transaction (execution reverted)")},
|
||||
|
||||
{"Revert", XDPoSChain.CallMsg{
|
||||
{"Revert", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &contractAddr,
|
||||
Gas: 0,
|
||||
|
|
@ -100,7 +152,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
Data: common.Hex2Bytes("d8b98391"),
|
||||
}, 0, errors.New("always failing transaction (execution reverted) (revert reason)")},
|
||||
|
||||
{"PureRevert", XDPoSChain.CallMsg{
|
||||
{"PureRevert", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &contractAddr,
|
||||
Gas: 0,
|
||||
|
|
@ -109,7 +161,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
Data: common.Hex2Bytes("aa8b1d30"),
|
||||
}, 0, errors.New("always failing transaction (execution reverted)")},
|
||||
|
||||
{"OOG", XDPoSChain.CallMsg{
|
||||
{"OOG", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &contractAddr,
|
||||
Gas: 100000,
|
||||
|
|
@ -118,7 +170,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
Data: common.Hex2Bytes("50f6fe34"),
|
||||
}, 0, errors.New("gas required exceeds allowance (100000)")},
|
||||
|
||||
{"Assert", XDPoSChain.CallMsg{
|
||||
{"Assert", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &contractAddr,
|
||||
Gas: 100000,
|
||||
|
|
@ -127,7 +179,7 @@ func TestSimulatedBackend_EstimateGas(t *testing.T) {
|
|||
Data: common.Hex2Bytes("b9b046f9"),
|
||||
}, 0, errors.New("always failing transaction (invalid opcode: INVALID)")},
|
||||
|
||||
{"Valid", XDPoSChain.CallMsg{
|
||||
{"Valid", ethereum.CallMsg{
|
||||
From: addr,
|
||||
To: &contractAddr,
|
||||
Gas: 100000,
|
||||
|
|
|
|||
Loading…
Reference in a new issue