mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-25 04:57:17 +00:00
e3: move txnum to erigon-lib (#847)
This commit is contained in:
parent
559e60f1a3
commit
ed637538bf
@ -28,9 +28,6 @@ func BytesToAddress(b []byte) Address {
|
||||
return a
|
||||
}
|
||||
|
||||
// BytesToAddressNoCopy - see https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer
|
||||
func BytesToAddressNoCopy(b []byte) Address { return *(*Address)(b) }
|
||||
|
||||
// BigToAddress returns Address with byte values of b.
|
||||
// If b is larger than len(h), b will be cropped from the left.
|
||||
func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
|
||||
|
@ -152,3 +152,9 @@ func (h *Hash) Scan(src interface{}) error {
|
||||
func (h Hash) Value() (driver.Value, error) {
|
||||
return h[:], nil
|
||||
}
|
||||
|
||||
type CodeRecord struct {
|
||||
BlockNumber uint64
|
||||
TxNumber uint64
|
||||
CodeHash Hash
|
||||
}
|
||||
|
186
common/rawdbv3/txnum.go
Normal file
186
common/rawdbv3/txnum.go
Normal file
@ -0,0 +1,186 @@
|
||||
package rawdbv3
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/ledgerwatch/erigon-lib/kv"
|
||||
)
|
||||
|
||||
type txNums struct{}
|
||||
|
||||
var TxNums txNums
|
||||
|
||||
// Min - returns maxTxNum in given block. If block not found - return last available value (`latest`/`pending` state)
|
||||
func (txNums) Max(tx kv.Tx, blockNum uint64) (maxTxNum uint64, err error) {
|
||||
var k [8]byte
|
||||
binary.BigEndian.PutUint64(k[:], blockNum)
|
||||
c, err := tx.Cursor(kv.MaxTxNum)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer c.Close()
|
||||
_, v, err := c.SeekExact(k[:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(v) == 0 {
|
||||
_, v, err = c.Last()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(v) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
return binary.BigEndian.Uint64(v), nil
|
||||
}
|
||||
|
||||
// Min = `max(blockNum-1)+1` returns minTxNum in given block. If block not found - return last available value (`latest`/`pending` state)
|
||||
func (txNums) Min(tx kv.Tx, blockNum uint64) (maxTxNum uint64, err error) {
|
||||
if blockNum == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
var k [8]byte
|
||||
binary.BigEndian.PutUint64(k[:], blockNum-1)
|
||||
c, err := tx.Cursor(kv.MaxTxNum)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
_, v, err := c.SeekExact(k[:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(v) == 0 {
|
||||
_, v, err = c.Last()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if len(v) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
}
|
||||
return binary.BigEndian.Uint64(v) + 1, nil
|
||||
}
|
||||
|
||||
func (txNums) Append(tx kv.RwTx, blockNum, maxTxNum uint64) (err error) {
|
||||
lastK, err := LastKey(tx, kv.MaxTxNum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(lastK) != 0 {
|
||||
lastBlockNum := binary.BigEndian.Uint64(lastK)
|
||||
if lastBlockNum > 1 && lastBlockNum+1 != blockNum { //allow genesis
|
||||
return fmt.Errorf("append with gap blockNum=%d, but current heigh=%d", blockNum, lastBlockNum)
|
||||
}
|
||||
}
|
||||
|
||||
var k, v [8]byte
|
||||
binary.BigEndian.PutUint64(k[:], blockNum)
|
||||
binary.BigEndian.PutUint64(v[:], maxTxNum)
|
||||
if err := tx.Append(kv.MaxTxNum, k[:], v[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (txNums) WriteForGenesis(tx kv.RwTx, maxTxNum uint64) (err error) {
|
||||
var k, v [8]byte
|
||||
binary.BigEndian.PutUint64(k[:], 0)
|
||||
binary.BigEndian.PutUint64(v[:], maxTxNum)
|
||||
return tx.Put(kv.MaxTxNum, k[:], v[:])
|
||||
}
|
||||
func (txNums) Truncate(tx kv.RwTx, blockNum uint64) (err error) {
|
||||
var seek [8]byte
|
||||
binary.BigEndian.PutUint64(seek[:], blockNum)
|
||||
c, err := tx.RwCursor(kv.MaxTxNum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Close()
|
||||
for k, _, err := c.Seek(seek[:]); k != nil; k, _, err = c.Next() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = c.DeleteCurrent(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (txNums) FindBlockNum(tx kv.Tx, endTxNumMinimax uint64) (ok bool, blockNum uint64, err error) {
|
||||
var seek [8]byte
|
||||
c, err := tx.Cursor(kv.MaxTxNum)
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
defer c.Close()
|
||||
|
||||
cnt, err := c.Count()
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
|
||||
blockNum = uint64(sort.Search(int(cnt), func(i int) bool {
|
||||
binary.BigEndian.PutUint64(seek[:], uint64(i))
|
||||
var v []byte
|
||||
_, v, err = c.SeekExact(seek[:])
|
||||
return binary.BigEndian.Uint64(v) >= endTxNumMinimax
|
||||
}))
|
||||
if err != nil {
|
||||
return false, 0, err
|
||||
}
|
||||
if blockNum == cnt {
|
||||
return false, 0, nil
|
||||
}
|
||||
return true, blockNum, nil
|
||||
}
|
||||
|
||||
// LastKey
|
||||
func LastKey(tx kv.Tx, table string) ([]byte, error) {
|
||||
c, err := tx.Cursor(table)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer c.Close()
|
||||
k, _, err := c.Last()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return k, nil
|
||||
}
|
||||
|
||||
// Last - candidate on move to kv.Tx interface
|
||||
func Last(tx kv.Tx, table string) ([]byte, []byte, error) {
|
||||
c, err := tx.Cursor(table)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer c.Close()
|
||||
k, v, err := c.Last()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return k, v, nil
|
||||
}
|
||||
|
||||
// SecondKey - useful if table always has zero-key (for example genesis block)
|
||||
func SecondKey(tx kv.Tx, table string) ([]byte, error) {
|
||||
c, err := tx.Cursor(table)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer c.Close()
|
||||
_, _, err = c.First()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
k, _, err := c.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return k, nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user