mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-27 23:26:44 +00:00
new: add bor block tx/receipt/logs as normal entities
This commit is contained in:
parent
eeecd69289
commit
30708baafd
17 changed files with 271 additions and 131 deletions
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/maticnetwork/bor/core/types"
|
||||
)
|
||||
|
||||
func (fb *filterBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
func (fb *filterBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
|
||||
number := rawdb.ReadHeaderNumber(fb.db, hash)
|
||||
if number == nil {
|
||||
return nil, nil
|
||||
|
|
|
|||
|
|
@ -497,6 +497,7 @@ func (bc *BlockChain) SetHead(head uint64) error {
|
|||
// removed in the hc.SetHead function.
|
||||
rawdb.DeleteBody(db, hash, num)
|
||||
rawdb.DeleteReceipts(db, hash, num)
|
||||
rawdb.DeleteBorReceipt(db, hash, num)
|
||||
}
|
||||
// Todo(rjl493456442) txlookup, bloombits, etc
|
||||
}
|
||||
|
|
@ -509,6 +510,7 @@ func (bc *BlockChain) SetHead(head uint64) error {
|
|||
bc.blockCache.Purge()
|
||||
bc.txLookupCache.Purge()
|
||||
bc.futureBlocks.Purge()
|
||||
bc.borReceiptsCache.Purge()
|
||||
|
||||
return bc.loadLastState()
|
||||
}
|
||||
|
|
@ -1460,8 +1462,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
|||
})
|
||||
|
||||
if len(blockLogs) > len(logs) {
|
||||
rawdb.WriteBorReceipt(blockBatch, block.Hash(), block.NumberU64(), &types.BorReceiptForStorage{
|
||||
Logs: blockLogs[len(logs):], // get state-sync logs from `state.Logs()`
|
||||
rawdb.WriteBorReceipt(blockBatch, block.Hash(), block.NumberU64(), &types.ReceiptForStorage{
|
||||
Status: types.ReceiptStatusSuccessful, // make receipt status successful
|
||||
Logs: blockLogs[len(logs):], // get state-sync logs from `state.Logs()`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import (
|
|||
)
|
||||
|
||||
// GetBorReceiptByHash retrieves the bor block receipt in a given block.
|
||||
func (bc *BlockChain) GetBorReceiptByHash(hash common.Hash) *types.BorReceipt {
|
||||
func (bc *BlockChain) GetBorReceiptByHash(hash common.Hash) *types.Receipt {
|
||||
if receipt, ok := bc.borReceiptsCache.Get(hash); ok {
|
||||
return receipt.(*types.BorReceipt)
|
||||
return receipt.(*types.Receipt)
|
||||
}
|
||||
|
||||
// read header from hash
|
||||
|
|
|
|||
|
|
@ -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, borReceipt *types.BorReceipt) int {
|
||||
func WriteAncientBlock(db ethdb.AncientWriter, block *types.Block, receipts types.Receipts, td *big.Int, borReceipt *types.Receipt) int {
|
||||
// Encode all block components to RLP format.
|
||||
headerBlob, err := rlp.EncodeToBytes(block.Header())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
package rawdb
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/core/types"
|
||||
"github.com/maticnetwork/bor/ethdb"
|
||||
|
|
@ -9,15 +11,19 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
borReceiptPrefix = []byte("bor-receipt-") // borReceiptPrefix + number + block hash -> bor block receipt
|
||||
// bor receipt key
|
||||
borReceiptKey = types.BorReceiptKey
|
||||
|
||||
// borTxLookupPrefix + hash -> transaction/receipt lookup metadata
|
||||
borTxLookupPrefix = []byte("matic-bor-tx-lookup-")
|
||||
|
||||
// freezerBorReceiptTable indicates the name of the freezer bor receipts table.
|
||||
freezerBorReceiptTable = "bor-receipts"
|
||||
freezerBorReceiptTable = "matic-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()...)
|
||||
// borTxLookupKey = borTxLookupPrefix + hash
|
||||
func borTxLookupKey(hash common.Hash) []byte {
|
||||
return append(borTxLookupPrefix, hash.Bytes()...)
|
||||
}
|
||||
|
||||
// HasBorReceipt verifies the existence of all block receipt belonging
|
||||
|
|
@ -68,7 +74,7 @@ func ReadBorReceiptRLP(db ethdb.Reader, hash common.Hash, number uint64) rlp.Raw
|
|||
// 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 {
|
||||
func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.Receipt {
|
||||
// Retrieve the flattened receipt slice
|
||||
data := ReadBorReceiptRLP(db, hash, number)
|
||||
if data == nil || len(data) == 0 {
|
||||
|
|
@ -76,32 +82,38 @@ func ReadRawBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.
|
|||
}
|
||||
|
||||
// Convert the receipts from their storage form to their internal representation
|
||||
var storageReceipt types.BorReceiptForStorage
|
||||
var storageReceipt types.ReceiptForStorage
|
||||
if err := rlp.DecodeBytes(data, &storageReceipt); err != nil {
|
||||
log.Error("Invalid receipt array RLP", "hash", hash, "err", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return (*types.BorReceipt)(&storageReceipt)
|
||||
return (*types.Receipt)(&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 {
|
||||
func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.Receipt {
|
||||
// We're deriving many fields from the block body, retrieve beside the receipt
|
||||
borReceipt := ReadRawBorReceipt(db, hash, number)
|
||||
if borReceipt == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// We're deriving many fields from the block body, retrieve beside the receipt
|
||||
receipts := ReadRawReceipts(db, hash, number)
|
||||
if receipts == 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 {
|
||||
if err := types.DeriveFieldsForBorReceipt(borReceipt, hash, number, receipts); err != nil {
|
||||
log.Error("Failed to derive bor receipt fields", "hash", hash, "number", number, "err", err)
|
||||
return nil
|
||||
}
|
||||
|
|
@ -109,7 +121,7 @@ func ReadBorReceipt(db ethdb.Reader, hash common.Hash, number uint64) *types.Bor
|
|||
}
|
||||
|
||||
// WriteBorReceipt stores all the bor receipt belonging to a block.
|
||||
func WriteBorReceipt(db ethdb.KeyValueWriter, hash common.Hash, number uint64, borReceipt *types.BorReceiptForStorage) {
|
||||
func WriteBorReceipt(db ethdb.KeyValueWriter, hash common.Hash, number uint64, borReceipt *types.ReceiptForStorage) {
|
||||
// Convert the bor receipt into their storage form and serialize them
|
||||
bytes, err := rlp.EncodeToBytes(borReceipt)
|
||||
if err != nil {
|
||||
|
|
@ -117,14 +129,73 @@ func WriteBorReceipt(db ethdb.KeyValueWriter, hash common.Hash, number uint64, b
|
|||
}
|
||||
|
||||
// Store the flattened receipt slice
|
||||
if err := db.Put(borReceiptKey(number, hash), bytes); err != nil {
|
||||
key := borReceiptKey(number, hash)
|
||||
if err := db.Put(key, bytes); err != nil {
|
||||
log.Crit("Failed to store bor receipt", "err", err)
|
||||
}
|
||||
|
||||
// Write bor tx reverse lookup
|
||||
WriteBorTxLookupEntry(db, types.GetDerivedBorTxHash(key), big.NewInt(0).SetUint64(number))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
key := borReceiptKey(number, hash)
|
||||
|
||||
if err := db.Delete(key); err != nil {
|
||||
log.Crit("Failed to delete bor receipt", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// ReadBorTransaction retrieves a specific bor (fake) transaction, along with
|
||||
// its added positional metadata.
|
||||
func ReadBorTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64) {
|
||||
blockNumber := ReadBorTxLookupEntry(db, hash)
|
||||
if blockNumber == nil {
|
||||
return nil, common.Hash{}, 0, 0
|
||||
}
|
||||
|
||||
blockHash := ReadCanonicalHash(db, *blockNumber)
|
||||
if blockHash == (common.Hash{}) {
|
||||
return nil, common.Hash{}, 0, 0
|
||||
}
|
||||
|
||||
body := ReadBody(db, blockHash, *blockNumber)
|
||||
if body == nil {
|
||||
log.Error("Transaction referenced missing", "number", blockNumber, "hash", blockHash)
|
||||
return nil, common.Hash{}, 0, 0
|
||||
}
|
||||
|
||||
// fetch receipt and return it
|
||||
return types.NewBorTransaction(), blockHash, *blockNumber, uint64(len(body.Transactions))
|
||||
}
|
||||
|
||||
//
|
||||
// Indexes for reverse lookup
|
||||
//
|
||||
|
||||
// ReadBorTxLookupEntry retrieves the positional metadata associated with a transaction
|
||||
// hash to allow retrieving the bor transaction or bor receipt by hash.
|
||||
func ReadBorTxLookupEntry(db ethdb.Reader, hash common.Hash) *uint64 {
|
||||
data, _ := db.Get(borTxLookupKey(hash))
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
number := new(big.Int).SetBytes(data).Uint64()
|
||||
return &number
|
||||
}
|
||||
|
||||
// WriteBorTxLookupEntry stores a positional metadata for bor transaction.
|
||||
func WriteBorTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash, number *big.Int) {
|
||||
if err := db.Put(borTxLookupKey(hash), number.Bytes()); err != nil {
|
||||
log.Crit("Failed to store bor transaction lookup entry", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteBorTxLookupEntry removes bor transaction data associated with a hash.
|
||||
func DeleteBorTxLookupEntry(db ethdb.KeyValueWriter, hash common.Hash) {
|
||||
if err := db.Delete(borTxLookupKey(hash)); err != nil {
|
||||
log.Crit("Failed to delete bor transaction lookup entry", "err", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,109 +1,73 @@
|
|||
package types
|
||||
|
||||
import (
|
||||
"io"
|
||||
"encoding/binary"
|
||||
"math/big"
|
||||
"sort"
|
||||
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/rlp"
|
||||
"github.com/maticnetwork/bor/crypto"
|
||||
)
|
||||
|
||||
// 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"`
|
||||
var (
|
||||
borReceiptPrefix = []byte("matic-bor-receipt-") // borReceiptPrefix + number + block hash -> bor block receipt
|
||||
|
||||
// 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"`
|
||||
// SystemAddress address for system sender
|
||||
SystemAddress = common.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE")
|
||||
)
|
||||
|
||||
// BorReceiptKey = borReceiptPrefix + num (uint64 big endian) + hash
|
||||
func BorReceiptKey(number uint64, hash common.Hash) []byte {
|
||||
enc := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(enc, number)
|
||||
return append(append(borReceiptPrefix, enc...), hash.Bytes()...)
|
||||
}
|
||||
|
||||
// borReceiptRLP is the consensus encoding of a block receipt.
|
||||
type borReceiptRLP struct {
|
||||
Bloom Bloom
|
||||
Logs []*Log
|
||||
// GetDerivedBorTxHash get derived tx hash from receipt key
|
||||
func GetDerivedBorTxHash(receiptKey []byte) common.Hash {
|
||||
return common.BytesToHash(crypto.Keccak256(receiptKey))
|
||||
}
|
||||
|
||||
// storedBorReceiptRLP is the storage encoding of a block receipt.
|
||||
type storedBorReceiptRLP struct {
|
||||
Logs []*LogForStorage
|
||||
// NewBorTransaction create new bor transaction for bor receipt
|
||||
func NewBorTransaction() *Transaction {
|
||||
return NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), make([]byte, 0))
|
||||
}
|
||||
|
||||
// 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
|
||||
// DeriveFieldsForBorReceipt 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("bor-receipt-"), hash.Bytes()...)))
|
||||
func DeriveFieldsForBorReceipt(receipt *Receipt, hash common.Hash, number uint64, receipts Receipts) error {
|
||||
// get derived tx hash
|
||||
txHash := GetDerivedBorTxHash(BorReceiptKey(number, hash))
|
||||
txIndex := uint(len(receipts))
|
||||
|
||||
// set tx hash and tx index
|
||||
receipt.TxHash = txHash
|
||||
receipt.TransactionIndex = txIndex
|
||||
receipt.BlockHash = hash
|
||||
receipt.BlockNumber = big.NewInt(0).SetUint64(number)
|
||||
|
||||
logIndex := 0
|
||||
for i := 0; i < len(receipts); i++ {
|
||||
logIndex += len(receipts[i].Logs)
|
||||
}
|
||||
|
||||
// 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)
|
||||
for j := 0; j < len(receipt.Logs); j++ {
|
||||
receipt.Logs[j].BlockNumber = number
|
||||
receipt.Logs[j].BlockHash = hash
|
||||
receipt.Logs[j].TxHash = txHash
|
||||
receipt.Logs[j].TxIndex = txIndex
|
||||
receipt.Logs[j].Index = uint(logIndex)
|
||||
logIndex++
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MergeBorLogs merges receipt logs and block receipt logs
|
||||
func MergeBorLogs(logs []*Log, borLogs []*Log) []*Log {
|
||||
result := append(logs, borLogs...)
|
||||
sort.SliceStable(result, func(i int, j int) bool {
|
||||
return (result[i].BlockNumber*100000 + uint64(result[i].Index)) < (result[j].BlockNumber*100000 + uint64(result[j].Index))
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
|
|
|||
|
|
@ -704,6 +704,16 @@ func (api *PrivateDebugAPI) computeStateDB(block *types.Block, reexec uint64) (*
|
|||
func (api *PrivateDebugAPI) TraceTransaction(ctx context.Context, hash common.Hash, config *TraceConfig) (interface{}, error) {
|
||||
// Retrieve the transaction and assemble its EVM context
|
||||
tx, blockHash, _, index := rawdb.ReadTransaction(api.eth.ChainDb(), hash)
|
||||
if tx == nil {
|
||||
// For BorTransaction, there will be no trace available
|
||||
tx, _, _, _ = rawdb.ReadBorTransaction(api.eth.ChainDb(), hash)
|
||||
if tx != nil {
|
||||
return ðapi.ExecutionResult{
|
||||
StructLogs: make([]ethapi.StructLogRes, 0),
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
if tx == nil {
|
||||
return nil, fmt.Errorf("transaction %#x not found", hash)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
ethereum "github.com/maticnetwork/bor"
|
||||
"github.com/maticnetwork/bor/common"
|
||||
"github.com/maticnetwork/bor/consensus/bor"
|
||||
"github.com/maticnetwork/bor/core/rawdb"
|
||||
"github.com/maticnetwork/bor/core/types"
|
||||
)
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ func (b *EthAPIBackend) GetRootHash(ctx context.Context, starBlockNr uint64, end
|
|||
return root, nil
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
func (b *EthAPIBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
|
||||
receipt := b.eth.blockchain.GetBorReceiptByHash(hash)
|
||||
if receipt == nil {
|
||||
return nil, ethereum.NotFound
|
||||
|
|
@ -40,3 +41,8 @@ func (b *EthAPIBackend) GetBorBlockLogs(ctx context.Context, hash common.Hash) (
|
|||
}
|
||||
return receipt.Logs, nil
|
||||
}
|
||||
|
||||
func (b *EthAPIBackend) GetBorBlockTransaction(ctx context.Context, hash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
tx, blockHash, blockNumber, index := rawdb.ReadBorTransaction(b.eth.ChainDb(), hash)
|
||||
return tx, blockHash, blockNumber, index, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,9 +357,12 @@ func (api *PublicFilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) {
|
|||
// https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getlogs
|
||||
func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error) {
|
||||
var filter *Filter
|
||||
var borLogsFilter *BorBlockLogsFilter
|
||||
if crit.BlockHash != nil {
|
||||
// Block filter requested, construct a single-shot filter
|
||||
filter = NewBlockFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics)
|
||||
// Block bor filter
|
||||
borLogsFilter = NewBorBlockLogsFilter(api.backend, *crit.BlockHash, crit.Addresses, crit.Topics)
|
||||
} else {
|
||||
// Convert the RPC block numbers into internal representations
|
||||
begin := rpc.LatestBlockNumber.Int64()
|
||||
|
|
@ -372,13 +375,23 @@ func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([
|
|||
}
|
||||
// Construct the range filter
|
||||
filter = NewRangeFilter(api.backend, begin, end, crit.Addresses, crit.Topics)
|
||||
// Block bor filter
|
||||
borLogsFilter = NewBorBlockLogsRangeFilter(api.backend, begin, end, crit.Addresses, crit.Topics)
|
||||
}
|
||||
|
||||
// Run the filter and return all the logs
|
||||
logs, err := filter.Logs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return returnLogs(logs), err
|
||||
// Run the filter and return all the logs
|
||||
borBlockLogs, err := borLogsFilter.Logs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// merge bor block logs and receipt logs and return it
|
||||
return returnLogs(types.MergeBorLogs(logs, borBlockLogs)), err
|
||||
}
|
||||
|
||||
// UninstallFilter removes the filter with the given filter id.
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ func (f *BorBlockLogsFilter) Logs(ctx context.Context) ([]*types.Log, error) {
|
|||
}
|
||||
|
||||
// adjust begin for sprint
|
||||
f.begin = nextSprintEnd(f.begin)
|
||||
f.begin = currentSprintEnd(f.begin)
|
||||
|
||||
end := f.end
|
||||
if f.end == -1 {
|
||||
|
|
@ -136,15 +136,14 @@ func (f *BorBlockLogsFilter) unindexedLogs(ctx context.Context, end uint64) ([]*
|
|||
}
|
||||
|
||||
// borBlockLogs returns the logs matching the filter criteria within a single block.
|
||||
func (f *BorBlockLogsFilter) borBlockLogs(ctx context.Context, receipt *types.BorReceipt) (logs []*types.Log, err error) {
|
||||
func (f *BorBlockLogsFilter) borBlockLogs(ctx context.Context, receipt *types.Receipt) (logs []*types.Log, err error) {
|
||||
if bloomFilter(receipt.Bloom, f.addresses, f.topics) {
|
||||
found := filterLogs(receipt.Logs, nil, nil, f.addresses, f.topics)
|
||||
logs = append(logs, found...)
|
||||
logs = filterLogs(receipt.Logs, nil, nil, f.addresses, f.topics)
|
||||
}
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
func nextSprintEnd(n int64) int64 {
|
||||
func currentSprintEnd(n int64) int64 {
|
||||
m := n % 64
|
||||
if m == 0 {
|
||||
return n
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/maticnetwork/bor/core/types"
|
||||
)
|
||||
|
||||
func (b *testBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
func (b *testBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
|
||||
number := rawdb.ReadHeaderNumber(b.db, hash)
|
||||
if number == nil {
|
||||
return nil, nil
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ type Backend interface {
|
|||
HeaderByHash(ctx context.Context, blockHash common.Hash) (*types.Header, error)
|
||||
GetReceipts(ctx context.Context, blockHash common.Hash) (types.Receipts, error)
|
||||
GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error)
|
||||
GetBorBlockReceipt(ctx context.Context, blockHash common.Hash) (*types.BorReceipt, error)
|
||||
GetBorBlockReceipt(ctx context.Context, blockHash common.Hash) (*types.Receipt, error)
|
||||
GetBorBlockLogs(ctx context.Context, blockHash common.Hash) ([]*types.Log, error)
|
||||
|
||||
SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ func (ec *Client) GetRootHash(ctx context.Context, startBlockNumber uint64, endB
|
|||
}
|
||||
|
||||
// GetBorBlockReceipt returns bor block receipt
|
||||
func (ec *Client) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
var r *types.BorReceipt
|
||||
func (ec *Client) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
|
||||
var r *types.Receipt
|
||||
err := ec.c.CallContext(ctx, &r, "eth_getBorBlockReceipt", hash)
|
||||
if err == nil {
|
||||
if r == nil {
|
||||
|
|
|
|||
|
|
@ -661,6 +661,12 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.B
|
|||
response[field] = nil
|
||||
}
|
||||
}
|
||||
|
||||
// append marshalled bor transaction
|
||||
if err == nil && response != nil {
|
||||
response = s.appendRPCMarshalBorTransaction(ctx, block, response, fullTx)
|
||||
}
|
||||
|
||||
return response, err
|
||||
}
|
||||
return nil, err
|
||||
|
|
@ -671,7 +677,12 @@ func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.B
|
|||
func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, hash common.Hash, fullTx bool) (map[string]interface{}, error) {
|
||||
block, err := s.b.BlockByHash(ctx, hash)
|
||||
if block != nil {
|
||||
return s.rpcMarshalBlock(block, true, fullTx)
|
||||
response, err := s.rpcMarshalBlock(block, true, fullTx)
|
||||
// append marshalled bor transaction
|
||||
if err == nil && response != nil {
|
||||
return s.appendRPCMarshalBorTransaction(ctx, block, response, fullTx), err
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -1357,14 +1368,33 @@ func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, addr
|
|||
|
||||
// GetTransactionByHash returns the transaction for the given hash
|
||||
func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
|
||||
borTx := false
|
||||
|
||||
// Try to return an already finalized transaction
|
||||
tx, blockHash, blockNumber, index, err := s.b.GetTransaction(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if tx != nil {
|
||||
return newRPCTransaction(tx, blockHash, blockNumber, index), nil
|
||||
|
||||
// fetch bor block tx if necessary
|
||||
if tx == nil {
|
||||
if tx, blockHash, blockNumber, index, err = s.b.GetBorBlockTransaction(ctx, hash); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
borTx = true
|
||||
}
|
||||
|
||||
if tx != nil {
|
||||
resultTx := newRPCTransaction(tx, blockHash, blockNumber, index)
|
||||
if borTx {
|
||||
// newRPCTransaction calculates hash based on RLP of the transaction data.
|
||||
// In case of bor block tx, we need simple derived tx hash (same as function argument) instead of RLP hash
|
||||
resultTx.Hash = hash
|
||||
}
|
||||
return resultTx, nil
|
||||
}
|
||||
|
||||
// No finalized transaction, try to retrieve it from the pool
|
||||
if tx := s.b.GetPoolTransaction(hash); tx != nil {
|
||||
return newRPCPendingTransaction(tx), nil
|
||||
|
|
@ -1393,18 +1423,33 @@ func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context,
|
|||
|
||||
// GetTransactionReceipt returns the transaction receipt for the given transaction hash.
|
||||
func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
|
||||
borTx := false
|
||||
|
||||
tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash)
|
||||
if tx == nil {
|
||||
tx, blockHash, blockNumber, index = rawdb.ReadBorTransaction(s.b.ChainDb(), hash)
|
||||
borTx = true
|
||||
}
|
||||
|
||||
if tx == nil {
|
||||
return nil, nil
|
||||
}
|
||||
receipts, err := s.b.GetReceipts(ctx, blockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
var receipt *types.Receipt
|
||||
|
||||
if borTx {
|
||||
// Fetch bor block receipt
|
||||
receipt = rawdb.ReadBorReceipt(s.b.ChainDb(), blockHash, blockNumber)
|
||||
} else {
|
||||
receipts, err := s.b.GetReceipts(ctx, blockHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(receipts) <= int(index) {
|
||||
return nil, nil
|
||||
}
|
||||
receipt = receipts[index]
|
||||
}
|
||||
if len(receipts) <= int(index) {
|
||||
return nil, nil
|
||||
}
|
||||
receipt := receipts[index]
|
||||
|
||||
var signer types.Signer = types.FrontierSigner{}
|
||||
if tx.Protected() {
|
||||
|
|
|
|||
|
|
@ -68,8 +68,9 @@ type Backend interface {
|
|||
|
||||
// Bor API
|
||||
GetRootHash(ctx context.Context, starBlockNr uint64, endBlockNr uint64) (string, error)
|
||||
GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error)
|
||||
GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error)
|
||||
GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error)
|
||||
GetBorBlockTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error)
|
||||
|
||||
// Transaction pool API
|
||||
SendTx(ctx context.Context, signedTx *types.Transaction) error
|
||||
|
|
|
|||
|
|
@ -15,6 +15,30 @@ func (s *PublicBlockChainAPI) GetRootHash(ctx context.Context, starBlockNr uint6
|
|||
return root, nil
|
||||
}
|
||||
|
||||
func (s *PublicBlockChainAPI) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
func (s *PublicBlockChainAPI) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
|
||||
return s.b.GetBorBlockReceipt(ctx, hash)
|
||||
}
|
||||
|
||||
//
|
||||
// Bor transaction utils
|
||||
//
|
||||
|
||||
func (s *PublicBlockChainAPI) appendRPCMarshalBorTransaction(ctx context.Context, block *types.Block, fields map[string]interface{}, fullTx bool) map[string]interface{} {
|
||||
if block != nil {
|
||||
txHash := types.GetDerivedBorTxHash(types.BorReceiptKey(block.Number().Uint64(), block.Hash()))
|
||||
borTx, blockHash, blockNumber, txIndex, _ := s.b.GetBorBlockTransaction(ctx, txHash)
|
||||
if borTx != nil {
|
||||
formattedTxs := fields["transactions"].([]interface{})
|
||||
if fullTx {
|
||||
marshalledTx := newRPCTransaction(borTx, blockHash, blockNumber, txIndex)
|
||||
// newRPCTransaction calculates hash based on RLP of the transaction data.
|
||||
// In case of bor block tx, we need simple derived tx hash (same as function argument) instead of RLP hash
|
||||
marshalledTx.Hash = txHash
|
||||
fields["transactions"] = append(formattedTxs, marshalledTx)
|
||||
} else {
|
||||
fields["transactions"] = append(formattedTxs, txHash)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
|
|
|||
|
|
@ -288,10 +288,14 @@ func (b *LesApiBackend) GetRootHash(ctx context.Context, starBlockNr uint64, end
|
|||
return "", errors.New("Not implemented")
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.BorReceipt, error) {
|
||||
func (b *LesApiBackend) GetBorBlockReceipt(ctx context.Context, hash common.Hash) (*types.Receipt, error) {
|
||||
return nil, errors.New("Not implemented")
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetBorBlockLogs(ctx context.Context, hash common.Hash) ([]*types.Log, error) {
|
||||
return nil, errors.New("Not implemented")
|
||||
}
|
||||
|
||||
func (b *LesApiBackend) GetBorBlockTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
return nil, common.Hash{}, 0, 0, errors.New("Not implemented")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue