diff --git a/README.md b/README.md index 2accd81..c5b6df4 100644 --- a/README.md +++ b/README.md @@ -50,10 +50,36 @@ The genesis configs of Itachi chain is same as Madara. You can learn more detail ## Starknet RPC -#### Compatible Versions: -- 0.5.1 -- 0.6.0 -#### Compatible RPC methods +### 0.5.1 +- [x] addDeclareTransaction +- [x] addDeployAccountTransaction +- [x] addInvokeTransaction +- [x] call +- [x] estimateFee +- [x] getTransactionReceipt +- [x] getTransactionByHash +- [x] getNonce +- [x] getTransactionStatus +- [x] getClass +- [x] getClassAt +- [x] getClassHashAt +- [ ] blockHashAndNumber +- [ ] getBlockWithTxs +- [x] chainId +- [ ] syncing +- [ ] getTransactionByBlockIdAndIndex +- [ ] getBlockTransactionCount +- [ ] estimateMessageFee +- [ ] blockNumber +- [x] specVersion +- [ ] traceTransaction +- [x] simulateTransactions +- [ ] traceBlockTransactions +- [x] getStorageAt +- [ ] getStateUpdate + + +### 0.6.0 - [x] addDeclareTransaction - [x] addDeployAccountTransaction - [x] addInvokeTransaction @@ -67,6 +93,7 @@ The genesis configs of Itachi chain is same as Madara. You can learn more detail - [x] getClassAt - [x] getClassHashAt - [ ] blockHashAndNumber +- [x] getBlockWithTxs - [x] chainId - [ ] syncing - [ ] getTransactionByBlockIdAndIndex diff --git a/cairo/api.go b/cairo/api.go index 729e57d..5012e62 100644 --- a/cairo/api.go +++ b/cairo/api.go @@ -9,7 +9,9 @@ import ( "github.com/NethermindEth/juno/rpc" "github.com/NethermindEth/juno/utils" "github.com/NethermindEth/juno/vm" + "github.com/yu-org/yu/common" "github.com/yu-org/yu/core/context" + "github.com/yu-org/yu/core/types" "net/http" "slices" ) @@ -99,6 +101,71 @@ func (c *Cairo) getReceipt(hash felt.Felt) (*rpc.TransactionReceipt, error) { return starkReceipt, err } +type BlockWithTxsRequest struct { + BlockID BlockID `json:"block_id"` +} + +type BlockWithTxsResponse struct { + BlockWithTxs *rpc.BlockWithTxs `json:"block_with_txs"` + Err *jsonrpc.Error `json:"err"` +} + +func (c *Cairo) GetBlockWithTxs(ctx *context.ReadContext) { + var br BlockWithTxsRequest + err := ctx.BindJson(&br) + if err != nil { + ctx.Json(http.StatusBadRequest, &BlockWithTxsResponse{Err: jsonrpc.Err(jsonrpc.InvalidJSON, err.Error())}) + return + } + + var compactBlock *types.CompactBlock + switch { + case br.BlockID.Latest || br.BlockID.Pending: + compactBlock, err = c.Chain.GetEndBlock() + default: + compactBlock, err = c.Chain.GetBlockByHeight(common.BlockNum(br.BlockID.Number)) + } + if err != nil { + ctx.Json(http.StatusInternalServerError, &BlockWithTxsResponse{Err: jsonrpc.Err(jsonrpc.InternalError, err.Error())}) + return + } + + starkTxs := make([]*rpc.Transaction, 0) + for _, txHash := range compactBlock.TxnsHashes { + var yuTxn *types.SignedTxn + yuTxn, err = c.TxDB.GetTxn(txHash) + if err != nil { + ctx.Json(http.StatusInternalServerError, &BlockWithTxsResponse{Err: jsonrpc.Err(jsonrpc.InternalError, err.Error())}) + return + } + txReq := new(TxRequest) + err = yuTxn.BindJson(txReq) + if err != nil { + ctx.Json(http.StatusInternalServerError, &BlockWithTxsResponse{Err: jsonrpc.Err(jsonrpc.InternalError, err.Error())}) + return + } + starkTxs = append(starkTxs, &txReq.Tx.Transaction) + } + + num := uint64(compactBlock.Height) + blockWithTxs := &rpc.BlockWithTxs{ + Status: rpc.BlockAcceptedL2, + BlockHeader: rpc.BlockHeader{ + Hash: new(felt.Felt).SetBytes(compactBlock.Hash.Bytes()), + ParentHash: new(felt.Felt).SetBytes(compactBlock.PrevHash.Bytes()), + Number: &num, + // FIXME + NewRoot: new(felt.Felt).SetBytes(compactBlock.StateRoot.Bytes()), + Timestamp: compactBlock.Timestamp, + SequencerAddress: c.sequencerAddr, + // TODOļ¼šL1GasPrice, StarknetVersion + }, + Transactions: starkTxs, + } + + ctx.JsonOk(&BlockWithTxsResponse{BlockWithTxs: blockWithTxs}) +} + type TransactionStatusRequest struct { Hash felt.Felt `json:"hash"` } diff --git a/cairo/cairo.go b/cairo/cairo.go index bb0e590..818e0ea 100644 --- a/cairo/cairo.go +++ b/cairo/cairo.go @@ -58,6 +58,7 @@ func NewCairo(cfg *config.Config) *Cairo { cairo.GetClassHashAt, cairo.GetNonce, cairo.GetStorage, cairo.GetTransaction, cairo.GetTransactionStatus, cairo.GetReceipt, cairo.SimulateTransactions, + cairo.GetBlockWithTxs, ) cairo.SetInit(cairo) cairo.SetTxnChecker(cairo) diff --git a/go.mod b/go.mod index fc5f19d..e5b294a 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/sirupsen/logrus v1.9.0 github.com/sourcegraph/conc v0.2.0 github.com/stretchr/testify v1.8.4 - github.com/yu-org/yu v0.0.0-20240415152650-db2903655297 + github.com/yu-org/yu v0.0.0-20240416111537-b95d87718178 ) require ( diff --git a/go.sum b/go.sum index 7a28dcb..fd9ac43 100644 --- a/go.sum +++ b/go.sum @@ -717,6 +717,8 @@ github.com/yu-org/yu v0.0.0-20240320055213-cb9a4b6cf999 h1:S+phH6kSI3Opbhr2AvJMu github.com/yu-org/yu v0.0.0-20240320055213-cb9a4b6cf999/go.mod h1:W2qfPLdMEmzOymqCFxb3vN+fjZT94CoWPCVPtpgxwdo= github.com/yu-org/yu v0.0.0-20240415152650-db2903655297 h1:ynCpNLkORUPnIMkfxlAzofOMy0a05G+7FiYlSk1juJQ= github.com/yu-org/yu v0.0.0-20240415152650-db2903655297/go.mod h1:W2qfPLdMEmzOymqCFxb3vN+fjZT94CoWPCVPtpgxwdo= +github.com/yu-org/yu v0.0.0-20240416111537-b95d87718178 h1:/4JuKSLlegvz48ZUGi2dCrG32zDUT/qFQvutcFiUS34= +github.com/yu-org/yu v0.0.0-20240416111537-b95d87718178/go.mod h1:W2qfPLdMEmzOymqCFxb3vN+fjZT94CoWPCVPtpgxwdo= 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= diff --git a/starknetrpc/methods.go b/starknetrpc/methods.go index d4b18c4..f68dd29 100644 --- a/starknetrpc/methods.go +++ b/starknetrpc/methods.go @@ -21,6 +21,16 @@ func (s *StarknetRPC) GetChainID() (*felt.Felt, *jsonrpc.Error) { return s.network.ChainID(), nil } +func (s *StarknetRPC) GetBlockWithTxs(id rpc.BlockID) (*rpc.BlockWithTxs, *jsonrpc.Error) { + req := &cairo.BlockWithTxsRequest{BlockID: cairo.NewFromJunoBlockID(id)} + resp, jsonErr := s.adaptChainRead(req, "GetBlockWithTxs") + if jsonErr != nil { + return nil, jsonErr + } + res := resp.DataInterface.(*cairo.BlockWithTxsResponse) + return res.BlockWithTxs, res.Err +} + func (s *StarknetRPC) AddTransaction(tx rpc.BroadcastedTransaction) (*rpc.AddTxResponse, *jsonrpc.Error) { return s.addTransaction(tx, false) } diff --git a/starknetrpc/rpc.go b/starknetrpc/rpc.go index 1979da5..1597c9f 100644 --- a/starknetrpc/rpc.go +++ b/starknetrpc/rpc.go @@ -111,6 +111,11 @@ func (s *StarknetRPC) Methods() ([]jsonrpc.Method, string) { Name: "starknet_specVersion", Handler: s.SpecVersion, }, + { + Name: "starknet_getBlockWithTxs", + Params: []jsonrpc.Parameter{{Name: "block_id"}}, + Handler: s.GetBlockWithTxs, + }, { Name: "starknet_addDeployAccountTransaction", Params: []jsonrpc.Parameter{{Name: "deploy_account_transaction"}},