verify state by balance

This commit is contained in:
Jinsuk Park 2024-03-12 18:54:35 -07:00
parent 32064fbf3d
commit 80d21f6c44
No known key found for this signature in database
GPG key ID: 55BC6A66FEF320E4
2 changed files with 55 additions and 27 deletions

View file

@ -106,23 +106,26 @@ func (b *Builder) AddTransaction(txn *types.Transaction) (*suavextypes.SimulateT
} }
func (b *Builder) AddTransactions(txns types.Transactions) ([]*suavextypes.SimulateTransactionResult, error) { func (b *Builder) AddTransactions(txns types.Transactions) ([]*suavextypes.SimulateTransactionResult, error) {
var result []*suavextypes.SimulateTransactionResult results := make([]*suavextypes.SimulateTransactionResult, 0)
snap := b.env.copy() snap := b.env.copy()
for _, txn := range txns { for _, txn := range txns {
res, err := b.addTransaction(txn, snap) res, err := b.addTransaction(txn, snap)
result = append(result, res) results = append(results, res)
if err != nil { if err != nil {
return result, nil return results, nil
} }
} }
b.env = snap b.env = snap
return result, nil return results, nil
} }
func (b *Builder) addBundle(bundle *suavextypes.Bundle, env *environment) (*suavextypes.SimulateBundleResult, error) { func (b *Builder) addBundle(bundle *suavextypes.Bundle, env *environment) (*suavextypes.SimulateBundleResult, error) {
if err := checkBundleInclusion(b.env.header.Number, bundle); err != nil { if err := checkBundleParams(b.env.header.Number, bundle); err != nil {
return nil, err return &suavextypes.SimulateBundleResult{
Error: err.Error(),
Success: false,
}, err
} }
revertingHashes := bundle.RevertingHashesMap() revertingHashes := bundle.RevertingHashesMap()
@ -138,9 +141,10 @@ func (b *Builder) addBundle(bundle *suavextypes.Bundle, env *environment) (*suav
continue continue
} }
return &suavextypes.SimulateBundleResult{ return &suavextypes.SimulateBundleResult{
Error: err.Error(), Error: err.Error(),
Success: false, SimulateTransactionResults: results,
}, nil Success: false,
}, err
} }
egp += result.Egp egp += result.Egp
} }
@ -157,10 +161,7 @@ func (b *Builder) AddBundle(bundle *suavextypes.Bundle) (*suavextypes.SimulateBu
result, err := b.addBundle(bundle, snap) result, err := b.addBundle(bundle, snap)
if err != nil { if err != nil {
return &suavextypes.SimulateBundleResult{ return result, nil
Error: err.Error(),
Success: false,
}, nil
} }
b.env = snap b.env = snap
@ -309,7 +310,7 @@ func executableDataToDenebExecutionPayload(data *engine.ExecutableData) (*deneb.
}, nil }, nil
} }
func checkBundleInclusion(currentBlockNumber *big.Int, bundle *suavextypes.Bundle) error { func checkBundleParams(currentBlockNumber *big.Int, bundle *suavextypes.Bundle) error {
if bundle.BlockNumber != nil && bundle.MaxBlock != nil && bundle.BlockNumber.Cmp(bundle.MaxBlock) > 0 { if bundle.BlockNumber != nil && bundle.MaxBlock != nil && bundle.BlockNumber.Cmp(bundle.MaxBlock) > 0 {
return ErrInvalidInclusionRange return ErrInvalidInclusionRange
} }

View file

@ -28,12 +28,13 @@ func TestBuilder_AddTxn_Simple(t *testing.T) {
builder, err := NewBuilder(config, &BuilderArgs{}) builder, err := NewBuilder(config, &BuilderArgs{})
require.NoError(t, err) require.NoError(t, err)
tx1 := backend.newRandomTx(true) tx1 := backend.newRandomTx(false)
res, err := builder.AddTransaction(tx1) res, err := builder.AddTransaction(tx1)
require.NoError(t, err) require.NoError(t, err)
require.True(t, res.Success) require.True(t, res.Success)
require.Len(t, builder.env.receipts, 1) require.Len(t, builder.env.receipts, 1)
require.Equal(t, big.NewInt(1000), builder.env.state.GetBalance(testUserAddress))
// we cannot add the same transaction again. Note that by design the // we cannot add the same transaction again. Note that by design the
// function does not error but returns the SimulateTransactionResult.success = false // function does not error but returns the SimulateTransactionResult.success = false
@ -41,6 +42,7 @@ func TestBuilder_AddTxn_Simple(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.False(t, res.Success) require.False(t, res.Success)
require.Len(t, builder.env.receipts, 1) require.Len(t, builder.env.receipts, 1)
require.Equal(t, big.NewInt(1000), builder.env.state.GetBalance(testUserAddress))
} }
func TestBuilder_AddTxns_Simple(t *testing.T) { func TestBuilder_AddTxns_Simple(t *testing.T) {
@ -58,6 +60,7 @@ func TestBuilder_AddTxns_Simple(t *testing.T) {
for _, r := range res { for _, r := range res {
require.True(t, r.Success) require.True(t, r.Success)
} }
require.Equal(t, big.NewInt(2000), builder.env.state.GetBalance(testUserAddress))
tx3 := backend.newRandomTxWithNonce(2) tx3 := backend.newRandomTxWithNonce(2)
tx4 := backend.newRandomTxWithNonce(1000) // fails with nonce too high tx4 := backend.newRandomTxWithNonce(1000) // fails with nonce too high
@ -68,6 +71,7 @@ func TestBuilder_AddTxns_Simple(t *testing.T) {
require.True(t, res[0].Success) require.True(t, res[0].Success)
require.False(t, res[1].Success) require.False(t, res[1].Success)
require.Len(t, builder.env.txs, 2) require.Len(t, builder.env.txs, 2)
require.Equal(t, big.NewInt(2000), builder.env.state.GetBalance(testUserAddress))
} }
func TestBuilder_AddBundle_Simple(t *testing.T) { func TestBuilder_AddBundle_Simple(t *testing.T) {
@ -87,6 +91,7 @@ func TestBuilder_AddBundle_Simple(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.True(t, res.Success) require.True(t, res.Success)
require.Len(t, res.SimulateTransactionResults, 2) require.Len(t, res.SimulateTransactionResults, 2)
require.Equal(t, big.NewInt(2000), builder.env.state.GetBalance(testUserAddress))
} }
func TestBuilder_AddBundle_RevertHashes(t *testing.T) { func TestBuilder_AddBundle_RevertHashes(t *testing.T) {
@ -99,26 +104,37 @@ func TestBuilder_AddBundle_RevertHashes(t *testing.T) {
tx2 := backend.newRandomTxWithNonce(3) // fails with nonce too high tx2 := backend.newRandomTxWithNonce(3) // fails with nonce too high
bundle := &suavextypes.Bundle{ bundle := &suavextypes.Bundle{
Txs: []*types.Transaction{tx1, tx2}, Txs: []*types.Transaction{tx1, tx2},
RevertingHashes: []common.Hash{tx2.Hash()},
} }
res, err := builder.AddBundle(bundle) res, err := builder.AddBundle(bundle)
require.NoError(t, err) require.NoError(t, err)
require.False(t, res.Success)
require.Len(t, res.SimulateTransactionResults, 2)
require.True(t, res.SimulateTransactionResults[0].Success)
require.False(t, res.SimulateTransactionResults[1].Success)
require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress))
bundle.RevertingHashes = []common.Hash{tx2.Hash()}
res, err = builder.AddBundle(bundle)
require.NoError(t, err)
require.True(t, res.Success) require.True(t, res.Success)
require.Len(t, res.SimulateTransactionResults, 2) require.Len(t, res.SimulateTransactionResults, 2)
require.True(t, res.SimulateTransactionResults[0].Success) require.True(t, res.SimulateTransactionResults[0].Success)
require.False(t, res.SimulateTransactionResults[1].Success) require.False(t, res.SimulateTransactionResults[1].Success)
require.Equal(t, big.NewInt(1000), builder.env.state.GetBalance(testUserAddress))
} }
func TestBuilder_AddBundle_InvalidInclusion(t *testing.T) { func TestBuilder_AddBundle_InvalidParams(t *testing.T) {
t.Parallel() t.Parallel()
config, backend := newMockBuilderConfig(t) config, backend := newMockBuilderConfig(t)
builder, err := NewBuilder(config, &BuilderArgs{ // set builder target block number to 10
Slot: 10, backend.insertRandomBlocks(9)
})
builder, err := NewBuilder(config, &BuilderArgs{})
require.Equal(t, uint64(10), builder.env.header.Number.Uint64())
require.NoError(t, err) require.NoError(t, err)
snap := builder.env
tx1 := backend.newRandomTx(false) tx1 := backend.newRandomTx(false)
tx2 := backend.newRandomTx(false) tx2 := backend.newRandomTx(false)
@ -128,13 +144,12 @@ func TestBuilder_AddBundle_InvalidInclusion(t *testing.T) {
BlockNumber: big.NewInt(20), BlockNumber: big.NewInt(20),
} }
backend.insertRandomBlocks(10)
require.Equal(t, uint64(10), backend.chain.CurrentBlock().Number.Uint64())
res, err := builder.AddBundle(bundle) res, err := builder.AddBundle(bundle)
require.NoError(t, err) require.NoError(t, err)
require.False(t, res.Success) require.False(t, res.Success)
require.Equal(t, ErrInvalidBlockNumber.Error(), res.Error)
require.Len(t, res.SimulateTransactionResults, 0) require.Len(t, res.SimulateTransactionResults, 0)
require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress))
bundle = &suavextypes.Bundle{ bundle = &suavextypes.Bundle{
Txs: []*types.Transaction{tx1, tx2}, Txs: []*types.Transaction{tx1, tx2},
@ -145,9 +160,20 @@ func TestBuilder_AddBundle_InvalidInclusion(t *testing.T) {
res, err = builder.AddBundle(bundle) res, err = builder.AddBundle(bundle)
require.NoError(t, err) require.NoError(t, err)
require.False(t, res.Success) require.False(t, res.Success)
require.Equal(t, ErrExceedsMaxBlock.Error(), res.Error)
require.Len(t, res.SimulateTransactionResults, 0) require.Len(t, res.SimulateTransactionResults, 0)
// should not modify state for failed bundle inclusion require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress))
require.Equal(t, snap, builder.env)
bundle = &suavextypes.Bundle{
Txs: []*types.Transaction{},
}
res, err = builder.AddBundle(bundle)
require.NoError(t, err)
require.False(t, res.Success)
require.Equal(t, ErrEmptyTxs.Error(), res.Error)
require.Len(t, res.SimulateTransactionResults, 0)
require.Equal(t, big.NewInt(0), builder.env.state.GetBalance(testUserAddress))
} }
func TestBuilder_AddBundles_Simple(t *testing.T) { func TestBuilder_AddBundles_Simple(t *testing.T) {
@ -177,6 +203,7 @@ func TestBuilder_AddBundles_Simple(t *testing.T) {
require.Len(t, res, 2) require.Len(t, res, 2)
require.True(t, res[0].Success) require.True(t, res[0].Success)
require.True(t, res[1].Success) require.True(t, res[1].Success)
require.Equal(t, big.NewInt(4000), builder.env.state.GetBalance(testUserAddress))
} }
func TestBuilder_FillTransactions(t *testing.T) { func TestBuilder_FillTransactions(t *testing.T) {