Skip to content

Commit

Permalink
Merge pull request #3 from dipdup-io/new-node-endpoints
Browse files Browse the repository at this point in the history
Add new endpoints and some optimizations
  • Loading branch information
aopoltorzhicky authored Jan 17, 2024
2 parents db7439f + eadabf1 commit ae578a7
Show file tree
Hide file tree
Showing 13 changed files with 100 additions and 38 deletions.
2 changes: 1 addition & 1 deletion example/sequencer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func main() {
number := uint64(1)
block, err := api.GetBlock(ctx, data.BlockID{
Number: &number,
})
}, true)
if err != nil {
log.Panic(err)
}
Expand Down
10 changes: 6 additions & 4 deletions pkg/rpc/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import (

// API - wrapper of starknet node API.
type API struct {
client *http.Client
baseURL string
id *atomic.Uint64
rateLimit *rate.Limiter
client *http.Client
baseURL string
id *atomic.Uint64
rateLimit *rate.Limiter
headerApiKey string
apiKey string
}

// NewAPI - constructor of API
Expand Down
22 changes: 14 additions & 8 deletions pkg/rpc/get_block_with_tx_hashes.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@ import (

// BlockWithTxHashes -
type BlockWithTxHashes struct {
Status string `json:"status"`
BlockHash string `json:"block_hash"`
ParentHash string `json:"parent_hash"`
BlockNumber uint64 `json:"block_number"`
NewRoot string `json:"new_root"`
Timestamp int64 `json:"timestamp"`
SequencerAddress string `json:"sequencer_address"`
Transactions []string `json:"transactions"`
Status string `json:"status"`
BlockHash string `json:"block_hash"`
ParentHash string `json:"parent_hash"`
BlockNumber uint64 `json:"block_number"`
NewRoot string `json:"new_root"`
Timestamp int64 `json:"timestamp"`
SequencerAddress string `json:"sequencer_address"`
L1GasPrice L1GasPrice `json:"l1_gas_price"`
Transactions []string `json:"transactions"`
}

type L1GasPrice struct {
PricInFri data.Felt `json:"price_in_fri"`
PricInWei data.Felt `json:"price_in_wei"`
}

// GetBlockWithTxHashes -
Expand Down
2 changes: 2 additions & 0 deletions pkg/rpc/get_block_with_txs.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ type BlockWithTxs struct {
NewRoot string `json:"new_root"`
Timestamp int64 `json:"timestamp"`
SequencerAddress string `json:"sequencer_address"`
Version *string `json:"starknet_version,omitempty"`
L1GasPrice L1GasPrice `json:"l1_gas_price"`
Transactions []data.Transaction `json:"transactions"`
}

Expand Down
10 changes: 8 additions & 2 deletions pkg/rpc/get_transaction_receipts.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,21 @@ import (
type Receipt struct {
Type string `json:"type"`
TransactionHash string `json:"transaction_hash"`
ActualFee string `json:"actual_fee"`
Status string `json:"status"`
ActualFee Fee `json:"actual_fee"`
ExecutionStatus string `json:"execution_status"`
FinalityStatus string `json:"finality_status"`
BlockHash string `json:"block_hash"`
BlockNumber uint64 `json:"block_number"`
MessagesSent []data.Message `json:"messages_sent"`
Events []data.Event `json:"events"`
ContractAddress string `json:"contract_address"`
}

type Fee struct {
Amount data.Felt `json:"amount"`
Unit string `json:"unit"`
}

// GetTransactionReceipts -
func (api API) GetTransactionReceipts(ctx context.Context, hash string, opts ...RequestOption) (*Response[Receipt], error) {
request := api.prepareRequest(ctx, "starknet_getTransactionReceipt", []any{
Expand Down
19 changes: 19 additions & 0 deletions pkg/rpc/get_transaction_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package api

import "context"

type TransactionStatus struct {
Finality string `json:"finality_status"`
Execution string `json:"execution_status"`
}

// GetTransactionStatus -
func (api API) GetTransactionStatus(ctx context.Context, hash string, opts ...RequestOption) (*Response[TransactionStatus], error) {
request := api.prepareRequest(ctx, "starknet_getTransactionReceipt", []any{
hash,
}, opts...)

var response Response[TransactionStatus]
err := post(ctx, api, *request, &response)
return &response, err
}
8 changes: 8 additions & 0 deletions pkg/rpc/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,11 @@ func WithRateLimit(requestPerSecond int) ApiOption {
}
}
}

// WithApiKey -
func WithApiKey(header, apiKey string) ApiOption {
return func(api *API) {
api.headerApiKey = header
api.apiKey = apiKey
}
}
23 changes: 16 additions & 7 deletions pkg/rpc/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/goccy/go-json"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)

func post[T any](ctx context.Context, api API, req Request, output *Response[T]) error {
Expand All @@ -22,6 +23,10 @@ func post[T any](ctx context.Context, api API, req Request, output *Response[T])
}
request.Header.Add("Content-Type", "application/json")

if api.apiKey != "" && api.headerApiKey != "" {
request.Header.Add(api.headerApiKey, api.apiKey)
}

if api.rateLimit != nil {
if err := api.rateLimit.Wait(ctx); err != nil {
return err
Expand All @@ -32,18 +37,13 @@ func post[T any](ctx context.Context, api API, req Request, output *Response[T])
if err != nil {
return err
}
defer response.Body.Close()

buffer := new(bytes.Buffer)
if _, err := io.Copy(buffer, response.Body); err != nil {
return err
}
defer closeWithLogError(response.Body)

if response.StatusCode != http.StatusOK {
return errors.Wrapf(ErrRequest, "request %d invalid status code: %d", output.ID, response.StatusCode)
}

if err := json.NewDecoder(buffer).Decode(output); err != nil {
if err := json.NewDecoder(response.Body).Decode(output); err != nil {
return err
}

Expand All @@ -53,3 +53,12 @@ func post[T any](ctx context.Context, api API, req Request, output *Response[T])

return nil
}

func closeWithLogError(stream io.ReadCloser) {
if _, err := io.Copy(io.Discard, stream); err != nil {
log.Err(err).Msg("api copy body response to discard")
}
if err := stream.Close(); err != nil {
log.Err(err).Msg("api close body request")
}
}
11 changes: 6 additions & 5 deletions pkg/rpc/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

type Trace struct {
TraceRoot TraceRoot `json:"trace_root"`
TransactionHash string `json:"transaction_hash"`
TransactionHash data.Felt `json:"transaction_hash"`
}

type TraceRoot struct {
Expand All @@ -20,12 +20,13 @@ type TraceRoot struct {
}

type Call struct {
CallerAddress string `json:"caller_address"`
ContractAddress string `json:"contract_address"`
CallerAddress data.Felt `json:"caller_address"`
ContractAddress data.Felt `json:"contract_address"`
CallType string `json:"call_type"`
ClassHash string `json:"class_hash"`
EntryPointSelector string `json:"entry_point_selector"`
ClassHash data.Felt `json:"class_hash"`
EntryPointSelector data.Felt `json:"entry_point_selector"`
EntryPointType string `json:"entry_point_type"`
RevertReason string `json:"revert_reason,omitempty"`
Calldata []data.Felt `json:"calldata"`
Result []data.Felt `json:"result"`
Calls []Call `json:"calls"`
Expand Down
22 changes: 13 additions & 9 deletions pkg/sequencer/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (api API) get(ctx context.Context, baseURL, path, cacheFileName string, arg
if err != nil {
return err
}
defer response.Body.Close()
defer closeWithLogError(response.Body)

log.Trace().Msgf("[%d ms] %s", time.Since(start).Milliseconds(), u.String())

Expand Down Expand Up @@ -158,21 +158,25 @@ func (api API) post(ctx context.Context, baseURL, path string, args map[string]s
if err != nil {
return err
}
defer response.Body.Close()

buffer := new(bytes.Buffer)
if _, err := io.Copy(buffer, response.Body); err != nil {
return err
}
defer closeWithLogError(response.Body)

if response.StatusCode != http.StatusOK {
var e Error
if err := json.NewDecoder(buffer).Decode(&e); err != nil {
if err := json.NewDecoder(response.Body).Decode(&e); err != nil {
return errors.Wrap(ErrRequest, err.Error())
}
return errors.Wrap(ErrRequest, e.Error())
}

err = json.NewDecoder(buffer).Decode(output)
err = json.NewDecoder(response.Body).Decode(output)
return err
}

func closeWithLogError(stream io.ReadCloser) {
if _, err := io.Copy(io.Discard, stream); err != nil {
log.Err(err).Msg("api copy body response to discard")
}
if err := stream.Close(); err != nil {
log.Err(err).Msg("api close body request")
}
}
5 changes: 4 additions & 1 deletion pkg/sequencer/get_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type Receipt struct {
}

// GetBlock - Gets block
func (api API) GetBlock(ctx context.Context, block data.BlockID) (response Block, err error) {
func (api API) GetBlock(ctx context.Context, block data.BlockID, headerOnly bool) (response Block, err error) {
if err := block.Validate(); err != nil {
return response, err
}
Expand All @@ -46,6 +46,9 @@ func (api API) GetBlock(ctx context.Context, block data.BlockID) (response Block
if name, value := block.GetArg(); name != "" {
args[name] = value
}
if headerOnly {
args["headerOnly"] = "true"
}

var cacheFileName string
switch {
Expand Down
2 changes: 2 additions & 0 deletions pkg/sequencer/get_transaction_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
// TransactionStatus -
type TransactionStatus struct {
Status string `json:"tx_status"`
Finality string `json:"finality_status"`
Execution string `json:"execution_status"`
BlockHash string `json:"block_hash"`
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/sequencer/trace_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Invocation struct {
ClassHash data.Felt `json:"class_hash"`
Selector data.Felt `json:"selector"`
EntrypointType string `json:"entry_point_type"`
Result []string `json:"result"`
Result []data.Felt `json:"result"`
ExecutionResources ExecutionResources `json:"execution_resources"`
InternalCalls []Invocation `json:"internal_calls"`
Events []data.Event `json:"events"`
Expand Down

0 comments on commit ae578a7

Please sign in to comment.