mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-30 16:43:46 +00:00
fix: add block receipt
This commit is contained in:
parent
93e2ac2733
commit
45230abb63
19 changed files with 427 additions and 43 deletions
|
|
@ -196,6 +196,8 @@ type BlockChain struct {
|
|||
badBlocks *lru.Cache // Bad block cache
|
||||
shouldPreserve func(*types.Block) bool // Function used to determine whether should preserve the given block.
|
||||
terminateInsert func(common.Hash, uint64) bool // Testing hook used to terminate ancient receipt chain insertion.
|
||||
|
||||
borReceiptsCache *lru.Cache // Cache for the most recent bor receipt receipts per block
|
||||
}
|
||||
|
||||
// NewBlockChain returns a fully initialised block chain using information
|
||||
|
|
@ -219,6 +221,8 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
|||
futureBlocks, _ := lru.New(maxFutureBlocks)
|
||||
badBlocks, _ := lru.New(badBlockLimit)
|
||||
|
||||
borReceiptsCache, _ := lru.New(receiptsCacheLimit)
|
||||
|
||||
bc := &BlockChain{
|
||||
chainConfig: chainConfig,
|
||||
cacheConfig: cacheConfig,
|
||||
|
|
@ -236,6 +240,8 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
|
|||
engine: engine,
|
||||
vmConfig: vmConfig,
|
||||
badBlocks: badBlocks,
|
||||
|
||||
borReceiptsCache: borReceiptsCache,
|
||||
}
|
||||
bc.validator = NewBlockValidator(chainConfig, bc, engine)
|
||||
bc.prefetcher = newStatePrefetcher(chainConfig, bc, engine)
|
||||
|
|
@ -1155,7 +1161,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
|||
}
|
||||
h := rawdb.ReadCanonicalHash(bc.db, frozen)
|
||||
b := rawdb.ReadBlock(bc.db, h, frozen)
|
||||
size += rawdb.WriteAncientBlock(bc.db, b, rawdb.ReadReceipts(bc.db, h, frozen, bc.chainConfig), rawdb.ReadTd(bc.db, h, frozen))
|
||||
size += rawdb.WriteAncientBlock(bc.db, b, rawdb.ReadReceipts(bc.db, h, frozen, bc.chainConfig), rawdb.ReadTd(bc.db, h, frozen), rawdb.ReadBorReceipt(bc.db, h, frozen))
|
||||
count += 1
|
||||
|
||||
// Always keep genesis block in active database.
|
||||
|
|
@ -1198,7 +1204,7 @@ func (bc *BlockChain) InsertReceiptChain(blockChain types.Blocks, receiptChain [
|
|||
log.Info("Migrated ancient blocks", "count", count, "elapsed", common.PrettyDuration(time.Since(start)))
|
||||
}
|
||||
// Flush data into ancient database.
|
||||
size += rawdb.WriteAncientBlock(bc.db, block, receiptChain[i], bc.GetTd(block.Hash(), block.NumberU64()))
|
||||
size += rawdb.WriteAncientBlock(bc.db, block, receiptChain[i], bc.GetTd(block.Hash(), block.NumberU64()), bc.GetBorReceiptByHash(block.Hash()))
|
||||
|
||||
// Write tx indices if any condition is satisfied:
|
||||
// * If user requires to reserve all tx indices(txlookuplimit=0)
|
||||
|
|
@ -1438,6 +1444,15 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
|||
rawdb.WriteTd(blockBatch, block.Hash(), block.NumberU64(), externTd)
|
||||
rawdb.WriteBlock(blockBatch, block)
|
||||
rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts)
|
||||
|
||||
// storing bor block receipt
|
||||
blockLogs := state.Logs()
|
||||
if len(blockLogs) > len(logs) {
|
||||
rawdb.WriteBorReceipt(blockBatch, block.Hash(), block.NumberU64(), &types.BorReceiptForStorage{
|
||||
Logs: blockLogs[len(logs):],
|
||||
})
|
||||
}
|
||||
|
||||
rawdb.WritePreimages(blockBatch, state.Preimages())
|
||||
if err := blockBatch.Write(); err != nil {
|
||||
log.Crit("Failed to write block into disk", "err", err)
|
||||
|
|
|
|||
30
core/bor_blockchain.go
Normal file
30
core/bor_blockchain.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/core/rawdb"
|
||||
"github.com/maticnetwork/bor/core/types"
|
||||
)
|
||||
|
||||
// GetBorReceiptByHash retrieves the bor block receipt in a given block.
|
||||
func (bc *BlockChain) GetBorReceiptByHash(hash common.Hash) *types.BorReceipt {
|
||||
if receipt, ok := bc.borReceiptsCache.Get(hash); ok {
|
||||
return receipt.(*types.BorReceipt)
|
||||
}
|
||||
|
||||
// read header from hash
|
||||
number := rawdb.ReadHeaderNumber(bc.db, hash)
|
||||
if number == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// read bor reciept by hash and number
|
||||
receipt := rawdb.ReadBorReceipt(bc.db, hash, *number)
|
||||
if receipt == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// add into bor receipt cache
|
||||
bc.borReceiptsCache.Add(hash, receipt)
|
||||
return receipt
|
||||
}
|
||||
|
|
@ -596,7 +596,7 @@ func WriteBlock(db ethdb.KeyValueWriter, block *types.Block) {
|
|||
}
|
||||
|
||||
// WriteAncientBlock writes entire block data into ancient store and returns the total written size.
|
||||
func WriteAncientBlock(db ethdb.AncientWriter, block *types.Block, receipts types.Receipts, td *big.Int) int {
|
||||
func WriteAncientBlock(db ethdb.AncientWriter, block *types.Block, receipts types.Receipts, td *big.Int, borReceipt *types.BorReceipt) int {
|
||||
// Encode all block components to RLP format.
|
||||
headerBlob, err := rlp.EncodeToBytes(block.Header())
|
||||
if err != nil {
|
||||
|
|
@ -618,8 +618,17 @@ func WriteAncientBlock(db ethdb.AncientWriter, block *types.Block, receipts type
|
|||
if err != nil {
|
||||
log.Crit("Failed to RLP encode block total difficulty", "err", err)
|
||||
}
|
||||
|
||||
borReceiptBlob := make([]byte, 0)
|
||||
if borReceipt != nil {
|
||||
borReceiptBlob, err = rlp.EncodeToBytes(borReceipt)
|
||||
if err != nil {
|
||||
log.Crit("Failed to RLP encode bor block receipt", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Write all blob to flatten files.
|
||||
err = db.AppendAncient(block.NumberU64(), block.Hash().Bytes(), headerBlob, bodyBlob, receiptBlob, tdBlob)
|
||||
err = db.AppendAncient(block.NumberU64(), block.Hash().Bytes(), headerBlob, bodyBlob, receiptBlob, tdBlob, borReceiptBlob)
|
||||
if err != nil {
|
||||
log.Crit("Failed to write block data to ancient store", "err", err)
|
||||
}
|
||||
|
|
@ -632,6 +641,9 @@ func DeleteBlock(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
|
|||
DeleteHeader(db, hash, number)
|
||||
DeleteBody(db, hash, number)
|
||||
DeleteTd(db, hash, number)
|
||||
|
||||
// delete bor receipt
|
||||
DeleteBorReceipt(db, hash, number)
|
||||
}
|
||||
|
||||
// DeleteBlockWithoutNumber removes all block data associated with a hash, except
|
||||
|
|
@ -641,6 +653,9 @@ func DeleteBlockWithoutNumber(db ethdb.KeyValueWriter, hash common.Hash, number
|
|||
deleteHeaderWithoutNumber(db, hash, number)
|
||||
DeleteBody(db, hash, number)
|
||||
DeleteTd(db, hash, number)
|
||||
|
||||
// delete bor receipt
|
||||
DeleteBorReceipt(db, hash, number)
|
||||
}
|
||||
|
||||
// FindCommonAncestor returns the last common ancestor of two block headers
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ func TestAncientStorage(t *testing.T) {
|
|||
t.Fatalf("non existent td returned")
|
||||
}
|
||||
// Write and verify the header in the database
|
||||
WriteAncientBlock(db, block, nil, big.NewInt(100))
|
||||
WriteAncientBlock(db, block, nil, big.NewInt(100), nil)
|
||||
if blob := ReadHeaderRLP(db, hash, number); len(blob) == 0 {
|
||||
t.Fatalf("no header returned")
|
||||
}
|
||||
|
|
|
|||
133
core/rawdb/bor_receipt.go
Normal file
133
core/rawdb/bor_receipt.go
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
package rawdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/core/types"
|
||||
"github.com/maticnetwork/bor/ethdb"
|
||||
"github.com/maticnetwork/bor/log"
|
||||
"github.com/maticnetwork/bor/rlp"
|
||||
)
|
||||
|
||||
var (
|
||||
borReceiptPrefix = []byte("bor-receipt-") // borReceiptPrefix + number + block hash -> bor block receipt
|
||||
|
||||
// freezerReceiptTable indicates the name of the freezer bor receipts table.
|
||||
freezerBorReceiptTable = "bor-receipts"
|
||||
)
|
||||
|
||||
// borReceiptKey = borReceiptPrefix + num (uint64 big endian) + hash
|
||||
func borReceiptKey(number uint64, hash common.Hash) []byte {
|
||||
return append(append(borReceiptPrefix, encodeBlockNumber(number)...), hash.Bytes()...)
|
||||
}
|
||||
|
||||
// HasBorReceipt verifies the existence of all block receipt belonging
|
||||
// to a block.
|
||||
func HasBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) bool {
|
||||
if has, err := db.Ancient(freezerHashTable, number); err == nil && common.BytesToHash(has) == hash {
|
||||
return true
|
||||
}
|
||||
|
||||
if has, err := db.Has(borReceiptKey(number, hash)); !has || err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadBorReceiptRLP retrieves all the transaction receipts belonging to a block in RLP encoding.
|
||||
func ReadBorReceiptRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.RawValue {
|
||||
// First try to look up the data in ancient database. Extra hash
|
||||
// comparison is necessary since ancient database only maintains
|
||||
// the canonical data.
|
||||
data, _ := db.Ancient(freezerBorReceiptTable, number)
|
||||
if len(data) > 0 {
|
||||
h, _ := db.Ancient(freezerHashTable, number)
|
||||
if common.BytesToHash(h) == hash {
|
||||
return data
|
||||
}
|
||||
}
|
||||
// Then try to look up the data in leveldb.
|
||||
data, _ = db.Get(borReceiptKey(number, hash))
|
||||
if len(data) > 0 {
|
||||
fmt.Println("==> RAWDB IN ReadBorReceiptRLP", common.Bytes2Hex(data))
|
||||
return data
|
||||
}
|
||||
// In the background freezer is moving data from leveldb to flatten files.
|
||||
// So during the first check for ancient db, the data is not yet in there,
|
||||
// but when we reach into leveldb, the data was already moved. That would
|
||||
// result in a not found error.
|
||||
data, _ = db.Ancient(freezerReceiptTable, number)
|
||||
if len(data) > 0 {
|
||||
h, _ := db.Ancient(freezerHashTable, number)
|
||||
if common.BytesToHash(h) == hash {
|
||||
return data
|
||||
}
|
||||
}
|
||||
return nil // Can't find the data anywhere.
|
||||
}
|
||||
|
||||
// ReadRawBorReceipt retrieves the block receipt belonging to a block.
|
||||
// The receipt metadata fields are not guaranteed to be populated, so they
|
||||
// should not be used. Use ReadBorReceipt instead if the metadata is needed.
|
||||
func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.BorReceipt {
|
||||
// Retrieve the flattened receipt slice
|
||||
data := ReadBorReceiptRLP(db, hash, number)
|
||||
if data == nil || len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert the receipts from their storage form to their internal representation
|
||||
var storageReceipt types.BorReceiptForStorage
|
||||
if err := rlp.DecodeBytes(data, &storageReceipt); err != nil {
|
||||
log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return (*types.BorReceipt)(&storageReceipt)
|
||||
}
|
||||
|
||||
// ReadBorReceipt retrieves all the bor block receipts belonging to a block, including
|
||||
// its correspoinding metadata fields. If it is unable to populate these metadata
|
||||
// fields then nil is returned.
|
||||
func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.BorReceipt {
|
||||
// We're deriving many fields from the block body, retrieve beside the receipt
|
||||
borReceipt := ReadRawBorReceipt(db, hash, number)
|
||||
if borReceipt == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
body := ReadBody(db, hash, number)
|
||||
if body == nil {
|
||||
log.Error("Missing body but have bor receipt", "hash", hash, "number", number)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := borReceipt.DeriveFields(hash, number); err != nil {
|
||||
log.Error("Failed to derive bor receipt fields", "hash", hash, "number", number, "err", err)
|
||||
return nil
|
||||
}
|
||||
return borReceipt
|
||||
}
|
||||
|
||||
// WriteBorReceipt stores all the bor receipt belonging to a block.
|
||||
func WriteBorReceipt(db ethdb.KeyValueWriter, hash common.Hash, number uint64, borReceipt *types.BorReceiptForStorage) {
|
||||
// Convert the bor receipt into their storage form and serialize them
|
||||
bytes, err := rlp.EncodeToBytes(borReceipt)
|
||||
if err != nil {
|
||||
log.Crit("Failed to encode bor receipt", "err", err)
|
||||
}
|
||||
|
||||
// Store the flattened receipt slice
|
||||
if err := db.Put(borReceiptKey(number, hash), bytes); err != nil {
|
||||
log.Crit("Failed to store bor receipt", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteBorReceipt removes receipt data associated with a block hash.
|
||||
func DeleteBorReceipt(db ethdb.KeyValueWriter, hash common.Hash, number uint64) {
|
||||
if err := db.Delete(borReceiptKey(number, hash)); err != nil {
|
||||
log.Crit("Failed to delete bor receipt", "err", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ func (db *nofreezedb) AncientSize(kind string) (uint64, error) {
|
|||
}
|
||||
|
||||
// AppendAncient returns an error as we don't have a backing chain freezer.
|
||||
func (db *nofreezedb) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error {
|
||||
func (db *nofreezedb) AppendAncient(number uint64, hash, header, body, receipts, td, borBlockReceipt []byte) error {
|
||||
return errNotSupported
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ func (f *freezer) AncientSize(kind string) (uint64, error) {
|
|||
// Notably, this function is lock free but kind of thread-safe. All out-of-order
|
||||
// injection will be rejected. But if two injections with same number happen at
|
||||
// the same time, we can get into the trouble.
|
||||
func (f *freezer) AppendAncient(number uint64, hash, header, body, receipts, td []byte) (err error) {
|
||||
func (f *freezer) AppendAncient(number uint64, hash, header, body, receipts, td, borBlockReceipt []byte) (err error) {
|
||||
// Ensure the binary blobs we are appending is continuous with freezer.
|
||||
if atomic.LoadUint64(&f.frozen) != number {
|
||||
return errOutOrderInsertion
|
||||
|
|
@ -217,6 +217,11 @@ func (f *freezer) AppendAncient(number uint64, hash, header, body, receipts, td
|
|||
log.Error("Failed to append ancient difficulty", "number", f.frozen, "hash", hash, "err", err)
|
||||
return err
|
||||
}
|
||||
if err := f.tables[freezerBorReceiptTable].Append(f.frozen, borBlockReceipt); err != nil {
|
||||
log.Error("Failed to append bor block receipt", "number", f.frozen, "hash", hash, "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
atomic.AddUint64(&f.frozen, 1) // Only modify atomically
|
||||
return nil
|
||||
}
|
||||
|
|
@ -340,9 +345,13 @@ func (f *freezer) freeze(db ethdb.KeyValueStore) {
|
|||
log.Error("Total difficulty missing, can't freeze", "number", f.frozen, "hash", hash)
|
||||
break
|
||||
}
|
||||
|
||||
// bor block receipt
|
||||
borBlockReceipt := ReadBorReceiptRLP(nfdb, hash, f.frozen)
|
||||
|
||||
log.Trace("Deep froze ancient block", "number", f.frozen, "hash", hash)
|
||||
// Inject all the components into the relevant data tables
|
||||
if err := f.AppendAncient(f.frozen, hash[:], header, body, receipts, td); err != nil {
|
||||
if err := f.AppendAncient(f.frozen, hash[:], header, body, receipts, td, borBlockReceipt); err != nil {
|
||||
break
|
||||
}
|
||||
ancients = append(ancients, hash)
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ var freezerNoSnappy = map[string]bool{
|
|||
freezerHashTable: true,
|
||||
freezerBodiesTable: false,
|
||||
freezerReceiptTable: false,
|
||||
freezerBorReceiptTable: false,
|
||||
freezerDifficultyTable: true,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ func (t *table) AncientSize(kind string) (uint64, error) {
|
|||
|
||||
// AppendAncient is a noop passthrough that just forwards the request to the underlying
|
||||
// database.
|
||||
func (t *table) AppendAncient(number uint64, hash, header, body, receipts, td []byte) error {
|
||||
return t.db.AppendAncient(number, hash, header, body, receipts, td)
|
||||
func (t *table) AppendAncient(number uint64, hash, header, body, receipts, td, borBlockReceipt []byte) error {
|
||||
return t.db.AppendAncient(number, hash, header, body, receipts, td, borBlockReceipt)
|
||||
}
|
||||
|
||||
// TruncateAncients is a noop passthrough that just forwards the request to the underlying
|
||||
|
|
|
|||
110
core/types/bor_receipt.go
Normal file
110
core/types/bor_receipt.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/crypto"
|
||||
"github.com/maticnetwork/bor/rlp"
|
||||
)
|
||||
|
||||
// BorReceipt represents the results of a block state syncs
|
||||
type BorReceipt struct {
|
||||
// Consensus fields
|
||||
Bloom Bloom `json:"logsBloom" gencodec:"required"`
|
||||
Logs []*Log `json:"logs" gencodec:"required"`
|
||||
|
||||
// Inclusion information: These fields provide information about the inclusion of the
|
||||
// transaction corresponding to this receipt.
|
||||
BlockHash common.Hash `json:"blockHash,omitempty"`
|
||||
BlockNumber *big.Int `json:"blockNumber,omitempty"`
|
||||
}
|
||||
|
||||
// borReceiptRLP is the consensus encoding of a block receipt.
|
||||
type borReceiptRLP struct {
|
||||
Bloom Bloom
|
||||
Logs []*Log
|
||||
}
|
||||
|
||||
// storedBorReceiptRLP is the storage encoding of a block receipt.
|
||||
type storedBorReceiptRLP struct {
|
||||
Logs []*LogForStorage
|
||||
}
|
||||
|
||||
// EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a block receipt
|
||||
// into an RLP stream. If no post state is present, byzantium fork is assumed.
|
||||
func (r *BorReceipt) EncodeRLP(w io.Writer) error {
|
||||
return rlp.Encode(w, &borReceiptRLP{r.Bloom, r.Logs})
|
||||
}
|
||||
|
||||
// DecodeRLP implements rlp.Decoder, and loads the consensus fields of a block receipt
|
||||
// from an RLP stream.
|
||||
func (r *BorReceipt) DecodeRLP(s *rlp.Stream) error {
|
||||
var dec receiptRLP
|
||||
if err := s.Decode(&dec); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Bloom, r.Logs = dec.Bloom, dec.Logs
|
||||
return nil
|
||||
}
|
||||
|
||||
// BorReceiptForStorage is a wrapper around a Bor Receipt that flattens and parses the
|
||||
// entire content of a receipt, as opposed to only the consensus fields originally.
|
||||
type BorReceiptForStorage BorReceipt
|
||||
|
||||
// EncodeRLP implements rlp.Encoder, and flattens all content fields of a receipt
|
||||
// into an RLP stream.
|
||||
func (r *BorReceiptForStorage) EncodeRLP(w io.Writer) error {
|
||||
enc := &storedBorReceiptRLP{
|
||||
Logs: make([]*LogForStorage, len(r.Logs)),
|
||||
}
|
||||
|
||||
for i, log := range r.Logs {
|
||||
enc.Logs[i] = (*LogForStorage)(log)
|
||||
}
|
||||
return rlp.Encode(w, enc)
|
||||
}
|
||||
|
||||
// DecodeRLP implements rlp.Decoder, and loads both consensus and implementation
|
||||
// fields of a receipt from an RLP stream.
|
||||
func (r *BorReceiptForStorage) DecodeRLP(s *rlp.Stream) error {
|
||||
// Retrieve the entire receipt blob as we need to try multiple decoders
|
||||
blob, err := s.Raw()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return decodeStoredBorReceiptRLP(r, blob)
|
||||
}
|
||||
|
||||
func decodeStoredBorReceiptRLP(r *BorReceiptForStorage, blob []byte) error {
|
||||
var stored storedBorReceiptRLP
|
||||
if err := rlp.DecodeBytes(blob, &stored); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.Logs = make([]*Log, len(stored.Logs))
|
||||
for i, log := range stored.Logs {
|
||||
r.Logs[i] = (*Log)(log)
|
||||
}
|
||||
r.Bloom = BytesToBloom(LogsBloom(r.Logs).Bytes())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeriveFields fills the receipts with their computed fields based on consensus
|
||||
// data and contextual infos like containing block and transactions.
|
||||
func (r *BorReceipt) DeriveFields(hash common.Hash, number uint64) error {
|
||||
txHash := common.BytesToHash(crypto.Keccak256(append([]byte("matic-receipt-"), hash.Bytes()...)))
|
||||
|
||||
// The derived log fields can simply be set from the block and transaction
|
||||
for j := 0; j < len(r.Logs); j++ {
|
||||
r.Logs[j].BlockNumber = number
|
||||
r.Logs[j].BlockHash = hash
|
||||
r.Logs[j].TxHash = txHash
|
||||
r.Logs[j].TxIndex = uint(0)
|
||||
r.Logs[j].Index = uint(j)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -23,7 +23,6 @@ import (
|
|||
|
||||
"github.com/maticnetwork/bor/accounts"
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/consensus/bor"
|
||||
"github.com/maticnetwork/bor/core"
|
||||
"github.com/maticnetwork/bor/core/bloombits"
|
||||
"github.com/maticnetwork/bor/core/rawdb"
|
||||
|
|
@ -312,17 +311,3 @@ func (b *EthAPIBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma
|
|||
go session.Multiplex(bloomRetrievalBatch, bloomRetrievalWait, b.eth.bloomRequests)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) {
|
||||
var api *bor.API
|
||||
for _, _api := range b.eth.Engine().APIs(b.eth.BlockChain()) {
|
||||
if _api.Namespace == "bor" {
|
||||
api = _api.Service.(*bor.API)
|
||||
}
|
||||
}
|
||||
root, err := api.GetRootHash(starBlockNr, endBlockNr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
|
|
|||
46
eth/bor_api_backend.go
Normal file
46
eth/bor_api_backend.go
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package eth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ethereum "github.com/maticnetwork/bor"
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/consensus/bor"
|
||||
"github.com/maticnetwork/bor/core/types"
|
||||
)
|
||||
|
||||
func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) {
|
||||
var api *bor.API
|
||||
for _, _api := range b.eth.Engine().APIs(b.eth.BlockChain()) {
|
||||
if _api.Namespace == "bor" {
|
||||
api = _api.Service.(*bor.API)
|
||||
}
|
||||
}
|
||||
|
||||
root, err := api.GetRootHash(starBlockNr, endBlockNr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
receipt := b.eth.blockchain.GetBorReceiptByHash(hash)
|
||||
if receipt == nil {
|
||||
return nil, ethereum.NotFound
|
||||
}
|
||||
|
||||
return receipt, nil
|
||||
}
|
||||
|
||||
// func (b *EthAPIBackend) GetBorBlockLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
|
||||
// receipts := b.eth.blockchain.GetReceiptsByHash(hash)
|
||||
// if receipts == nil {
|
||||
// return nil, nil
|
||||
// }
|
||||
// logs := make([][]*types.Log, len(receipts))
|
||||
// for i, receipt := range receipts {
|
||||
// logs[i] = receipt.Logs
|
||||
// }
|
||||
// return logs, nil
|
||||
// }
|
||||
30
ethclient/bor_ethclient.go
Normal file
30
ethclient/bor_ethclient.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package ethclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ethereum "github.com/maticnetwork/bor"
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/core/types"
|
||||
)
|
||||
|
||||
// GetRootHash returns the merkle root of the block headers
|
||||
func (ec *Client) GetRootHash(ctx context.Context, startBlockNumber uint64, endBlockNumber uint64) (string, error) {
|
||||
var rootHash string
|
||||
if err := ec.c.CallContext(ctx, &rootHash, "eth_getRootHash", startBlockNumber, endBlockNumber); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return rootHash, nil
|
||||
}
|
||||
|
||||
// GetBorBlockReceipt returns bor block receipt
|
||||
func (ec *Client) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
var r *types.BorReceipt
|
||||
err := ec.c.CallContext(ctx, &r, "eth_getBorBlockReceipt", hash)
|
||||
if err == nil {
|
||||
if r == nil {
|
||||
return nil, ethereum.NotFound
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
}
|
||||
|
|
@ -522,15 +522,6 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er
|
|||
return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data))
|
||||
}
|
||||
|
||||
// GetRootHash returns the merkle root of the block headers
|
||||
func (ec *Client) GetRootHash(ctx context.Context, startBlockNumber uint64, endBlockNumber uint64) (string, error) {
|
||||
var rootHash string
|
||||
if err := ec.c.CallContext(ctx, &rootHash, "eth_getRootHash", startBlockNumber, endBlockNumber); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return rootHash, nil
|
||||
}
|
||||
|
||||
func toCallArg(msg ethereum.CallMsg) interface{} {
|
||||
arg := map[string]interface{}{
|
||||
"from": msg.From,
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ type AncientReader interface {
|
|||
type AncientWriter interface {
|
||||
// AppendAncient injects all binary blobs belong to block at the end of the
|
||||
// append-only immutable table files.
|
||||
AppendAncient(number uint64, hash, header, body, receipt, td []byte) error
|
||||
AppendAncient(number uint64, hash, header, body, receipt, td, borBlockReceipt []byte) error
|
||||
|
||||
// TruncateAncients discards all but the first n ancient data from the ancient store.
|
||||
TruncateAncients(n uint64) error
|
||||
|
|
|
|||
|
|
@ -748,14 +748,6 @@ func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.A
|
|||
return res[:], state.Error()
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) {
|
||||
root, err := s.b.GetRootHash(ctx, starBlockNr, endBlockNr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// CallArgs represents the arguments for a call.
|
||||
type CallArgs struct {
|
||||
From *common.Address `json:"from"`
|
||||
|
|
|
|||
|
|
@ -65,7 +65,10 @@ type Backend interface {
|
|||
SubscribeStateSyncEvent(ch chan<- core.StateSyncEvent) event.Subscription
|
||||
SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription
|
||||
SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription
|
||||
|
||||
// Bor API
|
||||
GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error)
|
||||
GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error)
|
||||
|
||||
// Transaction pool API
|
||||
SendTx(ctx context.Context, signedTx *types.Transaction) error
|
||||
|
|
|
|||
20
internal/ethapi/bor_api.go
Normal file
20
internal/ethapi/bor_api.go
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
package ethapi
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/core/types"
|
||||
)
|
||||
|
||||
func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) {
|
||||
root, err := s.b.GetRootHash(ctx, starBlockNr, endBlockNr)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return root, nil
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
return s.b.GetBorBlockReceipt(ctx, hash)
|
||||
}
|
||||
|
|
@ -287,3 +287,7 @@ func (b *LesApiBackend) ServiceFilter(ctx context.Context, session *bloombits.Ma
|
|||
func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error) {
|
||||
return "", errors.New("Not implemented")
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
return nil, errors.New("Not implemented")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue