aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--accounts/abi/bind/backends/simulated.go19
-rw-r--r--accounts/abi/bind/backends/simulated_test.go66
2 files changed, 85 insertions, 0 deletions
diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index 6f46fc149..400227c3a 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -164,6 +164,25 @@ 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.NotFound
+}
+
// PendingCodeAt returns the code associated with an account in the pending state.
func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) {
b.mu.Lock()
diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go
new file mode 100644
index 000000000..ac6e9e228
--- /dev/null
+++ b/accounts/abi/bind/backends/simulated_test.go
@@ -0,0 +1,66 @@
+package backends_test
+
+import (
+ "context"
+ "math/big"
+ "testing"
+
+ ethereum "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind"
+ "github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
+)
+
+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 := backends.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.NotFound {
+ t.Fatalf("err should be `ethereum.NotFound` 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")
+ }
+
+}