Skip to content

Commit

Permalink
quai_api.go: addex ext block unmarshal and fixed ext block DB key
Browse files Browse the repository at this point in the history
  • Loading branch information
0xalank committed Jul 1, 2022
1 parent 5e7306b commit bf941b4
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 17 deletions.
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2867,7 +2867,7 @@ func (bc *BlockChain) GetExternalBlockTraceSet(hash common.Hash, context int) (*
return extBlockDecoded, nil
}
extBlock := rawdb.ReadExternalBlock(bc.db, hash, uint64(context))

fmt.Println("GetExternalBlockTraceSet: is block nil?", extBlock == nil)
return extBlock, nil
}

Expand Down
4 changes: 2 additions & 2 deletions core/rawdb/accessors_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ func ReadExternalBody(db ethdb.Reader, hash common.Hash, context uint64) *types.
}
body := new(types.ExternalBody)
if err := rlp.Decode(bytes.NewReader(data), body); err != nil {
log.Error("Invalid block body RLP", "hash", hash, "err", err)
log.Error("Invalid external block body RLP", "hash", hash, "err", err)
return nil
}
return body
Expand Down Expand Up @@ -862,7 +862,7 @@ func ReadExternalBlock(db ethdb.Reader, hash common.Hash, context uint64) *types
if body == nil {
return nil
}
return types.NewExternalBlockWithHeader(header).ExternalBlockWithBody(body.Transactions, body.Uncles, body.Receipts, body.Context)
return types.NewExternalBlockWithHeader(header).WithBody(body.Transactions, body.Uncles, body.Receipts, body.Context)
}

// WriteBlock serializes a block into the database, header and body separately.
Expand Down
5 changes: 3 additions & 2 deletions core/rawdb/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ var (

blockBodyPrefix = []byte("b") // blockBodyPrefix + num (uint64 big endian) + hash -> block body
blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
extBlockBodyPrefix = []byte("e") // extBlockBodyPrefix + num (uint64 big endian) + hash -> block body

txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata
bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
Expand Down Expand Up @@ -177,9 +178,9 @@ func blockBodyKey(number uint64, hash common.Hash) []byte {
return append(append(blockBodyPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
}

// extBlockBodyKey = blockBodyPrefix + num (uint64 big endian) + location + context + hash
// extBlockBodyKey = extBlockBodyPrefix + num (uint64 big endian) + location + context + hash
func extBlockBodyKey(context uint64, hash common.Hash) []byte {
return append(append(blockBodyPrefix, encodeBlockNumber(context)...), hash.Bytes()...)
return append(append(extBlockBodyPrefix, encodeBlockNumber(context)...), hash.Bytes()...)
}

// blockReceiptsKey = blockReceiptsPrefix + num (uint64 big endian) + hash
Expand Down
6 changes: 4 additions & 2 deletions core/types/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ func NewExternalBlockWithHeader(header *Header) *ExternalBlock {
}

// WithBody returns a new block with the given transaction and uncle contents.
func (b *ExternalBlock) ExternalBlockWithBody(transactions []*Transaction, uncles []*Header, receipts []*Receipt, context *big.Int) *ExternalBlock {
func (b *ExternalBlock) WithBody(transactions []*Transaction, uncles []*Header, receipts []*Receipt, context *big.Int) *ExternalBlock {
block := &ExternalBlock{
header: CopyHeader(b.header),
transactions: make([]*Transaction, len(transactions)),
Expand All @@ -319,7 +319,9 @@ func (b *ExternalBlock) ExternalBlockWithBody(transactions []*Transaction, uncle
context: context,
}
copy(block.transactions, transactions)
copy(block.uncles, uncles)
for i := range uncles {
block.uncles[i] = CopyHeader(uncles[i])
}
copy(block.receipts, receipts)
return block
}
Expand Down
65 changes: 58 additions & 7 deletions ethclient/ethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ type rpcReceiptBlock struct {
Receipts []*types.Receipt `json:"receipts"`
}

type rpcExternalBlock struct {
Hash common.Hash `json:"hash"`
Transactions []rpcTransaction `json:"transactions"`
Uncles []*types.Header `json:"uncles"`
Receipts []*types.Receipt `json:"receipts"`
Context *big.Int `json:"context:`
}

func (ec *Client) getBlockWithReceipts(ctx context.Context, method string, args ...interface{}) (*types.ReceiptBlock, error) {
var raw json.RawMessage
err := ec.c.CallContext(ctx, &raw, method, args...)
Expand Down Expand Up @@ -253,6 +261,55 @@ func (ec *Client) getBlock(ctx context.Context, method string, args ...interface
return types.NewBlockWithHeader(head).WithBody(txs, uncles), nil
}

func (ec *Client) getExternalBlock(ctx context.Context, method string, args ...interface{}) (*types.ExternalBlock, error) {
var raw json.RawMessage
err := ec.c.CallContext(ctx, &raw, method, args...)
if err != nil {
return nil, err
} else if len(raw) == 0 {
return nil, ethereum.NotFound
}
// Decode header and transactions.
var head *types.Header
var body rpcExternalBlock
if err := json.Unmarshal(raw, &head); err != nil {
return nil, err
}
if err := json.Unmarshal(raw, &body); err != nil {
return nil, err
}
// Quick-verify transaction and uncle lists. This mostly helps with debugging the server.
if types.IsEqualHashSlice(head.UncleHash, types.EmptyUncleHash) && len(body.Uncles) > 0 {
return nil, fmt.Errorf("server returned non-empty uncle list but block header indicates no uncles")
}
if !types.IsEqualHashSlice(head.UncleHash, types.EmptyUncleHash) && len(body.Uncles) == 0 {
return nil, fmt.Errorf("server returned empty uncle list but block header indicates uncles")
}
if types.IsEqualHashSlice(head.TxHash, types.EmptyRootHash) && len(body.Transactions) > 0 {
return nil, fmt.Errorf("server returned non-empty transaction list but block header indicates no transactions")
}
if !types.IsEqualHashSlice(head.TxHash, types.EmptyRootHash) && len(body.Transactions) == 0 {
return nil, fmt.Errorf("server returned empty transaction list but block header indicates transactions")
}
// Load uncles because they are not included in the block response.
var uncles []*types.Header
copy(uncles, body.Uncles)

// Fill the sender cache of transactions in the block.
txs := make([]*types.Transaction, len(body.Transactions))
for i, tx := range body.Transactions {
if tx.From != nil {
setSenderFromServer(tx.tx, *tx.From, body.Hash)
}
txs[i] = tx.tx
}
receipts := make([]*types.Receipt, len(body.Receipts))
for i, receipt := range body.Receipts {
receipts[i] = receipt
}
return types.NewExternalBlockWithHeader(head).WithBody(txs, uncles, receipts, body.Context), nil
}

// HeaderByHash returns the block header with the given hash.
func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
var head *types.Header
Expand Down Expand Up @@ -660,13 +717,7 @@ func (ec *Client) GetExternalBlockTraceSet(ctx context.Context, hash common.Hash
if err != nil {
return nil, err
}

var externalBlock *types.ExternalBlock
err = ec.c.CallContext(ctx, &externalBlock, "quai_getExternalBlockTraceSet", data)
if err != nil {
return nil, err
}
return externalBlock, nil
return ec.getExternalBlock(ctx, "quai_getExternalBlockTraceSet", data)
}

// header: header in which the intended chain is to roll back to.
Expand Down
7 changes: 4 additions & 3 deletions internal/ethapi/quai_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ func (s *PublicBlockChainQuaiAPI) SendExternalBlock(ctx context.Context, raw jso
receipts := make([]*types.Receipt, len(body.Receipts))
copy(receipts, body.Receipts)

block := types.NewExternalBlockWithHeader(head).ExternalBlockWithBody(txs, uncles, receipts, body.Context)
block := types.NewExternalBlockWithHeader(head).WithBody(txs, uncles, receipts, body.Context)

s.b.AddExternalBlock(block)

Expand All @@ -699,7 +699,7 @@ type HeaderHashWithContext struct {
}

// GetExternalBlockTraceSet will run checks on the header and get the External Block from the cache.
func (s *PublicBlockChainQuaiAPI) GetExternalBlockTraceSet(ctx context.Context, raw json.RawMessage) (*types.ExternalBlock, error) {
func (s *PublicBlockChainQuaiAPI) GetExternalBlockTraceSet(ctx context.Context, raw json.RawMessage) (map[string]interface{}, error) {
// Decode header and transactions.
var headerHashWithContext HeaderHashWithContext
if err := json.Unmarshal(raw, &headerHashWithContext); err != nil {
Expand All @@ -710,6 +710,7 @@ func (s *PublicBlockChainQuaiAPI) GetExternalBlockTraceSet(ctx context.Context,
if err != nil {
return nil, err
}
block := types.NewBlockWithHeader(extBlock.Header()).WithBody(extBlock.Transactions(), extBlock.Uncles())

return extBlock, nil
return RPCMarshalExternalBlock(block, extBlock.Receipts(), extBlock.Context())
}

0 comments on commit bf941b4

Please sign in to comment.