Skip to content

Commit

Permalink
Refactor rpc handlers and tests (#1768)
Browse files Browse the repository at this point in the history
All handlers and related helper methods was moved from `rpc/handlers` to the
corresponding "category" file, e.g. block, transaction, trace...

Handlers tests were refactor the same way.

I introduced new files in `rpc/` folder:

- `chain.go` - with `ChainId` handler
- `class.go` - `Class*` handlers
- `contract.go` - `Nonce` & `StorageAt`
- `estimate_fee.go`
- `helpers.go` - which contains helper functionality used in more than one
  "category".

Co-authored-by: IronGauntlets <[email protected]>
  • Loading branch information
pnowosie and IronGauntlets authored Apr 21, 2024
1 parent e43b0f3 commit c04fa8e
Show file tree
Hide file tree
Showing 27 changed files with 5,754 additions and 5,417 deletions.
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.18.2
github.com/stretchr/testify v1.8.4
github.com/stretchr/testify v1.9.0
go.uber.org/automaxprocs v1.5.3
go.uber.org/mock v0.4.0
go.uber.org/zap v1.26.0
Expand Down Expand Up @@ -136,7 +136,7 @@ require (
github.com/opencontainers/runtime-spec v1.1.0 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/polydawn/refmt v0.89.0 // indirect
github.com/prometheus/client_model v0.6.0 // indirect
Expand All @@ -160,7 +160,7 @@ require (
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.22.0 // indirect
go.opentelemetry.io/otel/metric v1.22.0 // indirect
Expand Down
12 changes: 7 additions & 5 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,8 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
Expand Down Expand Up @@ -517,6 +517,7 @@ github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
Expand All @@ -526,8 +527,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
Expand Down Expand Up @@ -561,8 +563,8 @@ github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsr
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
Expand Down
227 changes: 227 additions & 0 deletions rpc/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import (
"errors"
"fmt"

"github.com/NethermindEth/juno/core"
"github.com/NethermindEth/juno/core/felt"
"github.com/NethermindEth/juno/jsonrpc"
)

// https://github.com/starkware-libs/starknet-specs/blob/fbf8710c2d2dcdb70a95776f257d080392ad0816/api/starknet_api_openrpc.json#L2353-L2363
Expand Down Expand Up @@ -134,3 +136,228 @@ type BlockWithReceipts struct {
BlockHeader
Transactions []TransactionWithReceipt `json:"transactions"`
}

/****************************************************
Block Handlers
*****************************************************/

// BlockNumber returns the latest synced block number.
//
// It follows the specification defined here:
// https://github.com/starkware-libs/starknet-specs/blob/a789ccc3432c57777beceaa53a34a7ae2f25fda0/api/starknet_api_openrpc.json#L500
func (h *Handler) BlockNumber() (uint64, *jsonrpc.Error) {
num, err := h.bcReader.Height()
if err != nil {
return 0, ErrNoBlock
}

return num, nil
}

// BlockHashAndNumber returns the block hash and number of the latest synced block.
//
// It follows the specification defined here:
// https://github.com/starkware-libs/starknet-specs/blob/a789ccc3432c57777beceaa53a34a7ae2f25fda0/api/starknet_api_openrpc.json#L517
func (h *Handler) BlockHashAndNumber() (*BlockHashAndNumber, *jsonrpc.Error) {
block, err := h.bcReader.Head()
if err != nil {
return nil, ErrNoBlock
}
return &BlockHashAndNumber{Number: block.Number, Hash: block.Hash}, nil
}

// BlockWithTxHashes returns the block information with transaction hashes given a block ID.
//
// It follows the specification defined here:
// https://github.com/starkware-libs/starknet-specs/blob/a789ccc3432c57777beceaa53a34a7ae2f25fda0/api/starknet_api_openrpc.json#L11
func (h *Handler) BlockWithTxHashes(id BlockID) (*BlockWithTxHashes, *jsonrpc.Error) {
block, rpcErr := h.blockByID(&id)
if rpcErr != nil {
return nil, rpcErr
}

txnHashes := make([]*felt.Felt, len(block.Transactions))
for index, txn := range block.Transactions {
txnHashes[index] = txn.Hash()
}

status, rpcErr := h.blockStatus(id, block)
if rpcErr != nil {
return nil, rpcErr
}

return &BlockWithTxHashes{
Status: status,
BlockHeader: adaptBlockHeader(block.Header),
TxnHashes: txnHashes,
}, nil
}

func (h *Handler) BlockWithTxHashesV0_6(id BlockID) (*BlockWithTxHashes, *jsonrpc.Error) {
resp, err := h.BlockWithTxHashes(id)
if err != nil {
return nil, err
}

resp.L1DAMode = nil
resp.L1DataGasPrice = nil
return resp, nil
}

// BlockTransactionCount returns the number of transactions in a block
// identified by the given BlockID.
//
// It follows the specification defined here:
// https://github.com/starkware-libs/starknet-specs/blob/a789ccc3432c57777beceaa53a34a7ae2f25fda0/api/starknet_api_openrpc.json#L373
func (h *Handler) BlockTransactionCount(id BlockID) (uint64, *jsonrpc.Error) {
header, rpcErr := h.blockHeaderByID(&id)
if rpcErr != nil {
return 0, rpcErr
}
return header.TransactionCount, nil
}

func (h *Handler) BlockWithReceipts(id BlockID) (*BlockWithReceipts, *jsonrpc.Error) {
block, rpcErr := h.blockByID(&id)
if rpcErr != nil {
return nil, rpcErr
}

blockStatus, rpcErr := h.blockStatus(id, block)
if rpcErr != nil {
return nil, rpcErr
}

finalityStatus := TxnAcceptedOnL2
if blockStatus == BlockAcceptedL1 {
finalityStatus = TxnAcceptedOnL1
}

txsWithReceipts := make([]TransactionWithReceipt, len(block.Transactions))
for index, txn := range block.Transactions {
r := block.Receipts[index]

txsWithReceipts[index] = TransactionWithReceipt{
Transaction: AdaptTransaction(txn),
// block_hash, block_number are optional in BlockWithReceipts response
Receipt: AdaptReceipt(r, txn, finalityStatus, nil, 0, false),
}
}

return &BlockWithReceipts{
Status: blockStatus,
BlockHeader: adaptBlockHeader(block.Header),
Transactions: txsWithReceipts,
}, nil
}

// BlockWithTxs returns the block information with full transactions given a block ID.
//
// It follows the specification defined here:
// https://github.com/starkware-libs/starknet-specs/blob/a789ccc3432c57777beceaa53a34a7ae2f25fda0/api/starknet_api_openrpc.json#L44
func (h *Handler) BlockWithTxs(id BlockID) (*BlockWithTxs, *jsonrpc.Error) {
block, rpcErr := h.blockByID(&id)
if rpcErr != nil {
return nil, rpcErr
}

txs := make([]*Transaction, len(block.Transactions))
for index, txn := range block.Transactions {
txs[index] = AdaptTransaction(txn)
}

status, rpcErr := h.blockStatus(id, block)
if rpcErr != nil {
return nil, rpcErr
}

return &BlockWithTxs{
Status: status,
BlockHeader: adaptBlockHeader(block.Header),
Transactions: txs,
}, nil
}

func (h *Handler) BlockWithTxsV0_6(id BlockID) (*BlockWithTxs, *jsonrpc.Error) {
resp, err := h.BlockWithTxs(id)
if err != nil {
return nil, err
}

resp.L1DAMode = nil
resp.L1DataGasPrice = nil
return resp, nil
}

func (h *Handler) blockStatus(id BlockID, block *core.Block) (BlockStatus, *jsonrpc.Error) {
l1H, jsonErr := h.l1Head()
if jsonErr != nil {
return 0, jsonErr
}

status := BlockAcceptedL2
if id.Pending {
status = BlockPending
} else if isL1Verified(block.Number, l1H) {
status = BlockAcceptedL1
}

return status, nil
}

func adaptBlockHeader(header *core.Header) BlockHeader {
var blockNumber *uint64
// if header.Hash == nil it's a pending block
if header.Hash != nil {
blockNumber = &header.Number
}

sequencerAddress := header.SequencerAddress
if sequencerAddress == nil {
sequencerAddress = &felt.Zero
}

var l1DAMode L1DAMode
switch header.L1DAMode {
case core.Blob:
l1DAMode = Blob
case core.Calldata:
l1DAMode = Calldata
}

var l1DataGasPrice ResourcePrice
if header.L1DataGasPrice != nil {
l1DataGasPrice = ResourcePrice{
InWei: nilToZero(header.L1DataGasPrice.PriceInWei),
InFri: nilToZero(header.L1DataGasPrice.PriceInFri),
}
} else {
l1DataGasPrice = ResourcePrice{
InWei: &felt.Zero,
InFri: &felt.Zero,
}
}

return BlockHeader{
Hash: header.Hash,
ParentHash: header.ParentHash,
Number: blockNumber,
NewRoot: header.GlobalStateRoot,
Timestamp: header.Timestamp,
SequencerAddress: sequencerAddress,
L1GasPrice: &ResourcePrice{
InWei: header.GasPrice,
InFri: nilToZero(header.GasPriceSTRK), // Old block headers will be nil.
},
L1DataGasPrice: &l1DataGasPrice,
L1DAMode: &l1DAMode,
StarknetVersion: header.ProtocolVersion,
}
}

func nilToZero(f *felt.Felt) *felt.Felt {
if f == nil {
return &felt.Zero
}
return f
}
Loading

0 comments on commit c04fa8e

Please sign in to comment.