Skip to content
Open
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
13 changes: 13 additions & 0 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
blockNumber, index uint64,
) (transaction core.Transaction, err error)
TransactionsByBlockNumber(blockNumber uint64) (transactions []core.Transaction, err error)
TransactionsAndReceiptsByBlockNumber(blockNumber uint64) (
transactions []core.Transaction,
receipts []*core.TransactionReceipt,
err error,
)
TransactionHashesByBlockNumber(blockNumber uint64) (hashes []felt.Felt, err error)

Receipt(
Expand Down Expand Up @@ -299,6 +304,14 @@
return core.GetTransactionsByBlockNumber(b.database, number)
}

// TransactionsAndReceiptsByBlockNumber gets all transactions and receipts for a given block number
func (b *Blockchain) TransactionsAndReceiptsByBlockNumber(
number uint64,
) ([]core.Transaction, []*core.TransactionReceipt, error) {
b.listener.OnRead("TransactionsAndReceiptsByBlockNumber")
return core.GetTransactionsAndReceiptsByBlockNumber(b.database, number)

Check warning on line 312 in blockchain/blockchain.go

View check run for this annotation

Codecov / codecov/patch

blockchain/blockchain.go#L310-L312

Added lines #L310 - L312 were not covered by tests
}

// BlockNumberAndIndexByTxHash gets transaction block number and index by Tx hash
func (b *Blockchain) BlockNumberAndIndexByTxHash(
hash *felt.TransactionHash,
Expand Down
29 changes: 23 additions & 6 deletions core/accessors.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,28 @@
return BlockTransactionsAllTransactionHashesPartialBucket.Get(r, blockNumber, struct{}{})
}

// GetTransactionsAndReceiptsByBlockNumber returns all transactions and receipts in a given block.
// Both live under the same key, so this reads the block only once.
func GetTransactionsAndReceiptsByBlockNumber(
r db.KeyValueReader,
blockNumber uint64,
) ([]Transaction, []*TransactionReceipt, error) {
result, err := BlockTransactionsAllTransactionsAndReceiptsPartialBucket.Get(
r,
blockNumber,
struct{}{},
)
if err != nil {
return nil, nil, fmt.Errorf(
"getting transactions and receipts of block %d: %w",
blockNumber,
err,
)

Check warning on line 532 in core/accessors.go

View check run for this annotation

Codecov / codecov/patch

core/accessors.go#L528-L532

Added lines #L528 - L532 were not covered by tests
}

return result.Transactions, result.Receipts, nil
}

// GetReceiptByBlockAndIndex returns a receipt by block number and transaction index
func GetReceiptByBlockAndIndex(
r db.KeyValueReader,
Expand Down Expand Up @@ -555,12 +577,7 @@
return nil, err
}

txs, err := GetTransactionsByBlockNumber(r, blockNumber)
if err != nil {
return nil, err
}

receipts, err := GetReceiptsByBlockNumber(r, blockNumber)
txs, receipts, err := GetTransactionsAndReceiptsByBlockNumber(r, blockNumber)
if err != nil {
return nil, err
}
Expand Down
6 changes: 6 additions & 0 deletions core/block_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ type TransactionAndReceipt struct {
Receipt *TransactionReceipt
}

// TransactionsAndReceipts holds every transaction and receipt of a single block.
type TransactionsAndReceipts struct {
Transactions []Transaction
Receipts []*TransactionReceipt
}

func NewBlockTransactionsFromIterators[T, R any](
transactions iter.Seq2[T, error],
receipts iter.Seq2[R, error],
Expand Down
26 changes: 26 additions & 0 deletions core/block_transaction_serializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,27 @@
return b.Receipts().All()
}

type extractAllTransactionsAndReceipts struct{}

// extract decodes both halves of the entry in one pass, so reading them together needs neither a
// second lookup nor a copy of the whole block blob.
func (extractAllTransactionsAndReceipts) extract(
b *BlockTransactions,
_ struct{},
) (TransactionsAndReceipts, error) {
transactions, err := b.Transactions().All()
if err != nil {
return TransactionsAndReceipts{}, fmt.Errorf("extracting transactions: %w", err)

Check warning on line 125 in core/block_transaction_serializer.go

View check run for this annotation

Codecov / codecov/patch

core/block_transaction_serializer.go#L125

Added line #L125 was not covered by tests
}

receipts, err := b.Receipts().All()
if err != nil {
return TransactionsAndReceipts{}, fmt.Errorf("extracting receipts: %w", err)

Check warning on line 130 in core/block_transaction_serializer.go

View check run for this annotation

Codecov / codecov/patch

core/block_transaction_serializer.go#L130

Added line #L130 was not covered by tests
}

return TransactionsAndReceipts{Transactions: transactions, Receipts: receipts}, nil
}

type extractAllTransactionEvents struct{}

func (extractAllTransactionEvents) extract(
Expand Down Expand Up @@ -190,6 +211,11 @@
struct{},
[]*TransactionReceipt,
]{}
BlockTransactionsAllTransactionsAndReceiptsPartialSerializer = blockTransactionsPartialSerializer[
Comment thread
EgeCaner marked this conversation as resolved.
extractAllTransactionsAndReceipts,
struct{},
TransactionsAndReceipts,
]{}
BlockTransactionsAllTransactionEventsPartialSerializer = blockTransactionsPartialSerializer[
extractAllTransactionEvents,
struct{},
Expand Down
10 changes: 10 additions & 0 deletions core/block_transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,16 @@ func TestBlockTransactionsSerializer(t *testing.T) {
)
})

t.Run("BlockTransactionsAllTransactionsAndReceiptsPartialSerializer", func(t *testing.T) {
assertPartialSerializer(
t,
core.BlockTransactionsAllTransactionsAndReceiptsPartialSerializer,
struct{}{},
core.TransactionsAndReceipts{Transactions: transactions, Receipts: receipts},
serialised,
)
})

t.Run("BlockTransactionsAllTransactionEventsPartialSerializer", func(t *testing.T) {
expected := make([]core.TransactionEvents, len(receipts))
for i, receipt := range receipts {
Expand Down
10 changes: 6 additions & 4 deletions core/pending/pending.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,20 +116,22 @@ func (p *PreConfirmed) GetTransactionStateDiffs() []*core.StateDiff {

// TransactionByHash locates a transaction by hash in the block and returns
// it together with its index. Returns ErrTransactionNotFound when missing.
func (p *PreConfirmed) TransactionByHash(hash *felt.Felt) (core.Transaction, uint, error) {
func (p *PreConfirmed) TransactionByHash(
hash *felt.TransactionHash,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you for detail attention and updating the types 🙏

) (core.Transaction, uint, error) {
for i, tx := range p.Block.Transactions {
if tx.Hash().Equal(hash) {
if tx.Hash().Equal((*felt.Felt)(hash)) {
return tx, uint(i), nil
}
}
return nil, 0, ErrTransactionNotFound
}

func (p *PreConfirmed) ReceiptByHash(
hash *felt.Felt,
hash *felt.TransactionHash,
) (*core.TransactionReceipt, error) {
for _, receipt := range p.Block.Receipts {
if receipt.TransactionHash.Equal(hash) {
if receipt.TransactionHash.Equal((*felt.Felt)(hash)) {
return receipt, nil
}
}
Expand Down
12 changes: 6 additions & 6 deletions core/pending/pending_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import (
)

func TestPreConfirmedTransactionByHash(t *testing.T) {
preConfirmedTxHash := felt.FromUint64[felt.Felt](2)
nonExistingTxHash := felt.FromUint64[felt.Felt](4)
preConfirmedTxHash := felt.FromUint64[felt.TransactionHash](2)
nonExistingTxHash := felt.FromUint64[felt.TransactionHash](4)

preConfirmedTx := &core.InvokeTransaction{
TransactionHash: &preConfirmedTxHash,
TransactionHash: (*felt.Felt)(&preConfirmedTxHash),
}

preConfirmed := &pending.PreConfirmed{
Expand All @@ -41,11 +41,11 @@ func TestPreConfirmedTransactionByHash(t *testing.T) {
}

func TestPreConfirmedReceiptByHash(t *testing.T) {
preConfirmedReceiptHash := felt.FromUint64[felt.Felt](2)
nonExistingReceiptHash := felt.FromUint64[felt.Felt](3)
preConfirmedReceiptHash := felt.FromUint64[felt.TransactionHash](2)
nonExistingReceiptHash := felt.FromUint64[felt.TransactionHash](3)

preConfirmedReceipt := core.TransactionReceipt{
TransactionHash: &preConfirmedReceiptHash,
TransactionHash: (*felt.Felt)(&preConfirmedReceiptHash),
}

preConfirmedBlockNumber := uint64(2)
Expand Down
5 changes: 5 additions & 0 deletions core/typed_buckets.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ var BlockTransactionsAllReceiptsPartialBucket = partial.NewPartialBucket(
BlockTransactionsAllReceiptsPartialSerializer,
)

var BlockTransactionsAllTransactionsAndReceiptsPartialBucket = partial.NewPartialBucket(
BlockTransactionsBucket.Bucket,
BlockTransactionsAllTransactionsAndReceiptsPartialSerializer,
)

var BlockTransactionsAllTransactionEventsPartialBucket = partial.NewPartialBucket(
BlockTransactionsBucket.Bucket,
BlockTransactionsAllTransactionEventsPartialSerializer,
Expand Down
16 changes: 16 additions & 0 deletions mocks/mock_blockchain.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions rpc/rpccore/rpccore.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"

"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/jsonrpc"
"github.com/NethermindEth/juno/l1/eth"
)
Expand Down Expand Up @@ -35,10 +34,6 @@ type L1Client interface {
TransactionReceipt(ctx context.Context, txHash eth.Hash) (eth.Receipt, error)
}

type TraceCacheKey struct {
BlockHash felt.Felt
}

var (
ErrContractNotFound = &jsonrpc.Error{Code: 20, Message: "Contract not found"}
ErrEntrypointNotFound = &jsonrpc.Error{
Expand Down
6 changes: 3 additions & 3 deletions rpc/v10/adapt_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -303,14 +303,14 @@ func adaptVMInitialReads(vmInitialReads *vm.InitialReads) InitialReads {
*****************************************************/

func AdaptFeederBlockTrace(
block *core.Block,
transactions []core.Transaction,
blockTrace *starknet.BlockTrace,
) ([]TracedBlockTransaction, error) {
if blockTrace == nil {
return nil, nil
}

if len(block.Transactions) != len(blockTrace.Traces) {
if len(transactions) != len(blockTrace.Traces) {
return nil, errors.New("mismatched number of txs and traces")
}

Expand All @@ -320,7 +320,7 @@ func AdaptFeederBlockTrace(
feederTrace := &blockTrace.Traces[index]

trace := TransactionTrace{
Type: transactionTypeFrom(block.Transactions[index]),
Type: transactionTypeFrom(transactions[index]),
}

if feederTrace.FeeTransferInvocation != nil && trace.Type != TxnL1Handler {
Expand Down
7 changes: 3 additions & 4 deletions rpc/v10/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/NethermindEth/juno/blockchain"
"github.com/NethermindEth/juno/clients/feeder"
"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/core/pending"
"github.com/NethermindEth/juno/feed"
"github.com/NethermindEth/juno/jsonrpc"
Expand Down Expand Up @@ -42,9 +43,7 @@ type Handler struct {
idgen func() string
subscriptions stdsync.Map // map[string]*subscription

// todo(rdr): why do we have the `TraceCacheKey` type and why it feels uncomfortable
// to use. It makes no sense, why not use `Felt` or `Hash` directly?
blockTraceCache *lru.Cache[rpccore.TraceCacheKey, TraceBlockTransactionsResponse]
blockTraceCache *lru.Cache[felt.Felt, TraceBlockTransactionsResponse]
// todo(rdr): Can this cache be genericified and can it be applied to the `blockTraceCache`
submittedTransactionsCache *rpccore.TransactionCache

Expand Down Expand Up @@ -86,7 +85,7 @@ func New(
l1Heads: feed.New[*core.L1Head](),

blockTraceCache: lru.New[
rpccore.TraceCacheKey,
felt.Felt,
TraceBlockTransactionsResponse,
](rpccore.TraceCacheSize),
filterLimit: math.MaxUint,
Expand Down
4 changes: 3 additions & 1 deletion rpc/v10/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ func TestThrottledVMError(t *testing.T) {
Transactions: []core.Transaction{l1Tx, declareTx},
}

mockReader.EXPECT().BlockByHash(blockHash).Return(block, nil)
mockReader.EXPECT().BlockHeaderByHash(blockHash).Return(header, nil)
mockReader.EXPECT().TransactionsByBlockNumber(header.Number).
Return(block.Transactions, nil)
state := mocks.NewMockStateReader(mockCtrl)
mockReader.EXPECT().StateAtBlockHash(header.ParentHash).Return(state, nopCloser, nil)
headState := mocks.NewMockStateReader(mockCtrl)
Expand Down
Loading
Loading