From 0c13c1c41b399b50761e79e1fd4c251a67ac2a13 Mon Sep 17 00:00:00 2001 From: Sebastian Johnsson Date: Fri, 5 Feb 2021 21:45:44 +0100 Subject: [PATCH] RPC fixes - filter API:s + difficulty hex formatting --- node/api.go | 8 +-- rpc/eth/types.go | 140 +++++++++++++++++---------------------------- rpc/filters/api.go | 10 +++- 3 files changed, 61 insertions(+), 97 deletions(-) diff --git a/node/api.go b/node/api.go index c0e2955a9..825b5a2cf 100644 --- a/node/api.go +++ b/node/api.go @@ -111,14 +111,10 @@ func (node *Node) APIs(harmony *hmy.Harmony) []rpc.API { return []rpc.API{ hmy_rpc.NewPublicNetAPI(node.host, harmony.ChainID, hmy_rpc.V1), hmy_rpc.NewPublicNetAPI(node.host, harmony.ChainID, hmy_rpc.V2), - { - Namespace: "hmy", - Version: hmy_rpc.APIVersion, - Service: filters.NewPublicFilterAPI(harmony, false), - Public: true, - }, hmy_rpc.NewPublicNetAPI(node.host, harmony.ChainID, hmy_rpc.Eth), hmy_rpc.NewPublicWeb3API(), + filters.NewPublicFilterAPI(harmony, false, "hmy"), + filters.NewPublicFilterAPI(harmony, false, "eth"), } } diff --git a/rpc/eth/types.go b/rpc/eth/types.go index 5d50f722b..17ba6fa7b 100644 --- a/rpc/eth/types.go +++ b/rpc/eth/types.go @@ -3,7 +3,6 @@ package v1 import ( "fmt" "math/big" - "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -13,20 +12,18 @@ import ( rpc_common "github.com/harmony-one/harmony/rpc/common" ) -// BlockWithTxHash represents a block that will serialize to the RPC representation of a block -// having ONLY transaction hashes in the Transaction fields. -type BlockWithTxHash struct { - Number *hexutil.Big `json:"number"` - ViewID *hexutil.Big `json:"viewID"` - Epoch *hexutil.Big `json:"epoch"` - Hash common.Hash `json:"hash"` - ParentHash common.Hash `json:"parentHash"` - Nonce uint64 `json:"nonce"` - MixHash common.Hash `json:"mixHash"` +// Block represents a basic block which is further amended by BlockWithTxHash or BlockWithFullTx +type Block struct { + Number *hexutil.Big `json:"number"` + Hash common.Hash `json:"hash"` + ParentHash common.Hash `json:"parentHash"` + Nonce uint64 `json:"nonce"` + MixHash common.Hash `json:"mixHash"` + //UncleHash common.Hash `json:"sha3Uncles" - used in Ethereum RPC:s LogsBloom ethtypes.Bloom `json:"logsBloom"` StateRoot common.Hash `json:"stateRoot"` - Miner string `json:"miner"` - Difficulty uint64 `json:"difficulty"` + Miner common.Address `json:"miner"` + Difficulty *hexutil.Big `json:"difficulty"` ExtraData hexutil.Bytes `json:"extraData"` Size hexutil.Uint64 `json:"size"` GasLimit hexutil.Uint64 `json:"gasLimit"` @@ -35,34 +32,22 @@ type BlockWithTxHash struct { TransactionsRoot common.Hash `json:"transactionsRoot"` ReceiptsRoot common.Hash `json:"receiptsRoot"` Uncles []common.Hash `json:"uncles"` - Transactions []common.Hash `json:"transactions"` - Signers []string `json:"signers,omitempty"` +} + +// BlockWithTxHash represents a block that will serialize to the RPC representation of a block +// having ONLY transaction hashes in the Transaction fields. +type BlockWithTxHash struct { + *Block + Transactions []common.Hash `json:"transactions"` + Signers []string `json:"signers,omitempty"` } // BlockWithFullTx represents a block that will serialize to the RPC representation of a block // having FULL transactions in the Transaction fields. type BlockWithFullTx struct { - Number *hexutil.Big `json:"number"` - ViewID *hexutil.Big `json:"viewID"` - Epoch *hexutil.Big `json:"epoch"` - Hash common.Hash `json:"hash"` - ParentHash common.Hash `json:"parentHash"` - Nonce uint64 `json:"nonce"` - MixHash common.Hash `json:"mixHash"` - LogsBloom ethtypes.Bloom `json:"logsBloom"` - StateRoot common.Hash `json:"stateRoot"` - Miner string `json:"miner"` - Difficulty uint64 `json:"difficulty"` - ExtraData hexutil.Bytes `json:"extraData"` - Size hexutil.Uint64 `json:"size"` - GasLimit hexutil.Uint64 `json:"gasLimit"` - GasUsed hexutil.Uint64 `json:"gasUsed"` - Timestamp hexutil.Uint64 `json:"timestamp"` - TransactionsRoot common.Hash `json:"transactionsRoot"` - ReceiptsRoot common.Hash `json:"receiptsRoot"` - Uncles []common.Hash `json:"uncles"` - Transactions []*Transaction `json:"transactions"` - Signers []string `json:"signers,omitempty"` + *Block + Transactions []*Transaction `json:"transactions"` + Signers []string `json:"signers,omitempty"` } // Transaction represents a transaction that will serialize to the RPC representation of a transaction @@ -160,15 +145,8 @@ func NewReceipt(tx *types.EthTransaction, blockHash common.Hash, blockNumber, bl // NewBlock converts the given block to the RPC output which depends on fullTx. If inclTx is true transactions are // returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain // transaction hashes. -func NewBlock(b *types.Block, blockArgs *rpc_common.BlockArgs, leader string) (interface{}, error) { - if strings.HasPrefix(leader, "one1") { - // Handle hex address - addr, err := internal_common.Bech32ToAddress(leader) - if err != nil { - return nil, err - } - leader = addr.String() - } +func NewBlock(b *types.Block, blockArgs *rpc_common.BlockArgs, leaderAddress string) (interface{}, error) { + leader := internal_common.ParseAddr(leaderAddress) if blockArgs.FullTx { return NewBlockWithFullTx(b, blockArgs, leader) @@ -176,19 +154,11 @@ func NewBlock(b *types.Block, blockArgs *rpc_common.BlockArgs, leader string) (i return NewBlockWithTxHash(b, blockArgs, leader) } -// NewBlockWithTxHash .. -func NewBlockWithTxHash( - b *types.Block, blockArgs *rpc_common.BlockArgs, leader string, -) (*BlockWithTxHash, error) { - if blockArgs.FullTx { - return nil, fmt.Errorf("block args specifies full tx, but requested RPC block with only tx hash") - } - +func newBlock(b *types.Block, leader common.Address) *Block { head := b.Header() - blk := &BlockWithTxHash{ + + return &Block{ Number: (*hexutil.Big)(head.Number()), - ViewID: (*hexutil.Big)(head.ViewID()), - Epoch: (*hexutil.Big)(head.Epoch()), Hash: b.Hash(), ParentHash: head.ParentHash(), Nonce: 0, // Remove this because we don't have it in our header @@ -196,7 +166,7 @@ func NewBlockWithTxHash( LogsBloom: head.Bloom(), StateRoot: head.Root(), Miner: leader, - Difficulty: 0, // Remove this because we don't have it in our header + Difficulty: (*hexutil.Big)(big.NewInt(0)), // Remove this because we don't have it in our header ExtraData: hexutil.Bytes(head.Extra()), Size: hexutil.Uint64(b.Size()), GasLimit: hexutil.Uint64(head.GasLimit()), @@ -205,49 +175,41 @@ func NewBlockWithTxHash( TransactionsRoot: head.TxHash(), ReceiptsRoot: head.ReceiptHash(), Uncles: []common.Hash{}, - Transactions: []common.Hash{}, + } +} + +// NewBlockWithTxHash .. +func NewBlockWithTxHash(b *types.Block, blockArgs *rpc_common.BlockArgs, leader common.Address) (*BlockWithTxHash, error) { + if blockArgs.FullTx { + return nil, fmt.Errorf("block args specifies full tx, but requested RPC block with only tx hash") + } + + blk := newBlock(b, leader) + blkWithTxs := &BlockWithTxHash{ + Block: blk, + Transactions: []common.Hash{}, } for _, tx := range b.Transactions() { - blk.Transactions = append(blk.Transactions, tx.Hash()) + blkWithTxs.Transactions = append(blkWithTxs.Transactions, tx.Hash()) } if blockArgs.WithSigners { - blk.Signers = blockArgs.Signers + blkWithTxs.Signers = blockArgs.Signers } - return blk, nil + return blkWithTxs, nil } // NewBlockWithFullTx .. -func NewBlockWithFullTx( - b *types.Block, blockArgs *rpc_common.BlockArgs, leader string, -) (*BlockWithFullTx, error) { +func NewBlockWithFullTx(b *types.Block, blockArgs *rpc_common.BlockArgs, leader common.Address) (*BlockWithFullTx, error) { if !blockArgs.FullTx { return nil, fmt.Errorf("block args specifies NO full tx, but requested RPC block with full tx") } - head := b.Header() - blk := &BlockWithFullTx{ - Number: (*hexutil.Big)(head.Number()), - ViewID: (*hexutil.Big)(head.ViewID()), - Epoch: (*hexutil.Big)(head.Epoch()), - Hash: b.Hash(), - ParentHash: head.ParentHash(), - Nonce: 0, // Remove this because we don't have it in our header - MixHash: head.MixDigest(), - LogsBloom: head.Bloom(), - StateRoot: head.Root(), - Miner: leader, - Difficulty: 0, // Remove this because we don't have it in our header - ExtraData: hexutil.Bytes(head.Extra()), - Size: hexutil.Uint64(b.Size()), - GasLimit: hexutil.Uint64(head.GasLimit()), - GasUsed: hexutil.Uint64(head.GasUsed()), - Timestamp: hexutil.Uint64(head.Time().Uint64()), - TransactionsRoot: head.TxHash(), - ReceiptsRoot: head.ReceiptHash(), - Uncles: []common.Hash{}, - Transactions: []*Transaction{}, + blk := newBlock(b, leader) + blkWithTxs := &BlockWithFullTx{ + Block: blk, + Transactions: []*Transaction{}, } for _, tx := range b.Transactions() { @@ -255,14 +217,14 @@ func NewBlockWithFullTx( if err != nil { return nil, err } - blk.Transactions = append(blk.Transactions, fmtTx) + blkWithTxs.Transactions = append(blkWithTxs.Transactions, fmtTx) } if blockArgs.WithSigners { - blk.Signers = blockArgs.Signers + blkWithTxs.Signers = blockArgs.Signers } - return blk, nil + return blkWithTxs, nil } // NewTransactionFromBlockHash returns a transaction that will serialize to the RPC representation. diff --git a/rpc/filters/api.go b/rpc/filters/api.go index 2f1cd4d59..0a4ae2aff 100644 --- a/rpc/filters/api.go +++ b/rpc/filters/api.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/rpc" "github.com/harmony-one/harmony/block" "github.com/harmony-one/harmony/core/types" + hmy_rpc "github.com/harmony-one/harmony/rpc" ) var ( @@ -39,7 +40,7 @@ type PublicFilterAPI struct { } // NewPublicFilterAPI returns a new PublicFilterAPI instance. -func NewPublicFilterAPI(backend Backend, lightMode bool) *PublicFilterAPI { +func NewPublicFilterAPI(backend Backend, lightMode bool, namespace string) rpc.API { api := &PublicFilterAPI{ backend: backend, events: NewEventSystem(backend, lightMode), @@ -47,7 +48,12 @@ func NewPublicFilterAPI(backend Backend, lightMode bool) *PublicFilterAPI { } go api.timeoutLoop() - return api + return rpc.API{ + Namespace: namespace, + Version: hmy_rpc.APIVersion, + Service: api, + Public: true, + } } // timeoutLoop runs every 5 minutes and deletes filters that have not been recently used.