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
7 changes: 7 additions & 0 deletions blockchain/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type Reader interface {
BlockHeaderByNumber(number uint64) (header *core.Header, err error)
BlockHeaderByHash(hash *felt.Felt) (header *core.Header, err error)

BlockNumberByHash(hash *felt.Felt) (uint64, error)

TransactionByHash(hash *felt.Felt) (transaction core.Transaction, err error)
TransactionByBlockNumberAndIndex(blockNumber, index uint64) (transaction core.Transaction, err error)
Receipt(hash *felt.Felt) (receipt *core.TransactionReceipt, blockHash *felt.Felt, blockNumber uint64, err error)
Expand Down Expand Up @@ -150,6 +152,11 @@ func (b *Blockchain) BlockHeaderByNumber(number uint64) (*core.Header, error) {
return core.GetBlockHeaderByNumber(b.database, number)
}

func (b *Blockchain) BlockNumberByHash(hash *felt.Felt) (uint64, error) {
b.listener.OnRead("BlockNumberByHash")
return core.GetBlockHeaderNumberByHash(b.database, hash)
}

func (b *Blockchain) BlockByHash(hash *felt.Felt) (*core.Block, error) {
b.listener.OnRead("BlockByHash")
blockNum, err := core.GetBlockHeaderNumberByHash(b.database, hash)
Expand Down
13 changes: 13 additions & 0 deletions mocks/mock_blockchain.go

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

File renamed without changes.
27 changes: 20 additions & 7 deletions rpc/v6/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,16 @@ func (h *Handler) TransactionByHash(hash felt.Felt) (*Transaction, *jsonrpc.Erro
//
// It follows the specification defined here:
// https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json#L184
func (h *Handler) TransactionByBlockIDAndIndex(id BlockID, txIndex int) (*Transaction, *jsonrpc.Error) {
func (h *Handler) TransactionByBlockIDAndIndex(
id BlockID,
txIndex int,
) (*Transaction, *jsonrpc.Error) {
if txIndex < 0 {
return nil, rpccore.ErrInvalidTxIndex
}

var blockNumber uint64
var err error
if id.Pending {
pending, err := h.PendingData()
if err != nil {
Expand All @@ -500,14 +505,22 @@ func (h *Handler) TransactionByBlockIDAndIndex(id BlockID, txIndex int) (*Transa
}

return AdaptTransaction(pending.GetBlock().Transactions[txIndex]), nil
} else if id.Latest {
header, err := h.bcReader.HeadsHeader()
if err != nil {
return nil, rpccore.ErrBlockNotFound
}
blockNumber = header.Number
} else if id.Hash != nil {
blockNumber, err = h.bcReader.BlockNumberByHash(id.Hash)
if err != nil {
return nil, rpccore.ErrBlockNotFound
}
} else {
blockNumber = id.Number
}

header, rpcErr := h.blockHeaderByID(&id)
if rpcErr != nil {
return nil, rpcErr
}

txn, err := h.bcReader.TransactionByBlockNumberAndIndex(header.Number, uint64(txIndex))
txn, err := h.bcReader.TransactionByBlockNumberAndIndex(blockNumber, uint64(txIndex))
if err != nil {
return nil, rpccore.ErrInvalidTxIndex
}
Expand Down
13 changes: 7 additions & 6 deletions rpc/v6/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
})

t.Run("non-existent block hash", func(t *testing.T) {
mockReader.EXPECT().BlockHeaderByHash(gomock.Any()).Return(nil, db.ErrKeyNotFound)
mockReader.EXPECT().BlockNumberByHash(gomock.Any()).Return(uint64(0), db.ErrKeyNotFound)

txn, rpcErr := handler.TransactionByBlockIDAndIndex(
rpc.BlockID{Hash: new(felt.Felt).SetBytes([]byte("random"))}, rand.Int())
Expand All @@ -485,11 +485,13 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
})

t.Run("non-existent block number", func(t *testing.T) {
mockReader.EXPECT().BlockHeaderByNumber(gomock.Any()).Return(nil, db.ErrKeyNotFound)
blockNumber := rpc.BlockID{Number: rand.Uint64()}

txn, rpcErr := handler.TransactionByBlockIDAndIndex(rpc.BlockID{Number: rand.Uint64()}, rand.Int())
mockReader.EXPECT().TransactionByBlockNumberAndIndex(blockNumber.Number,
gomock.Any()).Return(nil, errors.New("invalid index"))
txn, rpcErr := handler.TransactionByBlockIDAndIndex(blockNumber, rand.Int())
assert.Nil(t, txn)
assert.Equal(t, rpccore.ErrBlockNotFound, rpcErr)
assert.Equal(t, rpccore.ErrInvalidTxIndex, rpcErr)
})

t.Run("negative index", func(t *testing.T) {
Expand Down Expand Up @@ -533,7 +535,7 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
t.Run("blockID - hash", func(t *testing.T) {
index := rand.Intn(int(latestBlock.TransactionCount))

mockReader.EXPECT().BlockHeaderByHash(latestBlockHash).Return(latestBlock.Header, nil)
mockReader.EXPECT().BlockNumberByHash(latestBlockHash).Return(latestBlock.Number, nil)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(uint64(latestBlockNumber),
uint64(index)).DoAndReturn(func(number, index uint64) (core.Transaction, error) {
return latestBlock.Transactions[index], nil
Expand All @@ -555,7 +557,6 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
t.Run("blockID - number", func(t *testing.T) {
index := rand.Intn(int(latestBlock.TransactionCount))

mockReader.EXPECT().BlockHeaderByNumber(uint64(latestBlockNumber)).Return(latestBlock.Header, nil)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(uint64(latestBlockNumber),
uint64(index)).DoAndReturn(func(number, index uint64) (core.Transaction, error) {
return latestBlock.Transactions[index], nil
Expand Down
28 changes: 20 additions & 8 deletions rpc/v7/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,12 +392,16 @@ func adaptRPCTxToFeederTx(rpcTx *Transaction) *starknet.Transaction {
//
// It follows the specification defined here:
// https://github.com/starkware-libs/starknet-specs/blob/master/api/starknet_api_openrpc.json#L184
func (h *Handler) TransactionByBlockIDAndIndex(id BlockID, txIndex int) (*Transaction, *jsonrpc.Error) {
func (h *Handler) TransactionByBlockIDAndIndex(
id BlockID, txIndex int,
) (*Transaction, *jsonrpc.Error) {
if txIndex < 0 {
return nil, rpccore.ErrInvalidTxIndex
}

if id.Pending {
var blockNumber uint64
var err error
if id.IsPending() {
pending, err := h.PendingData()
if err != nil {
return nil, rpccore.ErrBlockNotFound
Expand All @@ -408,14 +412,22 @@ func (h *Handler) TransactionByBlockIDAndIndex(id BlockID, txIndex int) (*Transa
}

return AdaptTransaction(pending.GetBlock().Transactions[txIndex]), nil
} else if id.IsLatest() {
header, err := h.bcReader.HeadsHeader()
if err != nil {
return nil, rpccore.ErrBlockNotFound
}
blockNumber = header.Number
} else if id.Hash != nil {
blockNumber, err = h.bcReader.BlockNumberByHash(id.Hash)
if err != nil {
return nil, rpccore.ErrBlockNotFound
}
} else {
blockNumber = id.Number
}

header, rpcErr := h.blockHeaderByID(&id)
if rpcErr != nil {
return nil, rpcErr
}

txn, err := h.bcReader.TransactionByBlockNumberAndIndex(header.Number, uint64(txIndex))
txn, err := h.bcReader.TransactionByBlockNumberAndIndex(blockNumber, uint64(txIndex))
if err != nil {
return nil, rpccore.ErrInvalidTxIndex
}
Expand Down
11 changes: 6 additions & 5 deletions rpc/v7/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,22 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
})

t.Run("non-existent block hash", func(t *testing.T) {
mockReader.EXPECT().BlockHeaderByHash(gomock.Any()).Return(nil, db.ErrKeyNotFound)
mockReader.EXPECT().BlockNumberByHash(gomock.Any()).Return(uint64(0), db.ErrKeyNotFound)

txn, rpcErr := handler.TransactionByBlockIDAndIndex(
rpc.BlockID{Hash: new(felt.Felt).SetBytes([]byte("random"))}, rand.Int())

assert.Nil(t, txn)
assert.Equal(t, rpccore.ErrBlockNotFound, rpcErr)
})

t.Run("non-existent block number", func(t *testing.T) {
mockReader.EXPECT().BlockHeaderByNumber(gomock.Any()).Return(nil, db.ErrKeyNotFound)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(gomock.Any(),
gomock.Any()).Return(nil, errors.New("invalid index"))

txn, rpcErr := handler.TransactionByBlockIDAndIndex(rpc.BlockID{Number: rand.Uint64()}, rand.Int())
assert.Nil(t, txn)
assert.Equal(t, rpccore.ErrBlockNotFound, rpcErr)
assert.Equal(t, rpccore.ErrInvalidTxIndex, rpcErr)
})

t.Run("negative index", func(t *testing.T) {
Expand Down Expand Up @@ -107,7 +109,7 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
t.Run("blockID - hash", func(t *testing.T) {
index := rand.Intn(int(latestBlock.TransactionCount))

mockReader.EXPECT().BlockHeaderByHash(latestBlockHash).Return(latestBlock.Header, nil)
mockReader.EXPECT().BlockNumberByHash(latestBlockHash).Return(latestBlock.Number, nil)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(uint64(latestBlockNumber),
uint64(index)).DoAndReturn(func(number, index uint64) (core.Transaction, error) {
return latestBlock.Transactions[index], nil
Expand All @@ -134,7 +136,6 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
t.Run("blockID - number", func(t *testing.T) {
index := rand.Intn(int(latestBlock.TransactionCount))

mockReader.EXPECT().BlockHeaderByNumber(uint64(latestBlockNumber)).Return(latestBlock.Header, nil)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(uint64(latestBlockNumber),
uint64(index)).DoAndReturn(func(number, index uint64) (core.Transaction, error) {
return latestBlock.Transactions[index], nil
Expand Down
24 changes: 19 additions & 5 deletions rpc/v8/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,10 @@ func (h *Handler) TransactionByBlockIDAndIndex(
return nil, rpccore.ErrInvalidTxIndex
}

if blockID.IsPending() {
var blockNumber uint64
var err error
switch blockID.Type() {
case pending:
pending, err := h.PendingData()
if err != nil {
return nil, rpccore.ErrBlockNotFound
Expand All @@ -520,14 +523,25 @@ func (h *Handler) TransactionByBlockIDAndIndex(
}

return AdaptTransaction(pending.GetBlock().Transactions[txIndex]), nil
case latest:
header, err := h.bcReader.HeadsHeader()
if err != nil {
return nil, rpccore.ErrBlockNotFound
}
blockNumber = header.Number
case hash:
blockNumber, err = h.bcReader.BlockNumberByHash(blockID.Hash())
case number:
blockNumber = blockID.Number()
default:
panic("unknown block type id")
}

header, rpcErr := h.blockHeaderByID(blockID)
if rpcErr != nil {
return nil, rpcErr
if err != nil {
return nil, rpccore.ErrBlockNotFound
}

txn, err := h.bcReader.TransactionByBlockNumberAndIndex(header.Number, uint64(txIndex))
txn, err := h.bcReader.TransactionByBlockNumberAndIndex(blockNumber, uint64(txIndex))
if err != nil {
return nil, rpccore.ErrInvalidTxIndex
}
Expand Down
10 changes: 5 additions & 5 deletions rpc/v8/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
})

t.Run("non-existent block hash", func(t *testing.T) {
mockReader.EXPECT().BlockHeaderByHash(gomock.Any()).Return(nil, db.ErrKeyNotFound)
mockReader.EXPECT().BlockNumberByHash(gomock.Any()).Return(uint64(0), db.ErrKeyNotFound)

blockID := blockIDHash(t, new(felt.Felt).SetBytes([]byte("random")))
txn, rpcErr := handler.TransactionByBlockIDAndIndex(&blockID, rand.Int())
Expand All @@ -485,12 +485,13 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
})

t.Run("non-existent block number", func(t *testing.T) {
mockReader.EXPECT().BlockHeaderByNumber(gomock.Any()).Return(nil, db.ErrKeyNotFound)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(gomock.Any(),
gomock.Any()).Return(nil, errors.New("invalid index"))

blockID := blockIDNumber(t, rand.Uint64())
txn, rpcErr := handler.TransactionByBlockIDAndIndex(&blockID, rand.Int())
assert.Nil(t, txn)
assert.Equal(t, rpccore.ErrBlockNotFound, rpcErr)
assert.Equal(t, rpccore.ErrInvalidTxIndex, rpcErr)
})

t.Run("negative index", func(t *testing.T) {
Expand Down Expand Up @@ -537,7 +538,7 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
t.Run("blockID - hash", func(t *testing.T) {
index := rand.Intn(int(latestBlock.TransactionCount))

mockReader.EXPECT().BlockHeaderByHash(latestBlockHash).Return(latestBlock.Header, nil)
mockReader.EXPECT().BlockNumberByHash(latestBlockHash).Return(latestBlock.Number, nil)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(latestBlockNumber,
uint64(index)).DoAndReturn(func(number, index uint64) (core.Transaction, error) {
return latestBlock.Transactions[index], nil
Expand All @@ -560,7 +561,6 @@ func TestTransactionByBlockIdAndIndex(t *testing.T) {
t.Run("blockID - number", func(t *testing.T) {
index := rand.Intn(int(latestBlock.TransactionCount))

mockReader.EXPECT().BlockHeaderByNumber(latestBlockNumber).Return(latestBlock.Header, nil)
mockReader.EXPECT().TransactionByBlockNumberAndIndex(latestBlockNumber,
uint64(index)).DoAndReturn(func(number, index uint64) (core.Transaction, error) {
return latestBlock.Transactions[index], nil
Expand Down
31 changes: 26 additions & 5 deletions rpc/v9/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,10 @@ func (h *Handler) TransactionByBlockIDAndIndex(
return nil, rpccore.ErrInvalidTxIndex
}

if blockID.IsPreConfirmed() {
var blockNumber uint64
var err error
switch blockID.Type() {
case preConfirmed:
pending, err := h.PendingData()
if err != nil {
return nil, rpccore.ErrBlockNotFound
Expand All @@ -548,14 +551,32 @@ func (h *Handler) TransactionByBlockIDAndIndex(
}

return AdaptTransaction(pending.GetBlock().Transactions[txIndex]), nil
case latest:
header, err := h.bcReader.HeadsHeader()
if err != nil {
return nil, rpccore.ErrBlockNotFound
}
blockNumber = header.Number
case hash:
blockNumber, err = h.bcReader.BlockNumberByHash(blockID.Hash())
case number:
blockNumber = blockID.Number()
case l1Accepted:
var l1Head core.L1Head
l1Head, err = h.bcReader.L1Head()
if err != nil {
break
}
blockNumber = l1Head.BlockNumber
default:
panic("unknown block type id")
}

header, rpcErr := h.blockHeaderByID(blockID)
if rpcErr != nil {
return nil, rpcErr
if err != nil {
return nil, rpccore.ErrBlockNotFound
}

txn, err := h.bcReader.TransactionByBlockNumberAndIndex(header.Number, uint64(txIndex))
txn, err := h.bcReader.TransactionByBlockNumberAndIndex(blockNumber, uint64(txIndex))
Copy link
Contributor

Choose a reason for hiding this comment

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

We're having 4 versions in v6, v7, v8 and v9, please also fix for the other versions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup, I'll update other versions, once the v9 implementation is good enough :)

Copy link
Collaborator

Choose a reason for hiding this comment

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

No need v8, v9 and v10 only please

if err != nil {
return nil, rpccore.ErrInvalidTxIndex
}
Expand Down
Loading
Loading