From adce2fff5398c4f26e54716ed264765eff60d989 Mon Sep 17 00:00:00 2001 From: Jens W <8270201+DragonDev1906@users.noreply.github.com> Date: Thu, 14 Jul 2022 10:34:16 +0200 Subject: [PATCH] accounts/abi/bind/backends: return hash of new blocks (#25163) Co-authored-by: Jens --- accounts/abi/bind/backends/simulated.go | 9 +- accounts/abi/bind/backends/simulated_test.go | 211 +++---------------- 2 files changed, 32 insertions(+), 188 deletions(-) diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 85efcf30158c..755409158b98 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -108,7 +108,7 @@ func (b *SimulatedBackend) Close() error { // Commit imports all the pending transactions as a single block and starts a // fresh new state. -func (b *SimulatedBackend) Commit() { +func (b *SimulatedBackend) Commit() common.Hash { b.mu.Lock() defer b.mu.Unlock() @@ -130,10 +130,13 @@ func (b *SimulatedBackend) Commit() { if _, err := b.blockchain.InsertChain([]*types.Block{blocks[0]}); err != nil { panic(err) // This cannot happen unless the simulator is wrong, fail in that case } + blockHash := b.pendingBlock.Hash() + // Using the last inserted block here makes it possible to build on a side // chain after a fork. - b.stuckTransactions = remainingTx - b.rollback(blocks[0]) + b.rollback(b.pendingBlock) + + return blockHash } // Rollback aborts all pending transactions, reverting to the last committed state. diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go index 9ac0139ab5aa..b5431bf5cc0b 100644 --- a/accounts/abi/bind/backends/simulated_test.go +++ b/accounts/abi/bind/backends/simulated_test.go @@ -1339,200 +1339,41 @@ func TestForkResendTx(t *testing.T) { } } -// TestLowGasTxNotBeingMined checks that the lower gas fee tx with same nonce does not get mined -// Steps: -// 1. Send a tx lower than the set market gas price -// 2. Commit to chain, check nonce stays the same -// 3. Send a tx meets the market gas price with same nonce. -// 4. Commit to chain -// 5. Check tx2 is not in pending state and nonce has increased -func TestLowGasTxNotBeingMined(t *testing.T) { +func TestCommitReturnValue(t *testing.T) { testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - var gas uint64 = 21000 - sim := simTestBackend(testAddr) defer sim.Close() - var testCases = []struct { - name string - txType byte - }{ - { - name: "LegacyTx", - txType: types.LegacyTxType, - }, - { - name: "dynamicTx", - txType: types.DynamicFeeTxType, - }, - } - for i, test := range testCases { - t.Run(test.name, func(t *testing.T) { - bgCtx := context.Background() - // Create tx and send - head, _ := sim.HeaderByNumber(context.Background(), nil) - tip, err := sim.SuggestGasTipCap(bgCtx) - require.NoError(t, err) - gasPrice := new(big.Int).Add(head.BaseFee, tip) - sim.SetMarketGasPrice(int64(gasPrice.Uint64())) - - lowFeeGas := new(big.Int).Sub(gasPrice, tip) - txValue := big.NewInt(1) - - var lowGasFeeTx *types.Transaction - - if test.txType == types.LegacyTxType { - lowGasFeeTx = types.NewTx(&types.LegacyTx{ - Nonce: uint64(i), - To: &testAddr, - Value: txValue, - GasPrice: lowFeeGas, - Gas: gas, - }) - } else if test.txType == types.DynamicFeeTxType { - lowGasFeeTx = types.NewTx(&types.DynamicFeeTx{ - Nonce: uint64(i), - Gas: gas, - To: &testAddr, - Value: txValue, - GasTipCap: lowFeeGas, - GasFeeCap: lowFeeGas, - }) - } else { - t.Fatal("unexpected txType received") - } + startBlockHeight := sim.blockchain.CurrentBlock().NumberU64() - signedTx, err := types.SignTx(lowGasFeeTx, types.LatestSigner(sim.config), testKey) - require.NoError(t, err) - - // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) - require.NoError(t, err) - sim.Commit() - - // expect nonce be the same because low gas fee tx will not be mined - nonce, err := sim.PendingNonceAt(bgCtx, testAddr) - require.NoError(t, err) - assert.Equal(t, uint64(i), nonce) - - // send tx with higher gas fee - sufficientGasFeeTx := types.NewTx(&types.LegacyTx{ - Nonce: uint64(i), - To: &testAddr, - Value: txValue, - GasPrice: gasPrice, - Gas: gas, - }) - - signedSufficientTx, err := types.SignTx(sufficientGasFeeTx, types.HomesteadSigner{}, testKey) - require.NoError(t, err) - - err = sim.SendTransaction(bgCtx, signedSufficientTx) - require.NoError(t, err) - sim.Commit() - - // the higher gas transaction should have been mined - _, isPending, err := sim.TransactionByHash(bgCtx, signedSufficientTx.Hash()) - require.NoError(t, err) - assert.False(t, isPending) - - // expect nonce has increased - nonce, err = sim.PendingNonceAt(bgCtx, testAddr) - require.NoError(t, err) - assert.Equal(t, uint64(i) + 1, nonce) - }) + // Test if Commit returns the correct block hash + h1 := sim.Commit() + if h1 != sim.blockchain.CurrentBlock().Hash() { + t.Error("Commit did not return the hash of the last block.") } -} - -// TestLowGasTxGetMinedOnceGasFeeDropped checks that lower gas fee txes still stay in mem pool -// and get mined once gas fee requirement has been met -// Steps: -// 1. Send a tx lower than the set market gas price -// 2. Commit to chain, tx does not get mined -// 3. Gas fee drops, commit again -// 4. Check tx get mined -func TestLowGasTxGetMinedOnceGasFeeDropped(t *testing.T) { - var testCases = []struct { - name string - txType byte - }{ - { - name: "LegacyTx", - txType: types.LegacyTxType, - }, - { - name: "dynamicTx", - txType: types.DynamicFeeTxType, - }, - } - testAddr := crypto.PubkeyToAddress(testKey.PublicKey) - var gas uint64 = 21000 - - sim := simTestBackend(testAddr) - defer sim.Close() - for i, test := range testCases { - t.Run(test.name, func(t *testing.T) { - bgCtx := context.Background() - // Create tx and send - head, _ := sim.HeaderByNumber(context.Background(), nil) - tip, err := sim.SuggestGasTipCap(bgCtx) - require.NoError(t, err) - normalGasPrice := new(big.Int).Add(head.BaseFee, tip) - highGasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(5)) - - sim.SetMarketGasPrice(int64(highGasPrice.Uint64())) - - var normalGasFeeTx *types.Transaction - txValue := big.NewInt(1) - - if test.txType == types.LegacyTxType { - normalGasFeeTx = types.NewTx(&types.LegacyTx{ - Nonce: uint64(i), - To: &testAddr, - Value: txValue, - GasPrice: normalGasPrice, - Gas: gas, - }) - } else if test.txType == types.DynamicFeeTxType { - normalGasFeeTx = types.NewTx(&types.DynamicFeeTx{ - Nonce: uint64(i), - Gas: gas, - To: &testAddr, - Value: txValue, - GasTipCap: normalGasPrice, - GasFeeCap: normalGasPrice, - }) - } else { - t.Fatal("unexpected txType received") - } - - signedTx, err := types.SignTx(normalGasFeeTx, types.LatestSigner(sim.config), testKey) - require.NoError(t, err) - - // send tx to simulated backend - err = sim.SendTransaction(bgCtx, signedTx) - require.NoError(t, err) - sim.Commit() - - // check that the nonce stays the same because nothing has been mined - pendingNonce, err := sim.PendingNonceAt(bgCtx, testAddr) - require.NoError(t, err) - assert.Equal(t, uint64(i), pendingNonce) + // Create a block in the original chain (containing a transaction to force different block hashes) + head, _ := sim.HeaderByNumber(context.Background(), nil) // Should be child's, good enough + gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) + _tx := types.NewTransaction(0, testAddr, big.NewInt(1000), params.TxGas, gasPrice, nil) + tx, _ := types.SignTx(_tx, types.HomesteadSigner{}, testKey) + sim.SendTransaction(context.Background(), tx) + h2 := sim.Commit() - // gas fee has dropped - sim.SetMarketGasPrice(int64(normalGasPrice.Uint64())) - sim.Commit() + // Create another block in the original chain + sim.Commit() - // nonce has increased - pendingNonce, err = sim.PendingNonceAt(bgCtx, testAddr) - require.NoError(t, err) - assert.Equal(t, uint64(i) + 1, pendingNonce) + // Fork at the first bock + if err := sim.Fork(context.Background(), h1); err != nil { + t.Errorf("forking: %v", err) + } - // the transaction should have been mined - _, isPending, err := sim.TransactionByHash(bgCtx, signedTx.Hash()) - require.NoError(t, err) - assert.False(t, isPending) - }) + // Test if Commit returns the correct block hash after the reorg + h2fork := sim.Commit() + if h2 == h2fork { + t.Error("The block in the fork and the original block are the same block!") + } + if sim.blockchain.GetHeader(h2fork, startBlockHeight+2) == nil { + t.Error("Could not retrieve the just created block (side-chain)") } }