mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-24 20:47:16 +00:00
initial implementation of eth_GetBlockByNumber, for now I did copy much functions from eth source because we may need max flexibility for benchmarks of rpcdaemon
This commit is contained in:
parent
f7b6b524fe
commit
570d3b79d7
@ -1,6 +1,7 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -11,8 +12,11 @@ import (
|
|||||||
|
|
||||||
"github.com/ledgerwatch/turbo-geth/common"
|
"github.com/ledgerwatch/turbo-geth/common"
|
||||||
"github.com/ledgerwatch/turbo-geth/common/dbutils"
|
"github.com/ledgerwatch/turbo-geth/common/dbutils"
|
||||||
|
"github.com/ledgerwatch/turbo-geth/core/types"
|
||||||
"github.com/ledgerwatch/turbo-geth/ethdb/remote"
|
"github.com/ledgerwatch/turbo-geth/ethdb/remote"
|
||||||
|
"github.com/ledgerwatch/turbo-geth/internal/ethapi"
|
||||||
"github.com/ledgerwatch/turbo-geth/log"
|
"github.com/ledgerwatch/turbo-geth/log"
|
||||||
|
"github.com/ledgerwatch/turbo-geth/rlp"
|
||||||
"github.com/ledgerwatch/turbo-geth/rpc"
|
"github.com/ledgerwatch/turbo-geth/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -29,6 +33,7 @@ func splitAndTrim(input string) []string {
|
|||||||
// EthAPI is a collection of functions that are exposed in the
|
// EthAPI is a collection of functions that are exposed in the
|
||||||
type EthAPI interface {
|
type EthAPI interface {
|
||||||
BlockNumber(ctx context.Context) (uint64, error)
|
BlockNumber(ctx context.Context) (uint64, error)
|
||||||
|
GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIImpl is implementation of the EthAPI interface based on remote Db access
|
// APIImpl is implementation of the EthAPI interface based on remote Db access
|
||||||
@ -89,6 +94,138 @@ func (api *APIImpl) BlockNumber(ctx context.Context) (uint64, error) {
|
|||||||
return blockNumber, nil
|
return blockNumber, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlockByNumber see https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getblockbynumber
|
||||||
|
// see internal/ethapi.PublicBlockChainAPI.GetBlockByNumber
|
||||||
|
func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
||||||
|
if err := api.ensureConnected(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var block *types.Block
|
||||||
|
|
||||||
|
if err := api.db.View(func(tx *remote.Tx) error {
|
||||||
|
block = GetBlockByNumber(tx, uint64(number.Int64()))
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
api.db.Close()
|
||||||
|
api.db = nil
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fmt.Printf("Debug: %#v %#v %#v\n", block.Number(), block.Hash(), block.Size())
|
||||||
|
|
||||||
|
if block != nil {
|
||||||
|
response, err := api.rpcMarshalBlock(block, true, fullTx)
|
||||||
|
if err == nil && number == rpc.PendingBlockNumber {
|
||||||
|
// Pending blocks need to nil out a few fields
|
||||||
|
for _, field := range []string{"hash", "nonce", "miner"} {
|
||||||
|
response[field] = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// rpcMarshalBlock reimplementation of ethapi.rpcMarshalBlock
|
||||||
|
func (api *APIImpl) rpcMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
||||||
|
fields, err := ethapi.RPCMarshalBlock(b, inclTx, fullTx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// TODO: implement .GetTd method and uncomment next line
|
||||||
|
//fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(b.Hash()))
|
||||||
|
return fields, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadCanonicalHash reimplementation of rawdb.ReadCanonicalHash
|
||||||
|
func ReadCanonicalHash(tx *remote.Tx, number uint64) common.Hash {
|
||||||
|
bucket := tx.Bucket(dbutils.HeaderPrefix)
|
||||||
|
if bucket == nil {
|
||||||
|
return common.Hash{}
|
||||||
|
//return fmt.Errorf("bucket %s not found", dbutils.HeaderPrefix)
|
||||||
|
}
|
||||||
|
|
||||||
|
data := bucket.Get(dbutils.HeaderHashKey(number))
|
||||||
|
if len(data) == 0 {
|
||||||
|
return common.Hash{}
|
||||||
|
}
|
||||||
|
return common.BytesToHash(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBlockByNumber reimplementation of chain.GetBlockByNumber
|
||||||
|
func GetBlockByNumber(tx *remote.Tx, number uint64) *types.Block {
|
||||||
|
hash := ReadCanonicalHash(tx, number)
|
||||||
|
if hash == (common.Hash{}) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return ReadBlock(tx, hash, number)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadBlock reimplementation of rawdb.ReadBlock
|
||||||
|
func ReadBlock(tx *remote.Tx, hash common.Hash, number uint64) *types.Block {
|
||||||
|
header := ReadHeader(tx, hash, number)
|
||||||
|
if header == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
body := ReadBody(tx, hash, number)
|
||||||
|
if body == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return types.NewBlockWithHeader(header).WithBody(body.Transactions, body.Uncles)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadBlock reimplementation of rawdb.ReadBlock
|
||||||
|
func ReadHeaderRLP(tx *remote.Tx, hash common.Hash, number uint64) rlp.RawValue {
|
||||||
|
bucket := tx.Bucket(dbutils.HeaderPrefix)
|
||||||
|
if bucket == nil {
|
||||||
|
//return fmt.Errorf("bucket %s not found", dbutils.HeaderPrefix)
|
||||||
|
log.Error("Bucket not founc", "error", dbutils.HeaderPrefix)
|
||||||
|
return rlp.RawValue{}
|
||||||
|
}
|
||||||
|
return bucket.Get(dbutils.HeaderKey(number, hash))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadHeader reimplementation of rawdb.ReadHeader
|
||||||
|
func ReadHeader(tx *remote.Tx, hash common.Hash, number uint64) *types.Header {
|
||||||
|
data := ReadHeaderRLP(tx, hash, number)
|
||||||
|
if len(data) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
header := new(types.Header)
|
||||||
|
if err := rlp.Decode(bytes.NewReader(data), header); err != nil {
|
||||||
|
log.Error("Invalid block header RLP", "hash", hash, "err", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return header
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadBodyRLP retrieves the block body (transactions and uncles) in RLP encoding.
|
||||||
|
func ReadBodyRLP(tx *remote.Tx, hash common.Hash, number uint64) rlp.RawValue {
|
||||||
|
bucket := tx.Bucket(dbutils.BlockBodyPrefix)
|
||||||
|
if bucket == nil {
|
||||||
|
//return fmt.Errorf("bucket %s not found", dbutils.HeaderPrefix)
|
||||||
|
log.Error("Bucket not founc", "error", dbutils.BlockBodyPrefix)
|
||||||
|
return rlp.RawValue{}
|
||||||
|
}
|
||||||
|
return bucket.Get(dbutils.BlockBodyKey(number, hash))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadBody reimplementation of rawdb.ReadBody
|
||||||
|
func ReadBody(tx *remote.Tx, hash common.Hash, number uint64) *types.Body {
|
||||||
|
data := ReadBodyRLP(tx, hash, number)
|
||||||
|
if len(data) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
body := new(types.Body)
|
||||||
|
if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
|
||||||
|
log.Error("Invalid block body RLP", "hash", hash, "err", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Post-processing
|
||||||
|
body.SendersToTxs()
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
func daemon(cfg Config) {
|
func daemon(cfg Config) {
|
||||||
vhosts := splitAndTrim(cfg.rpcVirtualHost)
|
vhosts := splitAndTrim(cfg.rpcVirtualHost)
|
||||||
cors := splitAndTrim(cfg.rpcCORSDomain)
|
cors := splitAndTrim(cfg.rpcCORSDomain)
|
||||||
|
18
cmd/rpcdaemon/test.http
Normal file
18
cmd/rpcdaemon/test.http
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
###
|
||||||
|
|
||||||
|
# curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"eth_getBlockByNumber", "params": ["0x1b4", true], "id":1}' localhost:8545
|
||||||
|
POST localhost:8545
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"method": "eth_getBlockByNumber",
|
||||||
|
"params": [
|
||||||
|
"0x1b4",
|
||||||
|
true
|
||||||
|
],
|
||||||
|
"id": 1
|
||||||
|
}
|
||||||
|
|
||||||
|
###
|
||||||
|
|
Loading…
Reference in New Issue
Block a user