diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 82084627f9e8c830218015ab67dca0d1ae35dc57..97c4022f4b7a6c71773c9f826b28931143526a59 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -386,7 +386,7 @@ func ReadSenders(db databaseReader, hash common.Hash, number uint64) ([]common.A func WriteBody(db ethdb.Database, hash common.Hash, number uint64, body *types.Body) error { // Pre-processing body.SendersFromTxs() - baseTxId, err := db.Sequence(dbutils.EthTx, uint64(len(body.Transactions))) + baseTxId, err := db.IncrementSequence(dbutils.EthTx, uint64(len(body.Transactions))) if err != nil { return err } diff --git a/ethdb/interface.go b/ethdb/interface.go index df261705a29c84563f5e11ed54eb634c6df227ed..9b525b9fd545ed51531ecfcdec6fa5dc03a3ddec 100644 --- a/ethdb/interface.go +++ b/ethdb/interface.go @@ -94,7 +94,8 @@ type Database interface { Append(bucket string, key, value []byte) error AppendDup(bucket string, key, value []byte) error - Sequence(bucket string, amount uint64) (uint64, error) + IncrementSequence(bucket string, amount uint64) (uint64, error) + ReadSequence(bucket string) (uint64, error) } // MinDatabase is a minimalistic version of the Database interface. diff --git a/ethdb/kv_abstract.go b/ethdb/kv_abstract.go index 6ccca94fbb151d3745ca460e097b670eb7c99b8a..b1fe10003caefe58140595059c32065d2a671118 100644 --- a/ethdb/kv_abstract.go +++ b/ethdb/kv_abstract.go @@ -118,7 +118,8 @@ type Tx interface { // Can be called for a read transaction to retrieve the current sequence value, and the increment must be zero. // Sequence changes become visible outside the current write transaction after it is committed, and discarded on abort. // Starts from 0. - Sequence(bucket string, amount uint64) (uint64, error) + ReadSequence(bucket string) (uint64, error) + IncrementSequence(bucket string, amount uint64) (uint64, error) CHandle() unsafe.Pointer // Pointer to the underlying C transaction handle (e.g. *C.MDB_txn) } diff --git a/ethdb/kv_abstract_test.go b/ethdb/kv_abstract_test.go index d7569b06a5cfaeef077085eb3a4758bb9d493e05..a3917ab355d666091e6f7895f04b8be4251b83b9 100644 --- a/ethdb/kv_abstract_test.go +++ b/ethdb/kv_abstract_test.go @@ -31,29 +31,29 @@ func TestSequence(t *testing.T) { require.NoError(t, err) defer tx.Rollback() - i, err := tx.Sequence(dbutils.Buckets[0], 0) + i, err := tx.ReadSequence(dbutils.Buckets[0]) require.NoError(t, err) require.Equal(t, uint64(0), i) - i, err = tx.Sequence(dbutils.Buckets[0], 1) + i, err = tx.IncrementSequence(dbutils.Buckets[0], 1) require.NoError(t, err) require.Equal(t, uint64(0), i) - i, err = tx.Sequence(dbutils.Buckets[0], 6) + i, err = tx.IncrementSequence(dbutils.Buckets[0], 6) require.NoError(t, err) require.Equal(t, uint64(1), i) - i, err = tx.Sequence(dbutils.Buckets[0], 1) + i, err = tx.IncrementSequence(dbutils.Buckets[0], 1) require.NoError(t, err) require.Equal(t, uint64(7), i) - i, err = tx.Sequence(dbutils.Buckets[1], 0) + i, err = tx.ReadSequence(dbutils.Buckets[1]) require.NoError(t, err) require.Equal(t, uint64(0), i) - i, err = tx.Sequence(dbutils.Buckets[1], 1) + i, err = tx.IncrementSequence(dbutils.Buckets[1], 1) require.NoError(t, err) require.Equal(t, uint64(0), i) - i, err = tx.Sequence(dbutils.Buckets[1], 6) + i, err = tx.IncrementSequence(dbutils.Buckets[1], 6) require.NoError(t, err) require.Equal(t, uint64(1), i) - i, err = tx.Sequence(dbutils.Buckets[1], 1) + i, err = tx.IncrementSequence(dbutils.Buckets[1], 1) require.NoError(t, err) require.Equal(t, uint64(7), i) } diff --git a/ethdb/kv_lmdb.go b/ethdb/kv_lmdb.go index 968a92f5f01fa1d5ca61c72172f917b2e6ea0067..b4a10d5fcf59984d4e1b1ad31b33f3f76c31e24d 100644 --- a/ethdb/kv_lmdb.go +++ b/ethdb/kv_lmdb.go @@ -729,7 +729,7 @@ func (tx *lmdbTx) HasOne(bucket string, key []byte) (bool, error) { } } -func (tx *lmdbTx) Sequence(bucket string, amount uint64) (uint64, error) { +func (tx *lmdbTx) IncrementSequence(bucket string, amount uint64) (uint64, error) { c := tx.Cursor(dbutils.Sequence) defer c.Close() _, v, err := c.SeekExact([]byte(bucket)) @@ -742,10 +742,6 @@ func (tx *lmdbTx) Sequence(bucket string, amount uint64) (uint64, error) { currentV = binary.BigEndian.Uint64(v) } - if amount == 0 { - return currentV, nil - } - newVBytes := make([]byte, 8) binary.BigEndian.PutUint64(newVBytes, currentV+amount) err = c.Put([]byte(bucket), newVBytes) @@ -755,6 +751,22 @@ func (tx *lmdbTx) Sequence(bucket string, amount uint64) (uint64, error) { return currentV, nil } +func (tx *lmdbTx) ReadSequence(bucket string) (uint64, error) { + c := tx.Cursor(dbutils.Sequence) + defer c.Close() + _, v, err := c.SeekExact([]byte(bucket)) + if err != nil && !lmdb.IsNotFound(err) { + return 0, err + } + + var currentV uint64 = 0 + if len(v) > 0 { + currentV = binary.BigEndian.Uint64(v) + } + + return currentV, nil +} + func (tx *lmdbTx) BucketSize(name string) (uint64, error) { st, err := tx.tx.Stat(lmdb.DBI(tx.db.buckets[name].DBI)) if err != nil { diff --git a/ethdb/kv_mdbx.go b/ethdb/kv_mdbx.go index b7d8b18d43c5fa5027aaf23699cec270a2d6c30a..8c6c093d41584cd92a599e670549810d24f53e8e 100644 --- a/ethdb/kv_mdbx.go +++ b/ethdb/kv_mdbx.go @@ -770,10 +770,7 @@ func (tx *MdbxTx) HasOne(bucket string, key []byte) (bool, error) { } } -func (tx *MdbxTx) Sequence(bucket string, amount uint64) (uint64, error) { - // non-native for now - // return tx.tx.Sequence(mdbx.DBI(tx.db.buckets[bucket].DBI), amount) - +func (tx *MdbxTx) IncrementSequence(bucket string, amount uint64) (uint64, error) { c := tx.Cursor(dbutils.Sequence) defer c.Close() _, v, err := c.SeekExact([]byte(bucket)) @@ -786,10 +783,6 @@ func (tx *MdbxTx) Sequence(bucket string, amount uint64) (uint64, error) { currentV = binary.BigEndian.Uint64(v) } - if amount == 0 { - return currentV, nil - } - newVBytes := make([]byte, 8) binary.BigEndian.PutUint64(newVBytes, currentV+amount) err = c.Put([]byte(bucket), newVBytes) @@ -799,6 +792,22 @@ func (tx *MdbxTx) Sequence(bucket string, amount uint64) (uint64, error) { return currentV, nil } +func (tx *MdbxTx) ReadSequence(bucket string) (uint64, error) { + c := tx.Cursor(dbutils.Sequence) + defer c.Close() + _, v, err := c.SeekExact([]byte(bucket)) + if err != nil && !mdbx.IsNotFound(err) { + return 0, err + } + + var currentV uint64 = 0 + if len(v) > 0 { + currentV = binary.BigEndian.Uint64(v) + } + + return currentV, nil +} + func (tx *MdbxTx) BucketSize(name string) (uint64, error) { st, err := tx.BucketStat(name) if err != nil { diff --git a/ethdb/kv_remote.go b/ethdb/kv_remote.go index 7ee542e03dd79e229bbfffe48012fd535e8db047..ac6da16e71a564aba1dd07fab146debf33c073f6 100644 --- a/ethdb/kv_remote.go +++ b/ethdb/kv_remote.go @@ -230,7 +230,10 @@ func (db *RemoteKV) Update(ctx context.Context, f func(tx Tx) error) (err error) func (tx *remoteTx) Comparator(bucket string) dbutils.CmpFunc { panic("not implemented yet") } func (tx *remoteTx) CHandle() unsafe.Pointer { panic("not implemented yet") } -func (tx *remoteTx) Sequence(bucket string, amount uint64) (uint64, error) { +func (tx *remoteTx) IncrementSequence(bucket string, amount uint64) (uint64, error) { + panic("not implemented yet") +} +func (tx *remoteTx) ReadSequence(bucket string) (uint64, error) { panic("not implemented yet") } diff --git a/ethdb/kv_snapshot.go b/ethdb/kv_snapshot.go index fa76498a42f6745e36561e0af95fe42ca9036aa6..bbc7be1830da3ed7bcd733f906301b65f8835181 100644 --- a/ethdb/kv_snapshot.go +++ b/ethdb/kv_snapshot.go @@ -272,7 +272,11 @@ func (s *sn2TX) Comparator(bucket string) dbutils.CmpFunc { return s.dbTX.Comparator(bucket) } -func (s *sn2TX) Sequence(bucket string, amount uint64) (uint64, error) { +func (s *sn2TX) IncrementSequence(bucket string, amount uint64) (uint64, error) { + panic("implement me") +} + +func (s *sn2TX) ReadSequence(bucket string) (uint64, error) { panic("implement me") } diff --git a/ethdb/mutation.go b/ethdb/mutation.go index eb5138857a2de076e7d3c6f7eac005b620ce5d1e..002273e86643e962fb4ab59a278d8b2c8f796ad6 100644 --- a/ethdb/mutation.go +++ b/ethdb/mutation.go @@ -67,7 +67,7 @@ func (m *mutation) getMem(table string, key []byte) ([]byte, bool) { return i.(*MutationItem).value, true } -func (m *mutation) Sequence(bucket string, amount uint64) (res uint64, err error) { +func (m *mutation) IncrementSequence(bucket string, amount uint64) (res uint64, err error) { v, ok := m.getMem(dbutils.Sequence, []byte(bucket)) if !ok && m.db != nil { v, err = m.db.Get(dbutils.Sequence, []byte(bucket)) @@ -88,6 +88,21 @@ func (m *mutation) Sequence(bucket string, amount uint64) (res uint64, err error return currentV, nil } +func (m *mutation) ReadSequence(bucket string) (res uint64, err error) { + v, ok := m.getMem(dbutils.Sequence, []byte(bucket)) + if !ok && m.db != nil { + v, err = m.db.Get(dbutils.Sequence, []byte(bucket)) + if err != nil && !errors.Is(err, ErrKeyNotFound) { + return 0, err + } + } + var currentV uint64 = 0 + if len(v) > 0 { + currentV = binary.BigEndian.Uint64(v) + } + + return currentV, nil +} // Can only be called from the worker thread func (m *mutation) Get(table string, key []byte) ([]byte, error) { diff --git a/ethdb/object_db.go b/ethdb/object_db.go index 71adf472fed74563cd31df68527e3e472e18f479..8d9826dfd0153739f5f2cdfdbf8f821a10a6e52d 100644 --- a/ethdb/object_db.go +++ b/ethdb/object_db.go @@ -142,16 +142,16 @@ func (db *ObjectDatabase) DiskSize(ctx context.Context) (uint64, error) { return casted.DiskSize(ctx) } -func (db *ObjectDatabase) Sequence(bucket string, amount uint64) (res uint64, err error) { - if amount == 0 { - err = db.kv.View(context.Background(), func(tx Tx) error { - res, err = tx.Sequence(bucket, amount) - return err - }) - return res, err - } +func (db *ObjectDatabase) IncrementSequence(bucket string, amount uint64) (res uint64, err error) { err = db.kv.Update(context.Background(), func(tx Tx) error { - res, err = tx.Sequence(bucket, amount) + res, err = tx.IncrementSequence(bucket, amount) + return err + }) + return res, err +} +func (db *ObjectDatabase) ReadSequence(bucket string) (res uint64, err error) { + err = db.kv.View(context.Background(), func(tx Tx) error { + res, err = tx.ReadSequence(bucket) return err }) return res, err diff --git a/ethdb/tx_db.go b/ethdb/tx_db.go index 43d28f8224c3662ae9cf361b48b42d1bdfcd246e..e05f513702ea3a24403602e2bd28a72b71416e1f 100644 --- a/ethdb/tx_db.go +++ b/ethdb/tx_db.go @@ -57,8 +57,12 @@ func (m *TxDb) cursor(bucket string) Cursor { return c } -func (m *TxDb) Sequence(bucket string, amount uint64) (res uint64, err error) { - return m.tx.Sequence(bucket, amount) +func (m *TxDb) IncrementSequence(bucket string, amount uint64) (res uint64, err error) { + return m.tx.IncrementSequence(bucket, amount) +} + +func (m *TxDb) ReadSequence(bucket string) (res uint64, err error) { + return m.tx.ReadSequence(bucket) } func (m *TxDb) Put(bucket string, key []byte, value []byte) error { diff --git a/migrations/transactions.go b/migrations/transactions.go index 24c87062420cba26469772968c122fe832f132f9..62b1b7a174b04ae52455dc019b5aab79c6a43896 100644 --- a/migrations/transactions.go +++ b/migrations/transactions.go @@ -95,7 +95,7 @@ var transactionsTable = Migration{ txIds := make([]uint64, len(body.Transactions)) var baseTxId uint64 - baseTxId, err = db.Sequence(dbutils.EthTx, uint64(len(body.Transactions))) + baseTxId, err = db.IncrementSequence(dbutils.EthTx, uint64(len(body.Transactions))) if err != nil { return false, nil }