diff --git a/cmd/rpcdaemon/commands/send_transaction_test.go b/cmd/rpcdaemon/commands/send_transaction_test.go index 4118fc0dc040e6d94977ab551ae3ebab935a441c..ecd1588a57cb8833876c857197e257406e63d8e9 100644 --- a/cmd/rpcdaemon/commands/send_transaction_test.go +++ b/cmd/rpcdaemon/commands/send_transaction_test.go @@ -25,7 +25,7 @@ import ( ) func TestSendRawTransaction(t *testing.T) { - //t.Skip("Flaky test") + t.Skip("Flaky test") m, require := stages.Mock(t), require.New(t) chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) { diff --git a/common/changeset/account_changeset.go b/common/changeset/account_changeset.go index af3847d24f43f2039f817a191247c5edac4c800f..ff1214772745c940b8bdc2214063320bcfe25517 100644 --- a/common/changeset/account_changeset.go +++ b/common/changeset/account_changeset.go @@ -42,11 +42,9 @@ func DecodeAccounts(dbKey, dbValue []byte) (uint64, []byte, []byte) { return blockN, k, v } -type AccountChangeSet struct{ c ethdb.CursorDupSort } - -func (b AccountChangeSet) Find(blockNumber uint64, key []byte) ([]byte, error) { +func FindAccount(c ethdb.CursorDupSort, blockNumber uint64, key []byte) ([]byte, error) { k := dbutils.EncodeBlockNumber(blockNumber) - v, err := b.c.SeekBothRange(k, key) + v, err := c.SeekBothRange(k, key) if err != nil { return nil, err } diff --git a/common/changeset/changeset.go b/common/changeset/changeset.go index 9d35e0adccf16f48c9c6cc72b0cfee488e584d30..d6cf1937a3b44e9153ffa6db31dac884ef546d41 100644 --- a/common/changeset/changeset.go +++ b/common/changeset/changeset.go @@ -11,10 +11,6 @@ import ( "github.com/ledgerwatch/erigon/ethdb" ) -type Walker interface { - Find(blockNumber uint64, k []byte) ([]byte, error) -} - func NewChangeSet() *ChangeSet { return &ChangeSet{ Changes: make([]Change, 0), @@ -174,7 +170,7 @@ func Truncate(tx ethdb.RwTx, from uint64) error { var Mapper = map[string]struct { IndexBucket string IndexChunkKey func([]byte, uint64) []byte - WalkerAdapter func(cursor ethdb.CursorDupSort) Walker + Find func(cursor ethdb.CursorDupSort, blockNumber uint64, key []byte) ([]byte, error) New func() *ChangeSet Encode Encoder Decode Decoder @@ -182,21 +178,17 @@ var Mapper = map[string]struct { dbutils.AccountChangeSetBucket: { IndexBucket: dbutils.AccountsHistoryBucket, IndexChunkKey: dbutils.AccountIndexChunkKey, - WalkerAdapter: func(c ethdb.CursorDupSort) Walker { - return AccountChangeSet{c: c} - }, - New: NewAccountChangeSet, - Encode: EncodeAccounts, - Decode: DecodeAccounts, + New: NewAccountChangeSet, + Find: FindAccount, + Encode: EncodeAccounts, + Decode: DecodeAccounts, }, dbutils.StorageChangeSetBucket: { IndexBucket: dbutils.StorageHistoryBucket, IndexChunkKey: dbutils.StorageIndexChunkKey, - WalkerAdapter: func(c ethdb.CursorDupSort) Walker { - return StorageChangeSet{c: c} - }, - New: NewStorageChangeSet, - Encode: EncodeStorage, - Decode: DecodeStorage, + Find: FindStorage, + New: NewStorageChangeSet, + Encode: EncodeStorage, + Decode: DecodeStorage, }, } diff --git a/common/changeset/storage_changeset.go b/common/changeset/storage_changeset.go index 2990132af0bcbbd99c287297e10ed6998f43942d..170f9f77ac84943c7bf1b07a85ee5bdfd527c5ff 100644 --- a/common/changeset/storage_changeset.go +++ b/common/changeset/storage_changeset.go @@ -58,77 +58,19 @@ func DecodeStorage(dbKey, dbValue []byte) (uint64, []byte, []byte) { return blockN, k, v } -type StorageChangeSet struct{ c ethdb.CursorDupSort } - -func (b StorageChangeSet) Find(blockNumber uint64, k []byte) ([]byte, error) { - return findWithoutIncarnationInStorageChangeSet2(b.c, blockNumber, common.AddressLength, k[:common.AddressLength], k[common.AddressLength:]) -} - -func (b StorageChangeSet) FindWithIncarnation(blockNumber uint64, k []byte) ([]byte, error) { - return doSearch2( - b.c, blockNumber, - k[:common.AddressLength], - k[common.AddressLength+common.IncarnationLength:common.AddressLength+common.HashLength+common.IncarnationLength], - binary.BigEndian.Uint64(k[common.AddressLength:]), /* incarnation */ - ) -} - -func (b StorageChangeSet) FindWithoutIncarnation(blockNumber uint64, addressToFind []byte, keyToFind []byte) ([]byte, error) { - return findWithoutIncarnationInStorageChangeSet2(b.c, blockNumber, common.AddressLength, addressToFind, keyToFind) -} - -func findWithoutIncarnationInStorageChangeSet2(c ethdb.CursorDupSort, blockNumber uint64, keyPrefixLen int, addrBytesToFind []byte, keyBytesToFind []byte) ([]byte, error) { - return doSearch2( - c, blockNumber, - addrBytesToFind, - keyBytesToFind, - 0, /* incarnation */ - ) -} - -func doSearch2( - c ethdb.CursorDupSort, - blockNumber uint64, - addrBytesToFind []byte, - keyBytesToFind []byte, - incarnation uint64, -) ([]byte, error) { - keyPrefixLen := common.AddressLength - if incarnation == 0 { - seek := make([]byte, 8+keyPrefixLen) - binary.BigEndian.PutUint64(seek, blockNumber) - copy(seek[8:], addrBytesToFind) - for k, v, err := c.Seek(seek); k != nil; k, v, err = c.Next() { - if err != nil { - return nil, err - } - _, k, v = DecodeStorage(k, v) - if !bytes.HasPrefix(k, addrBytesToFind) { - return nil, ErrNotFound - } - - stHash := k[keyPrefixLen+common.IncarnationLength:] - if bytes.Equal(stHash, keyBytesToFind) { - return v, nil - } - } - return nil, ErrNotFound - } - - seek := make([]byte, common.BlockNumberLength+keyPrefixLen+common.IncarnationLength) +func FindStorage(c ethdb.CursorDupSort, blockNumber uint64, k []byte) ([]byte, error) { + addWithInc, loc := k[:common.AddressLength+common.IncarnationLength], k[common.AddressLength+common.IncarnationLength:] + seek := make([]byte, common.BlockNumberLength+common.AddressLength+common.IncarnationLength) binary.BigEndian.PutUint64(seek, blockNumber) - copy(seek[8:], addrBytesToFind) - binary.BigEndian.PutUint64(seek[common.BlockNumberLength+keyPrefixLen:], incarnation) - k := seek - v, err := c.SeekBothRange(seek, keyBytesToFind) + copy(seek[8:], addWithInc) + v, err := c.SeekBothRange(seek, loc) if err != nil { return nil, err } - if !bytes.HasPrefix(v, keyBytesToFind) { + if !bytes.HasPrefix(v, loc) { return nil, ErrNotFound } - _, _, v = DecodeStorage(k, v) - return v, nil + return v[common.HashLength:], nil } // RewindDataPlain generates rewind data for all plain buckets between the timestamp diff --git a/common/changeset/storage_changeset_test.go b/common/changeset/storage_changeset_test.go index 71f19c86abeda2f9bcbac860302af8169090e893..0872b762a323e5a52209e4349fd1e9e691cb5c20 100644 --- a/common/changeset/storage_changeset_test.go +++ b/common/changeset/storage_changeset_test.go @@ -200,10 +200,6 @@ func TestEncodingStorageNewWithoutNotDefaultIncarnationFind(t *testing.T) { m := Mapper[storageTable] _, tx := kv.NewTestTx(t) - c, err := tx.CursorDupSort(storageTable) - require.NoError(t, err) - cs := m.WalkerAdapter(c).(StorageChangeSet) - clear := func() { c, err := tx.RwCursor(storageTable) require.NoError(t, err) @@ -219,7 +215,7 @@ func TestEncodingStorageNewWithoutNotDefaultIncarnationFind(t *testing.T) { } } - doTestFind(t, tx, cs.FindWithIncarnation, clear) + doTestFind(t, tx, m.Find, clear) } func TestEncodingStorageNewWithoutNotDefaultIncarnationFindWithoutIncarnation(t *testing.T) { @@ -227,10 +223,6 @@ func TestEncodingStorageNewWithoutNotDefaultIncarnationFindWithoutIncarnation(t m := Mapper[bkt] _, tx := kv.NewTestTx(t) - c, err := tx.CursorDupSort(bkt) - require.NoError(t, err) - cs := m.WalkerAdapter(c).(StorageChangeSet) - clear := func() { c, err := tx.RwCursor(bkt) require.NoError(t, err) @@ -246,21 +238,13 @@ func TestEncodingStorageNewWithoutNotDefaultIncarnationFindWithoutIncarnation(t } } - findFunc := func(blockN uint64, k []byte) ([]byte, error) { - addr, _, key := dbutils.PlainParseCompositeStorageKey(k) - addrBytes := addr[:] - keyBytes := key[:] - - return cs.FindWithoutIncarnation(blockN, addrBytes, keyBytes) - } - - doTestFind(t, tx, findFunc, clear) + doTestFind(t, tx, m.Find, clear) } func doTestFind( t *testing.T, tx ethdb.RwTx, - findFunc func(uint64, []byte) ([]byte, error), + findFunc func(ethdb.CursorDupSort, uint64, []byte) ([]byte, error), clear func(), ) { m := Mapper[storageTable] @@ -279,7 +263,7 @@ func doTestFind( } } - c, err := tx.RwCursor(storageTable) + c, err := tx.RwCursorDupSort(storageTable) require.NoError(t, err) err = m.Encode(1, ch, func(k, v []byte) error { @@ -293,7 +277,7 @@ func doTestFind( } for i, v := range ch.Changes { - val, err := findFunc(1, v.Key) + val, err := findFunc(c, 1, v.Key) if err != nil { t.Error(err, i) } @@ -383,7 +367,7 @@ func TestMultipleIncarnationsOfTheSameContract(t *testing.T) { c1, err := tx.CursorDupSort(bkt) require.NoError(t, err) - cs := m.WalkerAdapter(c1).(StorageChangeSet) + defer c1.Close() contractA := common.HexToAddress("0x6f0e0cdac6c716a00bd8db4d0eee4f2bfccf8e6a") contractB := common.HexToAddress("0xc5acb79c258108f288288bc26f7820d06f45f08c") @@ -422,24 +406,24 @@ func TestMultipleIncarnationsOfTheSameContract(t *testing.T) { return c.Put(k, v) })) - data1, err1 := cs.FindWithIncarnation(1, dbutils.PlainGenerateCompositeStorageKey(contractA.Bytes(), 2, key1.Bytes())) + data1, err1 := m.Find(c, 1, dbutils.PlainGenerateCompositeStorageKey(contractA.Bytes(), 2, key1.Bytes())) assert.NoError(t, err1) assert.Equal(t, data1, val1) - data3, err3 := cs.FindWithIncarnation(1, dbutils.PlainGenerateCompositeStorageKey(contractB.Bytes(), 1, key3.Bytes())) + data3, err3 := m.Find(c, 1, dbutils.PlainGenerateCompositeStorageKey(contractB.Bytes(), 1, key3.Bytes())) assert.NoError(t, err3) assert.Equal(t, data3, val3) - data5, err5 := cs.FindWithIncarnation(1, dbutils.PlainGenerateCompositeStorageKey(contractA.Bytes(), 1, key5.Bytes())) + data5, err5 := m.Find(c, 1, dbutils.PlainGenerateCompositeStorageKey(contractA.Bytes(), 1, key5.Bytes())) assert.NoError(t, err5) assert.Equal(t, data5, val5) - _, errA := cs.FindWithIncarnation(1, dbutils.PlainGenerateCompositeStorageKey(contractA.Bytes(), 1, key1.Bytes())) + _, errA := m.Find(c, 1, dbutils.PlainGenerateCompositeStorageKey(contractA.Bytes(), 1, key1.Bytes())) assert.Error(t, errA) - _, errB := cs.FindWithIncarnation(1, dbutils.PlainGenerateCompositeStorageKey(contractD.Bytes(), 2, key1.Bytes())) + _, errB := m.Find(c, 1, dbutils.PlainGenerateCompositeStorageKey(contractD.Bytes(), 2, key1.Bytes())) assert.Error(t, errB) - _, errC := cs.FindWithIncarnation(1, dbutils.PlainGenerateCompositeStorageKey(contractB.Bytes(), 1, key7.Bytes())) + _, errC := m.Find(c, 1, dbutils.PlainGenerateCompositeStorageKey(contractB.Bytes(), 1, key7.Bytes())) assert.Error(t, errC) } diff --git a/core/state/history.go b/core/state/history.go index 9be79364b2bf00a62c9b658084c728b3ab3308be..081bfafa7832bf169f68fb0fbc2a25f130bdf81f 100644 --- a/core/state/history.go +++ b/core/state/history.go @@ -16,26 +16,14 @@ import ( ) func GetAsOf(tx ethdb.Tx, storage bool, key []byte, timestamp uint64) ([]byte, error) { - var dat []byte v, err := FindByHistory(tx, storage, key, timestamp) if err == nil { - dat = make([]byte, len(v)) - copy(dat, v) - return dat, nil + return v, nil } if !errors.Is(err, ethdb.ErrKeyNotFound) { return nil, err } - v, err = tx.GetOne(dbutils.PlainStateBucket, key) - if err != nil { - return nil, err - } - if v == nil { - return nil, nil - } - dat = make([]byte, len(v)) - copy(dat, v) - return dat, nil + return tx.GetOne(dbutils.PlainStateBucket, key) } func FindByHistory(tx ethdb.Tx, storage bool, key []byte, timestamp uint64) ([]byte, error) { @@ -84,9 +72,9 @@ func FindByHistory(tx ethdb.Tx, storage bool, key []byte, timestamp uint64) ([]b } defer c.Close() if storage { - data, err = changeset.Mapper[csBucket].WalkerAdapter(c).(changeset.StorageChangeSet).FindWithIncarnation(changeSetBlock, key) + data, err = changeset.Mapper[csBucket].Find(c, changeSetBlock, key) } else { - data, err = changeset.Mapper[csBucket].WalkerAdapter(c).Find(changeSetBlock, key) + data, err = changeset.Mapper[csBucket].Find(c, changeSetBlock, key) } if err != nil { if !errors.Is(err, changeset.ErrNotFound) {