Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,24 +184,26 @@ func (b *Blockchain) L1HandlerTxnHash(msgHash *common.Hash) (felt.Felt, error) {
// TransactionByBlockNumberAndIndex gets the transaction for a given block number and index.
func (b *Blockchain) TransactionByBlockNumberAndIndex(blockNumber, index uint64) (core.Transaction, error) {
b.listener.OnRead("TransactionByBlockNumberAndIndex")
return core.GetTxByBlockNumIndex(b.database, blockNumber, index)
return core.GetTxByBlockNumberAndIndex(b.database, blockNumber, index)
}

// TransactionByHash gets the transaction for a given hash.
func (b *Blockchain) TransactionByHash(hash *felt.Felt) (core.Transaction, error) {
b.listener.OnRead("TransactionByHash")
return core.GetTxByHash(b.database, hash)
return core.GetTxByHash(b.database, (*felt.TransactionHash)(hash))
}

// Receipt gets the transaction receipt for a given transaction hash.
// TODO: Return TransactionReceipt instead of *TransactionReceipt.
func (b *Blockchain) Receipt(hash *felt.Felt) (*core.TransactionReceipt, *felt.Felt, uint64, error) {
b.listener.OnRead("Receipt")
bnIndex, err := core.GetTxBlockNumIndexByHash(b.database, hash)
txHash := (*felt.TransactionHash)(hash)
bnIndex, err := core.TransactionBlockNumbersAndIndicesByHashBucket.Get(b.database, txHash)
if err != nil {
return nil, nil, 0, err
}

receipt, err := core.GetReceiptByHash(b.database, hash)
receipt, err := core.GetReceiptByBlockNumberAndIndex(b.database, bnIndex.Number, bnIndex.Index)
if err != nil {
return nil, nil, 0, err
}
Expand Down Expand Up @@ -248,11 +250,13 @@ func (b *Blockchain) Store(
return err
}

for i, tx := range block.Transactions {
if err := core.WriteTxAndReceipt(txn, block.Number, uint64(i), tx,
block.Receipts[i]); err != nil {
return err
}
if err := core.WriteTransactionsAndReceipts(
txn,
block.Number,
block.Transactions,
block.Receipts,
); err != nil {
Comment on lines +253 to +258
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's separate the assign from the if please

return err
}

if err := core.WriteStateUpdateByBlockNum(txn, block.Number, stateUpdate); err != nil {
Expand Down Expand Up @@ -717,11 +721,13 @@ func (b *Blockchain) storeBlockData(
return err
}

// Store transactions and receipts
for i, tx := range block.Transactions {
if err := core.WriteTxAndReceipt(txn, block.Number, uint64(i), tx, block.Receipts[i]); err != nil {
return err
}
if err := core.WriteTransactionsAndReceipts(
txn,
block.Number,
block.Transactions,
block.Receipts,
); err != nil {
Comment on lines +724 to +729
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here as well 🙏

return err
}

// Store state update
Expand Down
226 changes: 64 additions & 162 deletions core/accessors.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/db"
"github.com/NethermindEth/juno/encoder"
"github.com/NethermindEth/juno/utils"
)

/**
Expand Down Expand Up @@ -247,67 +246,40 @@ func DeleteBlockHeaderByNumber(w db.KeyValueWriter, number uint64) error {
return w.Delete(db.BlockHeaderByNumberKey(number))
}

func GetReceiptByBlockNumIndexBytes(r db.KeyValueReader, bnIndex []byte) (*TransactionReceipt, error) {
var (
receipt *TransactionReceipt
val []byte
)
err := r.Get(db.ReceiptByBlockNumIndexKeyBytes(bnIndex), func(data []byte) error {
val = data
return nil
})
func GetReceiptByBlockNumberAndIndex(
r db.KeyValueReader,
blockNumber uint64,
index uint64,
) (*TransactionReceipt, error) {
blockTransactions, err := BlockTransactionsBucket.Get(r, blockNumber)
if err != nil {
return nil, err
}
if err = encoder.Unmarshal(val, &receipt); err != nil {
return nil, err
}
return receipt, nil
}

func WriteReceiptByBlockNumIndex(w db.KeyValueWriter, num, index uint64, receipt *TransactionReceipt) error {
data, err := encoder.Marshal(receipt)
if err != nil {
return err
if index >= uint64(len(blockTransactions.Receipts)) {
return nil, db.ErrKeyNotFound
}
return w.Put(db.ReceiptByBlockNumIndexKey(num, index), data)
}

func DeleteReceiptByBlockNumIndex(w db.KeyValueWriter, num, index uint64) error {
return w.Delete(db.ReceiptByBlockNumIndexKey(num, index))
return blockTransactions.Receipts[index], nil
}

func GetReceiptByHash(r db.KeyValueReader, hash *felt.Felt) (*TransactionReceipt, error) {
var val []byte
err := r.Get(db.TxBlockNumIndexByHashKey(hash), func(data []byte) error {
val = data
return nil
})
func DeleteTxsAndReceipts(batch db.IndexedBatch, blockNum, numTxs uint64) error {
blockTransactions, err := BlockTransactionsBucket.Get(batch, blockNum)
if err != nil {
return nil, err
return err
}

return GetReceiptByBlockNumIndexBytes(r, val)
}
if err := BlockTransactionsBucket.Delete(batch, blockNum); err != nil {
return err
}

func DeleteTxsAndReceipts(batch db.IndexedBatch, blockNum, numTxs uint64) error {
// remove txs and receipts
for i := range numTxs {
txn, err := GetTxByBlockNumIndex(batch, blockNum, i)
if err != nil {
for _, tx := range blockTransactions.Transactions {
txHash := (*felt.TransactionHash)(tx.Hash())
if err := TransactionBlockNumbersAndIndicesByHashBucket.Delete(batch, txHash); err != nil {
return err
}

if err := DeleteTxByBlockNumIndex(batch, blockNum, i); err != nil {
return err
}
if err := DeleteReceiptByBlockNumIndex(batch, blockNum, i); err != nil {
return err
}
if err := DeleteTxBlockNumIndexByHash(batch, txn.Hash()); err != nil {
return err
}
if l1handler, ok := txn.(*L1HandlerTransaction); ok {
if l1handler, ok := tx.(*L1HandlerTransaction); ok {
if err := DeleteL1HandlerTxnHashByMsgHash(batch, l1handler.MessageHash()); err != nil {
return err
}
Expand Down Expand Up @@ -411,64 +383,25 @@ func WriteBlockHeader(w db.KeyValueWriter, header *Header) error {

// Returns all transactions in a given block
func GetTxsByBlockNum(r db.KeyValueReader, blockNum uint64) ([]Transaction, error) {
prefix := db.TransactionsByBlockNumberAndIndex.Key(MarshalBlockNumber(blockNum))

it, err := r.NewIterator(prefix, true)
blockTransactions, err := BlockTransactionsBucket.Get(r, blockNum)
if err != nil {
return nil, err
}

var txs []Transaction
for it.First(); it.Valid(); it.Next() {
val, vErr := it.Value()
if vErr != nil {
return nil, utils.RunAndWrapOnError(it.Close, vErr)
}

var tx Transaction
if err = encoder.Unmarshal(val, &tx); err != nil {
return nil, utils.RunAndWrapOnError(it.Close, err)
}

txs = append(txs, tx)
}

if err = it.Close(); err != nil {
return nil, err
}

return txs, nil
return blockTransactions.Transactions, nil
}

// Returns all receipts in a given block
func GetReceiptsByBlockNum(r db.KeyValueReader, blockNum uint64) ([]*TransactionReceipt, error) {
prefix := db.ReceiptsByBlockNumberAndIndex.Key(MarshalBlockNumber(blockNum))

it, err := r.NewIterator(prefix, true)
func GetReceiptsByBlockNum(
r db.KeyValueReader,
blockNum uint64,
) ([]*TransactionReceipt, error) {
blockTransactions, err := BlockTransactionsBucket.Get(r, blockNum)
if err != nil {
return nil, err
}

var receipts []*TransactionReceipt
for it.First(); it.Valid(); it.Next() {
val, vErr := it.Value()
if vErr != nil {
return nil, utils.RunAndWrapOnError(it.Close, vErr)
}

var receipt *TransactionReceipt
if err = encoder.Unmarshal(val, &receipt); err != nil {
return nil, utils.RunAndWrapOnError(it.Close, err)
}

receipts = append(receipts, receipt)
}

if err = it.Close(); err != nil {
return nil, err
}

return receipts, nil
return blockTransactions.Receipts, nil
}

func GetBlockByNumber(r db.KeyValueReader, blockNum uint64) (*Block, error) {
Expand All @@ -477,102 +410,71 @@ func GetBlockByNumber(r db.KeyValueReader, blockNum uint64) (*Block, error) {
return nil, err
}

txs, err := GetTxsByBlockNum(r, blockNum)
if err != nil {
return nil, err
}

receipts, err := GetReceiptsByBlockNum(r, blockNum)
blockTransactions, err := BlockTransactionsBucket.Get(r, blockNum)
if err != nil {
return nil, err
}

return &Block{
Header: header,
Transactions: txs,
Receipts: receipts,
Transactions: blockTransactions.Transactions,
Receipts: blockTransactions.Receipts,
}, nil
}

func GetTxBlockNumIndexByHash(r db.KeyValueReader, hash *felt.Felt) (db.BlockNumIndexKey, error) {
bnIndex := db.BlockNumIndexKey{}
err := r.Get(db.TxBlockNumIndexByHashKey(hash), bnIndex.UnmarshalBinary)
return bnIndex, err
}

func WriteTxBlockNumIndexByHash(w db.KeyValueWriter, num, index uint64, hash *felt.Felt) error {
val := db.BlockNumIndexKey{
Number: num,
Index: index,
}
return w.Put(db.TxBlockNumIndexByHashKey(hash), val.Marshal())
}

func DeleteTxBlockNumIndexByHash(w db.KeyValueWriter, hash *felt.Felt) error {
return w.Delete(db.TxBlockNumIndexByHashKey(hash))
}
func WriteTransactionsAndReceipts(
w db.KeyValueWriter,
blockNumber uint64,
transactions []Transaction,
receipts []*TransactionReceipt,
) error {
for index, tx := range transactions {
txHash := (*felt.TransactionHash)(tx.Hash())
key := db.BlockNumIndexKey{
Number: blockNumber,
Index: uint64(index),
}

func GetTxByBlockNumIndex(r db.KeyValueReader, blockNum, index uint64) (Transaction, error) {
var tx Transaction
err := r.Get(db.TxByBlockNumIndexKey(blockNum, index), func(data []byte) error {
return encoder.Unmarshal(data, &tx)
})
if err != nil {
return nil, err
if err := TransactionBlockNumbersAndIndicesByHashBucket.Put(w, txHash, &key); err != nil {
return err
}
}
return tx, nil
}

func GetTxByBlockNumIndexBytes(r db.KeyValueReader, val []byte) (Transaction, error) {
var tx Transaction
err := r.Get(db.TxByBlockNumIndexKeyBytes(val), func(data []byte) error {
return encoder.Unmarshal(data, &tx)
})
if err != nil {
return nil, err
blockTransactions := BlockTransactions{
Transactions: transactions,
Receipts: receipts,
}
return tx, nil
}

func WriteTxByBlockNumIndex(w db.KeyValueWriter, num, index uint64, tx Transaction) error {
enc, err := encoder.Marshal(tx)
if err != nil {
if err := BlockTransactionsBucket.Put(w, blockNumber, &blockTransactions); err != nil {
return err
}
return w.Put(db.TxByBlockNumIndexKey(num, index), enc)
}

func DeleteTxByBlockNumIndex(w db.KeyValueWriter, num, index uint64) error {
return w.Delete(db.TxByBlockNumIndexKey(num, index))
return nil
}

func WriteTxAndReceipt(w db.KeyValueWriter, num, index uint64, tx Transaction, receipt *TransactionReceipt) error {
if err := WriteTxBlockNumIndexByHash(w, num, index, receipt.TransactionHash); err != nil {
return err
}

if err := WriteTxByBlockNumIndex(w, num, index, tx); err != nil {
return err
func GetTxByBlockNumberAndIndex(
r db.KeyValueReader,
blockNumber uint64,
index uint64,
) (Transaction, error) {
blockTransactions, err := BlockTransactionsBucket.Get(r, blockNumber)
if err != nil {
return nil, err
}

if err := WriteReceiptByBlockNumIndex(w, num, index, receipt); err != nil {
return err
if index >= uint64(len(blockTransactions.Transactions)) {
return nil, db.ErrKeyNotFound
}

return nil
return blockTransactions.Transactions[index], nil
}

func GetTxByHash(r db.KeyValueReader, hash *felt.Felt) (Transaction, error) {
var val []byte
err := r.Get(db.TxBlockNumIndexByHashKey(hash), func(data []byte) error {
val = data
return nil
})
func GetTxByHash(r db.KeyValueReader, hash *felt.TransactionHash) (Transaction, error) {
blockNumIndex, err := TransactionBlockNumbersAndIndicesByHashBucket.Get(r, hash)
if err != nil {
return nil, err
}

return GetTxByBlockNumIndexBytes(r, val)
return GetTxByBlockNumberAndIndex(r, blockNumIndex.Number, blockNumIndex.Index)
}

func GetAggregatedBloomFilter(r db.KeyValueReader, fromBlock, toBLock uint64) (AggregatedBloomFilter, error) {
Expand Down
6 changes: 6 additions & 0 deletions core/block_transaction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package core

type BlockTransactions struct {
Transactions []Transaction `cbor:"1,keyasint,omitempty"`
Receipts []*TransactionReceipt `cbor:"2,keyasint,omitempty"`
}
1 change: 1 addition & 0 deletions core/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ type BuiltinInstanceCounter struct {
}

type Transaction interface {
// TODO: This should be TransactionHash instead of Felt.
Hash() *felt.Felt
Signature() []*felt.Felt
TxVersion() *TransactionVersion
Expand Down
Loading
Loading