add test cases for GetModifiedAccountsByNumber and GetModifiedAccountsByHash

This commit is contained in:
maskpp 2025-05-07 11:09:54 +08:00
parent 255ee2aa9b
commit 7a6e4c842b

View file

@ -18,25 +18,74 @@ package eth
import (
"bytes"
"crypto/ecdsa"
"fmt"
"math/big"
"reflect"
"slices"
"strings"
"testing"
"time"
"github.com/davecgh/go-spew/spew"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus/ethash"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/core/state"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/triedb"
"github.com/holiman/uint256"
"github.com/stretchr/testify/assert"
)
var dumper = spew.ConfigState{Indent: " "}
type Account struct {
key *ecdsa.PrivateKey
addr common.Address
}
func newAccounts(n int) (accounts []Account) {
for i := 0; i < n; i++ {
key, _ := crypto.GenerateKey()
addr := crypto.PubkeyToAddress(key.PublicKey)
accounts = append(accounts, Account{key: key, addr: addr})
}
slices.SortFunc(accounts, func(a, b Account) int { return a.addr.Cmp(b.addr) })
return accounts
}
// newTestBackend creates a new test backend. OBS: After test is done, teardown must be
// invoked in order to release associated resources.
func newTestBlockChain(t *testing.T, n int, gspec *core.Genesis, generator func(i int, b *core.BlockGen)) *core.BlockChain {
engine := ethash.NewFaker()
// Generate blocks for testing
_, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, generator)
// Import the canonical chain
cacheConfig := &core.CacheConfig{
TrieCleanLimit: 256,
TrieDirtyLimit: 256,
TrieTimeLimit: 5 * time.Minute,
SnapshotLimit: 0,
Preimages: true,
TrieDirtyDisabled: true, // Archive mode
}
chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), cacheConfig, gspec, nil, engine, vm.Config{}, nil)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
if n, err := chain.InsertChain(blocks); err != nil {
t.Fatalf("block %d: failed to insert into chain: %v", n, err)
}
return chain
}
func accountRangeTest(t *testing.T, trie *state.Trie, statedb *state.StateDB, start common.Hash, requestedNum int, expectedNum int) state.Dump {
result := statedb.RawDump(&state.DumpConfig{
SkipCode: true,
@ -224,3 +273,64 @@ func TestStorageRangeAt(t *testing.T) {
}
}
}
func TestGetModifiedAccounts(t *testing.T) {
t.Parallel()
// Initialize test accounts
accounts := newAccounts(4)
genesis := &core.Genesis{
Config: params.TestChainConfig,
Alloc: types.GenesisAlloc{
accounts[0].addr: {Balance: big.NewInt(params.Ether)},
accounts[1].addr: {Balance: big.NewInt(params.Ether)},
accounts[2].addr: {Balance: big.NewInt(params.Ether)},
accounts[3].addr: {Balance: big.NewInt(params.Ether)},
},
}
genBlocks := 1
signer := types.HomesteadSigner{}
blockChain := newTestBlockChain(t, genBlocks, genesis, func(_ int, b *core.BlockGen) {
// Transfer from account[0] to account[1]
// value: 1000 wei
// fee: 0 wei
for _, account := range accounts[:3] {
tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{
Nonce: 0,
To: &accounts[3].addr,
Value: big.NewInt(1000),
Gas: params.TxGas,
GasPrice: b.BaseFee(),
Data: nil}),
signer, account.key)
b.AddTx(tx)
}
})
api := NewDebugAPI(&Ethereum{blockchain: blockChain})
// Test GetModifiedAccountsByNumber
t.Run("GetModifiedAccountsByNumber", func(t *testing.T) {
addrs, err := api.GetModifiedAccountsByNumber(uint64(genBlocks), nil)
assert.NoError(t, err)
assert.Len(t, addrs, len(accounts)+1) // +1 for the coinbase
for _, account := range accounts {
if !slices.Contains(addrs, account.addr) {
t.Fatalf("account %s not found in modified accounts", account.addr.Hex())
}
}
})
// Test GetModifiedAccountsByHash
t.Run("GetModifiedAccountsByHash", func(t *testing.T) {
header := blockChain.GetHeaderByNumber(uint64(genBlocks))
addrs, err := api.GetModifiedAccountsByHash(header.Hash(), nil)
assert.NoError(t, err)
assert.Len(t, addrs, len(accounts)+1) // +1 for the coinbase
for _, account := range accounts {
if !slices.Contains(addrs, account.addr) {
t.Fatalf("account %s not found in modified accounts", account.addr.Hex())
}
}
})
}