From e141ac03e8d7454a3e5aa24ea8dbb19d91ac2cce Mon Sep 17 00:00:00 2001 From: Exca-DK Date: Sat, 18 Jan 2025 09:13:31 +0100 Subject: [PATCH] Make internal blockchain methods private and duplicate them in migration --- blockchain/blockchain.go | 42 +++++----- blockchain/event_filter.go | 2 +- migration/blockchain.go | 165 +++++++++++++++++++++++++++++++++++++ migration/migration.go | 18 ++-- 4 files changed, 197 insertions(+), 30 deletions(-) create mode 100644 migration/blockchain.go diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 788fc8635f..791272cc48 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -128,12 +128,12 @@ func (b *Blockchain) Height() (uint64, error) { var height uint64 return height, b.database.View(func(txn db.Transaction) error { var err error - height, err = ChainHeight(txn) + height, err = chainHeight(txn) return err }) } -func ChainHeight(txn db.Transaction) (uint64, error) { +func chainHeight(txn db.Transaction) (uint64, error) { var height uint64 return height, txn.Get(db.ChainHeight.Key(), func(val []byte) error { height = binary.BigEndian.Uint64(val) @@ -163,15 +163,15 @@ func (b *Blockchain) HeadsHeader() (*core.Header, error) { } func head(txn db.Transaction) (*core.Block, error) { - height, err := ChainHeight(txn) + height, err := chainHeight(txn) if err != nil { return nil, err } - return BlockByNumber(txn, height) + return blockByNumber(txn, height) } func headsHeader(txn db.Transaction) (*core.Header, error) { - height, err := ChainHeight(txn) + height, err := chainHeight(txn) if err != nil { return nil, err } @@ -184,7 +184,7 @@ func (b *Blockchain) BlockByNumber(number uint64) (*core.Block, error) { var block *core.Block return block, b.database.View(func(txn db.Transaction) error { var err error - block, err = BlockByNumber(txn, number) + block, err = blockByNumber(txn, number) return err }) } @@ -339,7 +339,7 @@ func (b *Blockchain) Store(block *core.Block, blockCommitments *core.BlockCommit if err := core.NewState(txn).Update(block.Number, stateUpdate, newClasses); err != nil { return err } - if err := StoreBlockHeader(txn, block.Header); err != nil { + if err := storeBlockHeader(txn, block.Header); err != nil { return err } @@ -354,11 +354,11 @@ func (b *Blockchain) Store(block *core.Block, blockCommitments *core.BlockCommit return err } - if err := StoreBlockCommitments(txn, block.Number, blockCommitments); err != nil { + if err := storeBlockCommitments(txn, block.Number, blockCommitments); err != nil { return err } - if err := StoreL1HandlerMsgHashes(txn, block.Transactions); err != nil { + if err := storeL1HandlerMsgHashes(txn, block.Transactions); err != nil { return err } @@ -402,7 +402,7 @@ func verifyBlock(txn db.Transaction, block *core.Block) error { return nil } -func StoreBlockCommitments(txn db.Transaction, blockNumber uint64, commitments *core.BlockCommitments) error { +func storeBlockCommitments(txn db.Transaction, blockNumber uint64, commitments *core.BlockCommitments) error { numBytes := core.MarshalBlockNumber(blockNumber) commitmentBytes, err := encoder.Marshal(commitments) @@ -445,7 +445,7 @@ func blockCommitmentsByNumber(txn db.Transaction, blockNumber uint64) (*core.Blo // "[]" is the db prefix to represent a bucket // "()" are additional keys appended to the prefix or multiple values marshalled together // "->" represents a key value pair. -func StoreBlockHeader(txn db.Transaction, header *core.Header) error { +func storeBlockHeader(txn db.Transaction, header *core.Header) error { numBytes := core.MarshalBlockNumber(header.Number) if err := txn.Set(db.BlockHeaderNumbersByHash.Key(header.Hash.Marshal()), numBytes); err != nil { @@ -483,8 +483,8 @@ func blockHeaderByHash(txn db.Transaction, hash *felt.Felt) (*core.Header, error }) } -// BlockByNumber retrieves a block from database by its number -func BlockByNumber(txn db.Transaction, number uint64) (*core.Block, error) { +// blockByNumber retrieves a block from database by its number +func blockByNumber(txn db.Transaction, number uint64) (*core.Block, error) { header, err := blockHeaderByNumber(txn, number) if err != nil { return nil, err @@ -492,7 +492,7 @@ func BlockByNumber(txn db.Transaction, number uint64) (*core.Block, error) { block := new(core.Block) block.Header = header - block.Transactions, err = TransactionsByBlockNumber(txn, number) + block.Transactions, err = transactionsByBlockNumber(txn, number) if err != nil { return nil, err } @@ -504,7 +504,7 @@ func BlockByNumber(txn db.Transaction, number uint64) (*core.Block, error) { return block, nil } -func TransactionsByBlockNumber(txn db.Transaction, number uint64) ([]core.Transaction, error) { +func transactionsByBlockNumber(txn db.Transaction, number uint64) ([]core.Transaction, error) { numBytes := core.MarshalBlockNumber(number) prefix := db.TransactionsByBlockNumberAndIndex.Key(numBytes) @@ -576,12 +576,12 @@ func blockByHash(txn db.Transaction, hash *felt.Felt) (*core.Block, error) { var block *core.Block return block, txn.Get(db.BlockHeaderNumbersByHash.Key(hash.Marshal()), func(val []byte) error { var err error - block, err = BlockByNumber(txn, binary.BigEndian.Uint64(val)) + block, err = blockByNumber(txn, binary.BigEndian.Uint64(val)) return err }) } -func StoreL1HandlerMsgHashes(dbTxn db.Transaction, blockTxns []core.Transaction) error { +func storeL1HandlerMsgHashes(dbTxn db.Transaction, blockTxns []core.Transaction) error { for _, txn := range blockTxns { if l1Handler, ok := (txn).(*core.L1HandlerTransaction); ok { err := dbTxn.Set(db.L1HandlerTxnHashByMsgHash.Key(l1Handler.MessageHash()), txn.Hash().Marshal()) @@ -773,7 +773,7 @@ func (b *Blockchain) HeadState() (core.StateReader, StateCloser, error) { return nil, nil, err } - _, err = ChainHeight(txn) + _, err = chainHeight(txn) if err != nil { return nil, nil, utils.RunAndWrapOnError(txn.Discard, err) } @@ -827,7 +827,7 @@ func (b *Blockchain) EventFilter(from *felt.Felt, keys [][]felt.Felt) (EventFilt return nil, err } - latest, err := ChainHeight(txn) + latest, err := chainHeight(txn) if err != nil { return nil, err } @@ -843,7 +843,7 @@ func (b *Blockchain) RevertHead() error { func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) { var reverseStateDiff *core.StateDiff return reverseStateDiff, b.database.View(func(txn db.Transaction) error { - blockNumber, err := ChainHeight(txn) + blockNumber, err := chainHeight(txn) if err != nil { return err } @@ -858,7 +858,7 @@ func (b *Blockchain) GetReverseStateDiff() (*core.StateDiff, error) { } func (b *Blockchain) revertHead(txn db.Transaction) error { - blockNumber, err := ChainHeight(txn) + blockNumber, err := chainHeight(txn) if err != nil { return err } diff --git a/blockchain/event_filter.go b/blockchain/event_filter.go index 09ea67437e..6e71623b1f 100644 --- a/blockchain/event_filter.go +++ b/blockchain/event_filter.go @@ -112,7 +112,7 @@ type FilteredEvent struct { //nolint:gocyclo func (e *EventFilter) Events(cToken *ContinuationToken, chunkSize uint64) ([]*FilteredEvent, *ContinuationToken, error) { var matchedEvents []*FilteredEvent - latest, err := ChainHeight(e.txn) + latest, err := chainHeight(e.txn) if err != nil { return nil, nil, err } diff --git a/migration/blockchain.go b/migration/blockchain.go new file mode 100644 index 0000000000..baab05abdc --- /dev/null +++ b/migration/blockchain.go @@ -0,0 +1,165 @@ +package migration + +import ( + "bytes" + "encoding/binary" + + "github.com/NethermindEth/juno/core" + "github.com/NethermindEth/juno/db" + "github.com/NethermindEth/juno/encoder" + "github.com/NethermindEth/juno/utils" +) + +func blockByNumber(txn db.Transaction, number uint64) (*core.Block, error) { + header, err := blockHeaderByNumber(txn, number) + if err != nil { + return nil, err + } + + block := new(core.Block) + block.Header = header + block.Transactions, err = transactionsByBlockNumber(txn, number) + if err != nil { + return nil, err + } + + block.Receipts, err = receiptsByBlockNumber(txn, number) + if err != nil { + return nil, err + } + return block, nil +} + +func blockHeaderByNumber(txn db.Transaction, number uint64) (*core.Header, error) { + numBytes := core.MarshalBlockNumber(number) + + var header *core.Header + if err := txn.Get(db.BlockHeadersByNumber.Key(numBytes), func(val []byte) error { + header = new(core.Header) + return encoder.Unmarshal(val, header) + }); err != nil { + return nil, err + } + return header, nil +} + +func head(txn db.Transaction) (*core.Block, error) { + height, err := chainHeight(txn) + if err != nil { + return nil, err + } + return blockByNumber(txn, height) +} + +func chainHeight(txn db.Transaction) (uint64, error) { + var height uint64 + return height, txn.Get(db.ChainHeight.Key(), func(val []byte) error { + height = binary.BigEndian.Uint64(val) + return nil + }) +} + +func transactionsByBlockNumber(txn db.Transaction, number uint64) ([]core.Transaction, error) { + numBytes := core.MarshalBlockNumber(number) + prefix := db.TransactionsByBlockNumberAndIndex.Key(numBytes) + + iterator, err := txn.NewIterator(prefix, true) + if err != nil { + return nil, err + } + + var txs []core.Transaction + for iterator.First(); iterator.Valid(); iterator.Next() { + val, vErr := iterator.Value() + if vErr != nil { + return nil, utils.RunAndWrapOnError(iterator.Close, vErr) + } + + var tx core.Transaction + if err = encoder.Unmarshal(val, &tx); err != nil { + return nil, utils.RunAndWrapOnError(iterator.Close, err) + } + + txs = append(txs, tx) + } + + if err = iterator.Close(); err != nil { + return nil, err + } + + return txs, nil +} + +func receiptsByBlockNumber(txn db.Transaction, number uint64) ([]*core.TransactionReceipt, error) { + numBytes := core.MarshalBlockNumber(number) + prefix := db.ReceiptsByBlockNumberAndIndex.Key(numBytes) + + iterator, err := txn.NewIterator(prefix, true) + if err != nil { + return nil, err + } + + var receipts []*core.TransactionReceipt + + for iterator.First(); iterator.Valid(); iterator.Next() { + if !bytes.HasPrefix(iterator.Key(), prefix) { + break + } + + val, vErr := iterator.Value() + if vErr != nil { + return nil, utils.RunAndWrapOnError(iterator.Close, vErr) + } + + receipt := new(core.TransactionReceipt) + if err = encoder.Unmarshal(val, receipt); err != nil { + return nil, utils.RunAndWrapOnError(iterator.Close, err) + } + + receipts = append(receipts, receipt) + } + + if err = iterator.Close(); err != nil { + return nil, err + } + + return receipts, nil +} + +func storeBlockHeader(txn db.Transaction, header *core.Header) error { + numBytes := core.MarshalBlockNumber(header.Number) + + if err := txn.Set(db.BlockHeaderNumbersByHash.Key(header.Hash.Marshal()), numBytes); err != nil { + return err + } + + headerBytes, err := encoder.Marshal(header) + if err != nil { + return err + } + + return txn.Set(db.BlockHeadersByNumber.Key(numBytes), headerBytes) +} + +func storeBlockCommitments(txn db.Transaction, blockNumber uint64, commitments *core.BlockCommitments) error { + numBytes := core.MarshalBlockNumber(blockNumber) + + commitmentBytes, err := encoder.Marshal(commitments) + if err != nil { + return err + } + + return txn.Set(db.BlockCommitments.Key(numBytes), commitmentBytes) +} + +func storeL1HandlerMsgHashes(dbTxn db.Transaction, blockTxns []core.Transaction) error { + for _, txn := range blockTxns { + if l1Handler, ok := (txn).(*core.L1HandlerTransaction); ok { + err := dbTxn.Set(db.L1HandlerTxnHashByMsgHash.Key(l1Handler.MessageHash()), txn.Hash().Marshal()) + if err != nil { + return err + } + } + } + return nil +} diff --git a/migration/migration.go b/migration/migration.go index 47db65c3ce..069142a03e 100644 --- a/migration/migration.go +++ b/migration/migration.go @@ -12,7 +12,6 @@ import ( "sync" "github.com/NethermindEth/juno/adapters/sn2core" - "github.com/NethermindEth/juno/blockchain" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" "github.com/NethermindEth/juno/core/trie" @@ -257,7 +256,7 @@ func relocateContractStorageRootKeys(txn db.Transaction, _ *utils.Network) error // recalculateBloomFilters updates bloom filters in block headers to match what the most recent implementation expects func recalculateBloomFilters(txn db.Transaction, _ *utils.Network) error { for blockNumber := uint64(0); ; blockNumber++ { - block, err := blockchain.BlockByNumber(txn, blockNumber) + block, err := blockByNumber(txn, blockNumber) if err != nil { if errors.Is(err, db.ErrKeyNotFound) { return nil @@ -265,7 +264,7 @@ func recalculateBloomFilters(txn db.Transaction, _ *utils.Network) error { return err } block.EventsBloom = core.EventsBloom(block.Receipts) - if err = blockchain.StoreBlockHeader(txn, block.Header); err != nil { + if err = storeBlockHeader(txn, block.Header); err != nil { return err } } @@ -445,13 +444,14 @@ func processBlocks(txn db.Transaction, processBlock func(uint64, *sync.Mutex) er numOfWorkers := runtime.GOMAXPROCS(0) workerPool := pool.New().WithErrors().WithMaxGoroutines(numOfWorkers) - chainHeight, err := blockchain.ChainHeight(txn) + header, err := head(txn) if err != nil { if errors.Is(err, db.ErrKeyNotFound) { return nil } return err } + chainHeight := header.Number blockNumbers := make(chan uint64, 1024) //nolint:mnd go func() { for bNumber := range chainHeight + 1 { @@ -477,7 +477,7 @@ func processBlocks(txn db.Transaction, processBlock func(uint64, *sync.Mutex) er func calculateBlockCommitments(txn db.Transaction, network *utils.Network) error { processBlockFunc := func(blockNumber uint64, txnLock *sync.Mutex) error { txnLock.Lock() - block, err := blockchain.BlockByNumber(txn, blockNumber) + block, err := blockByNumber(txn, blockNumber) txnLock.Unlock() if err != nil { return err @@ -490,7 +490,7 @@ func calculateBlockCommitments(txn db.Transaction, network *utils.Network) error } txnLock.Lock() defer txnLock.Unlock() - return blockchain.StoreBlockCommitments(txn, block.Number, commitments) + return storeBlockCommitments(txn, block.Number, commitments) } return processBlocks(txn, processBlockFunc) } @@ -498,14 +498,16 @@ func calculateBlockCommitments(txn db.Transaction, network *utils.Network) error func calculateL1MsgHashes(txn db.Transaction, n *utils.Network) error { processBlockFunc := func(blockNumber uint64, txnLock *sync.Mutex) error { txnLock.Lock() - txns, err := blockchain.TransactionsByBlockNumber(txn, blockNumber) + block, err := blockByNumber(txn, blockNumber) txnLock.Unlock() if err != nil { return err } + + txns := block.Transactions txnLock.Lock() defer txnLock.Unlock() - return blockchain.StoreL1HandlerMsgHashes(txn, txns) + return storeL1HandlerMsgHashes(txn, txns) } return processBlocks(txn, processBlockFunc) }