mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
Additional bor RPC fixes (#4675)
* Add borTx to GetBlockByHash; ensure borTxs have hashes; don't try to derive sender for borTxs * Surface borReceipt logs in eth_getLogs * Check for existence of borReceipt before synthesizing a borTx
This commit is contained in:
parent
63f6eab6c7
commit
8de866028a
@ -339,6 +339,30 @@ func newRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber
|
||||
return result
|
||||
}
|
||||
|
||||
// newRPCBorTransaction returns a Bor transaction that will serialize to the RPC
|
||||
// representation, with the given location metadata set (if available).
|
||||
func newRPCBorTransaction(opaqueTx types.Transaction, txHash common.Hash, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int) *RPCTransaction {
|
||||
tx := opaqueTx.(*types.LegacyTx)
|
||||
result := &RPCTransaction{
|
||||
Type: hexutil.Uint64(tx.Type()),
|
||||
ChainID: (*hexutil.Big)(new(big.Int)),
|
||||
GasPrice: (*hexutil.Big)(tx.GasPrice.ToBig()),
|
||||
Gas: hexutil.Uint64(tx.GetGas()),
|
||||
Hash: txHash,
|
||||
Input: hexutil.Bytes(tx.GetData()),
|
||||
Nonce: hexutil.Uint64(tx.GetNonce()),
|
||||
From: common.Address{},
|
||||
To: tx.GetTo(),
|
||||
Value: (*hexutil.Big)(tx.GetValue().ToBig()),
|
||||
}
|
||||
if blockHash != (common.Hash{}) {
|
||||
result.BlockHash = &blockHash
|
||||
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
||||
result.TransactionIndex = (*hexutil.Uint64)(&index)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
||||
func newRPCPendingTransaction(tx types.Transaction, current *types.Header, config *params.ChainConfig) *RPCTransaction {
|
||||
var baseFee *big.Int
|
||||
|
@ -217,24 +217,15 @@ func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber
|
||||
return nil, err
|
||||
}
|
||||
var borTx types.Transaction
|
||||
var borReceipt *types.Receipt
|
||||
var borTxHash common.Hash
|
||||
if chainConfig.Bor != nil {
|
||||
borTx, _, _, _, err = rawdb.ReadBorTransactionWithBlockNumberAndHash(tx, b.NumberU64(), b.Hash())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
borTx, _, _, _ = rawdb.ReadBorTransactionForBlock(tx, b)
|
||||
if borTx != nil {
|
||||
borReceipt = rawdb.ReadBorReceipt(tx, b.Hash(), b.NumberU64())
|
||||
if borReceipt != nil {
|
||||
borTx, err = borTx.WithHash(borReceipt.TxHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
borTxHash = types.ComputeBorTxHash(b.NumberU64(), b.Hash())
|
||||
}
|
||||
}
|
||||
|
||||
response, err := ethapi.RPCMarshalBlockEx(b, true, fullTx, borTx, borReceipt, additionalFields)
|
||||
response, err := ethapi.RPCMarshalBlockEx(b, true, fullTx, borTx, borTxHash, additionalFields)
|
||||
|
||||
if err == nil && number == rpc.PendingBlockNumber {
|
||||
// Pending blocks need to nil out a few fields
|
||||
@ -280,7 +271,21 @@ func (api *APIImpl) GetBlockByHash(ctx context.Context, numberOrHash rpc.BlockNu
|
||||
return nil, err
|
||||
}
|
||||
additionalFields["totalDifficulty"] = (*hexutil.Big)(td)
|
||||
response, err := ethapi.RPCMarshalBlock(block, true, fullTx, additionalFields)
|
||||
|
||||
chainConfig, err := api.chainConfig(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var borTx types.Transaction
|
||||
var borTxHash common.Hash
|
||||
if chainConfig.Bor != nil {
|
||||
borTx, _, _, _ = rawdb.ReadBorTransactionForBlock(tx, block)
|
||||
if borTx != nil {
|
||||
borTxHash = types.ComputeBorTxHash(block.NumberU64(), block.Hash())
|
||||
}
|
||||
}
|
||||
|
||||
response, err := ethapi.RPCMarshalBlockEx(block, true, fullTx, borTx, borTxHash, additionalFields)
|
||||
|
||||
if err == nil && int64(number) == rpc.PendingBlockNumber.Int64() {
|
||||
// Pending blocks need to nil out a few fields
|
||||
|
@ -157,6 +157,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([
|
||||
|
||||
block := uint64(iter.Next())
|
||||
var logIndex uint
|
||||
var txIndex uint
|
||||
var blockLogs []*types.Log
|
||||
err := tx.ForPrefix(kv.Log, dbutils.EncodeBlockNumber(block), func(k, v []byte) error {
|
||||
var logs types.Logs
|
||||
@ -171,7 +172,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([
|
||||
if len(filtered) == 0 {
|
||||
return nil
|
||||
}
|
||||
txIndex := uint(binary.BigEndian.Uint32(k[8:]))
|
||||
txIndex = uint(binary.BigEndian.Uint32(k[8:]))
|
||||
for _, log := range filtered {
|
||||
log.TxIndex = txIndex
|
||||
}
|
||||
@ -200,6 +201,14 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([
|
||||
log.TxHash = b.Transactions()[log.TxIndex].Hash()
|
||||
}
|
||||
logs = append(logs, blockLogs...)
|
||||
|
||||
borLogs := rawdb.ReadBorReceiptLogs(tx, blockHash, block, txIndex+1, logIndex)
|
||||
if borLogs != nil {
|
||||
borLogs = filterLogs(borLogs, crit.Addresses, crit.Topics)
|
||||
if len(borLogs) > 0 {
|
||||
logs = append(logs, borLogs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return logs, nil
|
||||
@ -245,7 +254,7 @@ func getTopicsBitmap(c kv.Tx, topics [][]common.Hash, from, to uint32) (*roaring
|
||||
}
|
||||
|
||||
// GetTransactionReceipt implements eth_getTransactionReceipt. Returns the receipt of a transaction given the transaction's hash.
|
||||
func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
|
||||
func (api *APIImpl) GetTransactionReceipt(ctx context.Context, txnHash common.Hash) (map[string]interface{}, error) {
|
||||
tx, err := api.db.BeginRo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -255,7 +264,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash)
|
||||
var blockNum uint64
|
||||
var ok bool
|
||||
|
||||
blockNum, ok, err = api.txnLookup(ctx, tx, hash)
|
||||
blockNum, ok, err = api.txnLookup(ctx, tx, txnHash)
|
||||
if !ok || blockNum == 0 {
|
||||
// It is not an ideal solution (ideal solution requires extending TxnLookupReply proto type to include bool flag indicating absense of result),
|
||||
// but 0 block number is used here to mean that the transaction is not found
|
||||
@ -280,7 +289,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash)
|
||||
var txnIndex uint64
|
||||
var txn types.Transaction
|
||||
for idx, transaction := range block.Transactions() {
|
||||
if transaction.Hash() == hash {
|
||||
if transaction.Hash() == txnHash {
|
||||
txn = transaction
|
||||
txnIndex = uint64(idx)
|
||||
break
|
||||
@ -292,7 +301,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
borTx, blockHash, _, _, err := rawdb.ReadBorTransactionWithBlockNumber(tx, blockNum)
|
||||
borTx, blockHash, _, _, err := rawdb.ReadBorTransactionForBlockNumber(tx, blockNum)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -300,7 +309,10 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash)
|
||||
return nil, nil
|
||||
}
|
||||
borReceipt := rawdb.ReadBorReceipt(tx, blockHash, blockNum)
|
||||
return marshalReceipt(borReceipt, borTx, cc, block, hash), nil
|
||||
if borReceipt == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return marshalReceipt(borReceipt, borTx, cc, block, txnHash, false), nil
|
||||
}
|
||||
|
||||
receipts, err := api.getReceipts(ctx, tx, cc, block, block.Body().SendersFromTxs())
|
||||
@ -310,7 +322,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash)
|
||||
if len(receipts) <= int(txnIndex) {
|
||||
return nil, fmt.Errorf("block has less receipts than expected: %d <= %d, block: %d", len(receipts), int(txnIndex), blockNum)
|
||||
}
|
||||
return marshalReceipt(receipts[txnIndex], block.Transactions()[txnIndex], cc, block, hash), nil
|
||||
return marshalReceipt(receipts[txnIndex], block.Transactions()[txnIndex], cc, block, txnHash, true), nil
|
||||
}
|
||||
|
||||
// GetBlockReceipts - receipts for individual block
|
||||
@ -344,22 +356,15 @@ func (api *APIImpl) GetBlockReceipts(ctx context.Context, number rpc.BlockNumber
|
||||
result := make([]map[string]interface{}, 0, len(receipts))
|
||||
for _, receipt := range receipts {
|
||||
txn := block.Transactions()[receipt.TransactionIndex]
|
||||
result = append(result, marshalReceipt(receipt, txn, chainConfig, block, txn.Hash()))
|
||||
result = append(result, marshalReceipt(receipt, txn, chainConfig, block, txn.Hash(), true))
|
||||
}
|
||||
|
||||
if chainConfig.Bor != nil {
|
||||
borTx, _, _, _, err := rawdb.ReadBorTransactionWithBlockNumberAndHash(tx, blockNum, block.Hash())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
borTx, _, _, _ := rawdb.ReadBorTransactionForBlock(tx, block)
|
||||
if borTx != nil {
|
||||
borReceipt := rawdb.ReadBorReceipt(tx, block.Hash(), blockNum)
|
||||
borTx, err = borTx.WithHash(borReceipt.TxHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if borReceipt != nil {
|
||||
result = append(result, marshalReceipt(borReceipt, borTx, chainConfig, block, borReceipt.TxHash))
|
||||
result = append(result, marshalReceipt(borReceipt, borTx, chainConfig, block, borReceipt.TxHash, false))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -367,7 +372,7 @@ func (api *APIImpl) GetBlockReceipts(ctx context.Context, number rpc.BlockNumber
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig *params.ChainConfig, block *types.Block, hash common.Hash) map[string]interface{} {
|
||||
func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig *params.ChainConfig, block *types.Block, txnHash common.Hash, signed bool) map[string]interface{} {
|
||||
var chainId *big.Int
|
||||
switch t := txn.(type) {
|
||||
case *types.LegacyTx:
|
||||
@ -379,13 +384,17 @@ func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig *
|
||||
case *types.DynamicFeeTransaction:
|
||||
chainId = t.ChainID.ToBig()
|
||||
}
|
||||
signer := types.LatestSignerForChainID(chainId)
|
||||
from, _ := txn.Sender(*signer)
|
||||
|
||||
var from common.Address
|
||||
if signed {
|
||||
signer := types.LatestSignerForChainID(chainId)
|
||||
from, _ = txn.Sender(*signer)
|
||||
}
|
||||
|
||||
fields := map[string]interface{}{
|
||||
"blockHash": receipt.BlockHash,
|
||||
"blockNumber": hexutil.Uint64(receipt.BlockNumber.Uint64()),
|
||||
"transactionHash": hash,
|
||||
"transactionHash": txnHash,
|
||||
"transactionIndex": hexutil.Uint64(receipt.TransactionIndex),
|
||||
"from": from,
|
||||
"to": txn.GetTo(),
|
||||
|
@ -18,7 +18,7 @@ import (
|
||||
)
|
||||
|
||||
// GetTransactionByHash implements eth_getTransactionByHash. Returns information about a transaction given the transaction's hash.
|
||||
func (api *APIImpl) GetTransactionByHash(ctx context.Context, hash common.Hash) (*RPCTransaction, error) {
|
||||
func (api *APIImpl) GetTransactionByHash(ctx context.Context, txnHash common.Hash) (*RPCTransaction, error) {
|
||||
tx, err := api.db.BeginRo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -30,7 +30,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, hash common.Hash)
|
||||
}
|
||||
|
||||
// https://infura.io/docs/ethereum/json-rpc/eth-getTransactionByHash
|
||||
blockNum, ok, err := api.txnLookup(ctx, tx, hash)
|
||||
blockNum, ok, err := api.txnLookup(ctx, tx, txnHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -46,7 +46,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, hash common.Hash)
|
||||
var txnIndex uint64
|
||||
var txn types2.Transaction
|
||||
for i, transaction := range block.Transactions() {
|
||||
if transaction.Hash() == hash {
|
||||
if transaction.Hash() == txnHash {
|
||||
txn = transaction
|
||||
txnIndex = uint64(i)
|
||||
break
|
||||
@ -61,17 +61,14 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, hash common.Hash)
|
||||
|
||||
// if no transaction was found then we return nil
|
||||
if txn == nil {
|
||||
if chainConfig.Bor != nil {
|
||||
borTx, _, _, _, err := rawdb.ReadBorTransactionWithBlockNumberAndHash(tx, blockNum, block.Hash())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if borTx != nil {
|
||||
return newRPCTransaction(borTx, blockHash, blockNum, uint64(len(block.Transactions())), baseFee), nil
|
||||
}
|
||||
if chainConfig.Bor == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
borTx, _, _, _ := rawdb.ReadBorTransactionForBlock(tx, block)
|
||||
if borTx == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return newRPCBorTransaction(borTx, txnHash, blockHash, blockNum, uint64(len(block.Transactions())), baseFee), nil
|
||||
}
|
||||
|
||||
return newRPCTransaction(txn, blockHash, blockNum, txnIndex, baseFee), nil
|
||||
@ -83,7 +80,7 @@ func (api *APIImpl) GetTransactionByHash(ctx context.Context, hash common.Hash)
|
||||
}
|
||||
|
||||
// No finalized transaction, try to retrieve it from the pool
|
||||
reply, err := api.txPool.Transactions(ctx, &txpool.TransactionsRequest{Hashes: []*types.H256{gointerfaces.ConvertHashToH256(hash)}})
|
||||
reply, err := api.txPool.Transactions(ctx, &txpool.TransactionsRequest{Hashes: []*types.H256{gointerfaces.ConvertHashToH256(txnHash)}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -179,17 +176,15 @@ func (api *APIImpl) GetTransactionByBlockHashAndIndex(ctx context.Context, block
|
||||
if uint64(txIndex) > uint64(len(txs)) {
|
||||
return nil, nil // not error
|
||||
} else if uint64(txIndex) == uint64(len(txs)) {
|
||||
if chainConfig.Bor != nil {
|
||||
borTx, _, _, _, err := rawdb.ReadBorTransactionWithBlockNumberAndHash(tx, block.NumberU64(), block.Hash())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if borTx != nil {
|
||||
return newRPCTransaction(borTx, block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil
|
||||
}
|
||||
} else {
|
||||
if chainConfig.Bor == nil {
|
||||
return nil, nil // not error
|
||||
}
|
||||
borTx, _, _, _ := rawdb.ReadBorTransactionForBlock(tx, block)
|
||||
if borTx == nil {
|
||||
return nil, nil // not error
|
||||
}
|
||||
derivedBorTxHash := types2.ComputeBorTxHash(block.NumberU64(), block.Hash())
|
||||
return newRPCBorTransaction(borTx, derivedBorTxHash, block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil
|
||||
}
|
||||
|
||||
return newRPCTransaction(txs[txIndex], block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil
|
||||
@ -245,17 +240,15 @@ func (api *APIImpl) GetTransactionByBlockNumberAndIndex(ctx context.Context, blo
|
||||
if uint64(txIndex) > uint64(len(txs)) {
|
||||
return nil, nil // not error
|
||||
} else if uint64(txIndex) == uint64(len(txs)) {
|
||||
if chainConfig.Bor != nil {
|
||||
borTx, _, _, _, err := rawdb.ReadBorTransactionWithBlockNumberAndHash(tx, blockNum, block.Hash())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if borTx != nil {
|
||||
return newRPCTransaction(borTx, block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil
|
||||
}
|
||||
} else {
|
||||
if chainConfig.Bor == nil {
|
||||
return nil, nil // not error
|
||||
}
|
||||
borTx, _, _, _ := rawdb.ReadBorTransactionForBlock(tx, block)
|
||||
if borTx == nil {
|
||||
return nil, nil
|
||||
}
|
||||
derivedBorTxHash := types2.ComputeBorTxHash(block.NumberU64(), block.Hash())
|
||||
return newRPCBorTransaction(borTx, derivedBorTxHash, block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil
|
||||
}
|
||||
|
||||
return newRPCTransaction(txs[txIndex], block.Hash(), block.NumberU64(), uint64(txIndex), block.BaseFee()), nil
|
||||
|
@ -305,7 +305,7 @@ func (api *APIImpl) GetTransactionReceipt(ctx context.Context, hash common.Hash)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
borTx, blockHash, _, _, err := rawdb.ReadBorTransactionWithBlockNumber(tx, blockNum)
|
||||
borTx, blockHash, _, _, err := rawdb.ReadBorTransactionForBlockNumber(tx, blockNum)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ var (
|
||||
|
||||
// HasBorReceipt verifies the existence of all block receipt belonging
|
||||
// to a block.
|
||||
func HasBorReceipts(db kv.Has, hash common.Hash, number uint64) bool {
|
||||
func HasBorReceipts(db kv.Has, number uint64) bool {
|
||||
if has, err := db.Has(kv.BorReceipts, borReceiptKey(number)); !has || err != nil {
|
||||
return false
|
||||
}
|
||||
@ -70,12 +70,6 @@ func ReadBorReceipt(db kv.Tx, hash common.Hash, number uint64) *types.Receipt {
|
||||
receipts = make(types.Receipts, 0)
|
||||
}
|
||||
|
||||
data := ReadStorageBodyRLP(db, hash, number)
|
||||
if len(data) == 0 {
|
||||
log.Error("Missing body but have bor receipt", "hash", hash, "number", number)
|
||||
return 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
|
||||
@ -83,6 +77,22 @@ func ReadBorReceipt(db kv.Tx, hash common.Hash, number uint64) *types.Receipt {
|
||||
return borReceipt
|
||||
}
|
||||
|
||||
// ReadBorReceiptLogs retrieves all the bor block receipt logs belonging to a block.
|
||||
// If it is unable to populate these metadata fields then nil is returned.
|
||||
func ReadBorReceiptLogs(db kv.Tx, blockHash common.Hash, blockNumber uint64, txIndex uint, logIndex uint) []*types.Log {
|
||||
// We're deriving many fields from the block body, retrieve beside the receipt
|
||||
borReceipt := ReadRawBorReceipt(db, blockHash, blockNumber)
|
||||
if borReceipt == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
borLogs := borReceipt.Logs
|
||||
|
||||
types.DeriveFieldsForBorLogs(borLogs, blockHash, blockNumber, txIndex, logIndex)
|
||||
|
||||
return borLogs
|
||||
}
|
||||
|
||||
// WriteBorReceipt stores all the bor receipt belonging to a block.
|
||||
func WriteBorReceipt(tx kv.RwTx, hash common.Hash, number uint64, borReceipt *types.ReceiptForStorage) error {
|
||||
// Convert the bor receipt into their storage form and serialize them
|
||||
@ -130,7 +140,7 @@ func ReadBorTransactionWithBlockHash(db kv.Tx, borTxHash common.Hash, blockHash
|
||||
}
|
||||
*/
|
||||
|
||||
// ReadBorTransaction retrieves a specific bor (fake) transaction by hash, along with
|
||||
// ReadBorTransaction returns a specific bor (fake) transaction by txn hash, along with
|
||||
// its added positional metadata.
|
||||
func ReadBorTransaction(db kv.Tx, borTxHash common.Hash) (types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
blockNumber, err := ReadTxLookupEntry(db, borTxHash)
|
||||
@ -141,12 +151,19 @@ func ReadBorTransaction(db kv.Tx, borTxHash common.Hash) (types.Transaction, com
|
||||
return nil, common.Hash{}, 0, 0, errors.New("missing block number")
|
||||
}
|
||||
|
||||
return ReadBorTransactionWithBlockNumber(db, *blockNumber)
|
||||
return computeBorTransactionForBlockNumber(db, *blockNumber)
|
||||
}
|
||||
|
||||
// ReadBorTransaction retrieves a specific bor (fake) transaction by block number, along with
|
||||
// ReadBorTransactionForBlockNumber returns a bor (fake) transaction by block number, along with
|
||||
// its added positional metadata.
|
||||
func ReadBorTransactionWithBlockNumber(db kv.Tx, blockNumber uint64) (types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
func ReadBorTransactionForBlockNumber(db kv.Tx, blockNumber uint64) (types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
if !HasBorReceipts(db, blockNumber) {
|
||||
return nil, common.Hash{}, 0, 0, nil
|
||||
}
|
||||
return computeBorTransactionForBlockNumber(db, blockNumber)
|
||||
}
|
||||
|
||||
func computeBorTransactionForBlockNumber(db kv.Tx, blockNumber uint64) (types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
blockHash, err := ReadCanonicalHash(db, blockNumber)
|
||||
if err != nil {
|
||||
return nil, common.Hash{}, 0, 0, err
|
||||
@ -155,12 +172,19 @@ func ReadBorTransactionWithBlockNumber(db kv.Tx, blockNumber uint64) (types.Tran
|
||||
return nil, common.Hash{}, 0, 0, errors.New("missing block hash")
|
||||
}
|
||||
|
||||
return ReadBorTransactionWithBlockNumberAndHash(db, blockNumber, blockHash)
|
||||
return computeBorTransactionForBlockNumberAndHash(db, blockNumber, blockHash)
|
||||
}
|
||||
|
||||
// ReadBorTransactionWithBlockNumberAndHash retrieves a specific bor (fake) transaction by block number and block hash, along with
|
||||
// ReadBorTransactionForBlockNumberAndHash returns a bor (fake) transaction by block number and block hash, along with
|
||||
// its added positional metadata.
|
||||
func ReadBorTransactionWithBlockNumberAndHash(db kv.Tx, blockNumber uint64, blockHash common.Hash) (types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
func ReadBorTransactionForBlockNumberAndHash(db kv.Tx, blockNumber uint64, blockHash common.Hash) (types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
if !HasBorReceipts(db, blockNumber) {
|
||||
return nil, common.Hash{}, 0, 0, nil
|
||||
}
|
||||
return computeBorTransactionForBlockNumberAndHash(db, blockNumber, blockHash)
|
||||
}
|
||||
|
||||
func computeBorTransactionForBlockNumberAndHash(db kv.Tx, blockNumber uint64, blockHash common.Hash) (types.Transaction, common.Hash, uint64, uint64, error) {
|
||||
bodyForStorage, err := ReadStorageBody(db, blockHash, blockNumber)
|
||||
if err != nil {
|
||||
return nil, common.Hash{}, 0, 0, err
|
||||
@ -170,6 +194,20 @@ func ReadBorTransactionWithBlockNumberAndHash(db kv.Tx, blockNumber uint64, bloc
|
||||
return tx, blockHash, blockNumber, uint64(bodyForStorage.TxAmount), nil
|
||||
}
|
||||
|
||||
// ReadBorTransactionForBlock retrieves a specific bor (fake) transaction associated with a block, along with
|
||||
// its added positional metadata.
|
||||
func ReadBorTransactionForBlock(db kv.Tx, block *types.Block) (types.Transaction, common.Hash, uint64, uint64) {
|
||||
if !HasBorReceipts(db, block.NumberU64()) {
|
||||
return nil, common.Hash{}, 0, 0
|
||||
}
|
||||
return computeBorTransactionForBlock(db, block)
|
||||
}
|
||||
|
||||
func computeBorTransactionForBlock(db kv.Tx, block *types.Block) (types.Transaction, common.Hash, uint64, uint64) {
|
||||
var tx types.Transaction = types.NewBorTransaction()
|
||||
return tx, block.Hash(), block.NumberU64(), uint64(len(block.Transactions()))
|
||||
}
|
||||
|
||||
// TruncateBorReceipts removes all bor receipt for given block number or newer
|
||||
func TruncateBorReceipts(db kv.RwTx, number uint64) error {
|
||||
if err := db.ForEach(kv.BorReceipts, dbutils.EncodeBlockNumber(number), func(k, _ []byte) error {
|
||||
|
@ -566,10 +566,6 @@ func (tx *AccessListTx) FakeSign(address common.Address) (Transaction, error) {
|
||||
return cpy, nil
|
||||
}
|
||||
|
||||
func (tx *AccessListTx) WithHash(newHash common.Hash) (Transaction, error) {
|
||||
return nil, errors.New("hash is immutable for AccessListTx")
|
||||
}
|
||||
|
||||
// Hash computes the hash (but not for signatures!)
|
||||
func (tx *AccessListTx) Hash() common.Hash {
|
||||
if hash := tx.hash.Load(); hash != nil {
|
||||
|
@ -10,24 +10,20 @@ import (
|
||||
"github.com/ledgerwatch/erigon/crypto"
|
||||
)
|
||||
|
||||
// TenToTheFive - To be used while sorting bor logs
|
||||
//
|
||||
// Sorted using ( blockNumber * (10 ** 5) + logIndex )
|
||||
const TenToTheFive uint64 = 100000
|
||||
|
||||
var (
|
||||
// SystemAddress address for system sender
|
||||
SystemAddress = common.HexToAddress("0xffffFFFfFFffffffffffffffFfFFFfffFFFfFFfE")
|
||||
)
|
||||
const BorTxKeyPrefix string = "matic-bor-receipt-"
|
||||
|
||||
// BorReceiptKey = num (uint64 big endian)
|
||||
func BorReceiptKey(number uint64) []byte {
|
||||
return dbutils.EncodeBlockNumber(number)
|
||||
}
|
||||
|
||||
// GetDerivedBorTxHash get derived tx hash from receipt key
|
||||
func GetDerivedBorTxHash(receiptKey []byte) common.Hash {
|
||||
return common.BytesToHash(crypto.Keccak256(receiptKey))
|
||||
// ComputeBorTxHash get derived tx hash from block number and hash
|
||||
func ComputeBorTxHash(blockNumber uint64, blockHash common.Hash) common.Hash {
|
||||
txKeyPlain := make([]byte, 0, len(BorTxKeyPrefix)+8+32)
|
||||
txKeyPlain = append(txKeyPlain, BorTxKeyPrefix...)
|
||||
txKeyPlain = append(txKeyPlain, BorReceiptKey(blockNumber)...)
|
||||
txKeyPlain = append(txKeyPlain, blockHash.Bytes()...)
|
||||
return common.BytesToHash(crypto.Keccak256(txKeyPlain))
|
||||
}
|
||||
|
||||
// NewBorTransaction create new bor transaction for bor receipt
|
||||
@ -37,18 +33,15 @@ func NewBorTransaction() *LegacyTx {
|
||||
|
||||
// DeriveFieldsForBorReceipt fills the receipts with their computed fields based on consensus
|
||||
// data and contextual infos like containing block and transactions.
|
||||
func DeriveFieldsForBorReceipt(receipt *Receipt, hash common.Hash, number uint64, receipts Receipts) error {
|
||||
// get derived tx hash
|
||||
borPrefix := []byte("matic-bor-receipt-")
|
||||
// hashing using prefix + number + hash
|
||||
txHash := GetDerivedBorTxHash((append(borPrefix, append(BorReceiptKey(number), hash.Bytes()...)...)))
|
||||
func DeriveFieldsForBorReceipt(receipt *Receipt, blockHash common.Hash, blockNumber uint64, receipts Receipts) error {
|
||||
txHash := ComputeBorTxHash(blockNumber, blockHash)
|
||||
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)
|
||||
receipt.BlockHash = blockHash
|
||||
receipt.BlockNumber = big.NewInt(0).SetUint64(blockNumber)
|
||||
|
||||
logIndex := 0
|
||||
for i := 0; i < len(receipts); i++ {
|
||||
@ -57,8 +50,8 @@ func DeriveFieldsForBorReceipt(receipt *Receipt, hash common.Hash, number uint64
|
||||
|
||||
// The derived log fields can simply be set from the block and transaction
|
||||
for j := 0; j < len(receipt.Logs); j++ {
|
||||
receipt.Logs[j].BlockNumber = number
|
||||
receipt.Logs[j].BlockHash = hash
|
||||
receipt.Logs[j].BlockNumber = blockNumber
|
||||
receipt.Logs[j].BlockHash = blockHash
|
||||
receipt.Logs[j].TxHash = txHash
|
||||
receipt.Logs[j].TxIndex = txIndex
|
||||
receipt.Logs[j].Index = uint(logIndex)
|
||||
@ -69,14 +62,13 @@ func DeriveFieldsForBorReceipt(receipt *Receipt, hash common.Hash, number uint64
|
||||
|
||||
// DeriveFieldsForBorLogs fills the receipts with their computed fields based on consensus
|
||||
// data and contextual infos like containing block and transactions.
|
||||
func DeriveFieldsForBorLogs(logs []*Log, hash common.Hash, number uint64, txIndex uint, logIndex uint) {
|
||||
// get derived tx hash
|
||||
txHash := GetDerivedBorTxHash(BorReceiptKey(number))
|
||||
func DeriveFieldsForBorLogs(logs []*Log, blockHash common.Hash, blockNumber uint64, txIndex uint, logIndex uint) {
|
||||
txHash := ComputeBorTxHash(blockNumber, blockHash)
|
||||
|
||||
// the derived log fields can simply be set from the block and transaction
|
||||
for j := 0; j < len(logs); j++ {
|
||||
logs[j].BlockNumber = number
|
||||
logs[j].BlockHash = hash
|
||||
logs[j].BlockNumber = blockNumber
|
||||
logs[j].BlockHash = blockHash
|
||||
logs[j].TxHash = txHash
|
||||
logs[j].TxIndex = txIndex
|
||||
logs[j].Index = logIndex
|
||||
|
@ -463,10 +463,6 @@ func (tx DynamicFeeTransaction) AsMessage(s Signer, baseFee *big.Int, rules *par
|
||||
return msg, err
|
||||
}
|
||||
|
||||
func (tx *DynamicFeeTransaction) WithHash(newHash common.Hash) (Transaction, error) {
|
||||
return nil, errors.New("hash is immutable for DynamicFeeTransaction")
|
||||
}
|
||||
|
||||
// Hash computes the hash (but not for signatures!)
|
||||
func (tx *DynamicFeeTransaction) Hash() common.Hash {
|
||||
if hash := tx.hash.Load(); hash != nil {
|
||||
|
@ -482,12 +482,6 @@ func (tx *LegacyTx) FakeSign(address common.Address) (Transaction, error) {
|
||||
return cpy, nil
|
||||
}
|
||||
|
||||
func (tx *LegacyTx) WithHash(hash common.Hash) (Transaction, error) {
|
||||
cpy := tx.copy()
|
||||
cpy.hash.Store(&hash)
|
||||
return cpy, nil
|
||||
}
|
||||
|
||||
// Hash computes the hash (but not for signatures!)
|
||||
func (tx *LegacyTx) Hash() common.Hash {
|
||||
if hash := tx.hash.Load(); hash != nil {
|
||||
|
@ -170,10 +170,6 @@ func (tx StarknetTransaction) FakeSign(address common.Address) (Transaction, err
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (tx *StarknetTransaction) WithHash(newHash common.Hash) (Transaction, error) {
|
||||
return nil, errors.New("hash is immutable for StarknetTransaction")
|
||||
}
|
||||
|
||||
func (tx StarknetTransaction) Hash() common.Hash {
|
||||
if hash := tx.hash.Load(); hash != nil {
|
||||
return *hash.(*common.Hash)
|
||||
|
@ -65,7 +65,6 @@ type Transaction interface {
|
||||
AsMessage(s Signer, baseFee *big.Int, rules *params.Rules) (Message, error)
|
||||
WithSignature(signer Signer, sig []byte) (Transaction, error)
|
||||
FakeSign(address common.Address) (Transaction, error)
|
||||
WithHash(newHash common.Hash) (Transaction, error)
|
||||
Hash() common.Hash
|
||||
SigningHash(chainID *big.Int) common.Hash
|
||||
Size() common.StorageSize
|
||||
|
@ -283,10 +283,10 @@ func RPCMarshalHeader(head *types.Header) map[string]interface{} {
|
||||
// returned. When fullTx is true the returned block contains full transaction details, otherwise it will only contain
|
||||
// transaction hashes.
|
||||
func RPCMarshalBlock(block *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) {
|
||||
return RPCMarshalBlockEx(block, inclTx, fullTx, nil, nil)
|
||||
return RPCMarshalBlockEx(block, inclTx, fullTx, nil, common.Hash{})
|
||||
}
|
||||
|
||||
func RPCMarshalBlockEx(block *types.Block, inclTx bool, fullTx bool, borTx types.Transaction, borTxReceipt *types.Receipt) (map[string]interface{}, error) {
|
||||
func RPCMarshalBlockEx(block *types.Block, inclTx bool, fullTx bool, borTx types.Transaction, borTxHash common.Hash) (map[string]interface{}, error) {
|
||||
fields := RPCMarshalHeader(block.Header())
|
||||
fields["size"] = hexutil.Uint64(block.Size())
|
||||
|
||||
@ -308,11 +308,11 @@ func RPCMarshalBlockEx(block *types.Block, inclTx bool, fullTx bool, borTx types
|
||||
}
|
||||
}
|
||||
|
||||
if borTx != nil && borTxReceipt != nil {
|
||||
if borTx != nil {
|
||||
if fullTx {
|
||||
transactions = append(transactions, newRPCTransactionFromBlockAndTxGivenIndex(block, borTx, uint64(len(txs))))
|
||||
transactions = append(transactions, newRPCBorTransaction(borTx, borTxHash, block.Hash(), block.NumberU64(), uint64(len(txs)), block.BaseFee()))
|
||||
} else {
|
||||
transactions = append(transactions, borTxReceipt.TxHash)
|
||||
transactions = append(transactions, borTxHash)
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,6 +444,30 @@ func newRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber
|
||||
return result
|
||||
}
|
||||
|
||||
// newRPCBorTransaction returns a Bor transaction that will serialize to the RPC
|
||||
// representation, with the given location metadata set (if available).
|
||||
func newRPCBorTransaction(opaqueTx types.Transaction, txHash common.Hash, blockHash common.Hash, blockNumber uint64, index uint64, baseFee *big.Int) *RPCTransaction {
|
||||
tx := opaqueTx.(*types.LegacyTx)
|
||||
result := &RPCTransaction{
|
||||
Type: hexutil.Uint64(tx.Type()),
|
||||
ChainID: (*hexutil.Big)(new(big.Int)),
|
||||
GasPrice: (*hexutil.Big)(tx.GasPrice.ToBig()),
|
||||
Gas: hexutil.Uint64(tx.GetGas()),
|
||||
Hash: txHash,
|
||||
Input: hexutil.Bytes(tx.GetData()),
|
||||
Nonce: hexutil.Uint64(tx.GetNonce()),
|
||||
From: common.Address{},
|
||||
To: tx.GetTo(),
|
||||
Value: (*hexutil.Big)(tx.GetValue().ToBig()),
|
||||
}
|
||||
if blockHash != (common.Hash{}) {
|
||||
result.BlockHash = &blockHash
|
||||
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
|
||||
result.TransactionIndex = (*hexutil.Uint64)(&index)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/*
|
||||
// newRPCPendingTransaction returns a pending transaction that will serialize to the RPC representation
|
||||
func newRPCPendingTransaction(tx types.Transaction) *RPCTransaction {
|
||||
|
@ -2,6 +2,7 @@ package ethapi
|
||||
|
||||
// This file stores proxy-objects for `internal` package
|
||||
import (
|
||||
"github.com/ledgerwatch/erigon/common"
|
||||
"github.com/ledgerwatch/erigon/core"
|
||||
"github.com/ledgerwatch/erigon/core/types"
|
||||
"github.com/ledgerwatch/erigon/internal/ethapi"
|
||||
@ -45,8 +46,8 @@ func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool, additional map[st
|
||||
}
|
||||
|
||||
//nolint
|
||||
func RPCMarshalBlockEx(b *types.Block, inclTx bool, fullTx bool, borTx types.Transaction, borReceipt *types.Receipt, additional map[string]interface{}) (map[string]interface{}, error) {
|
||||
fields, err := ethapi.RPCMarshalBlockEx(b, inclTx, fullTx, borTx, borReceipt)
|
||||
func RPCMarshalBlockEx(b *types.Block, inclTx bool, fullTx bool, borTx types.Transaction, borTxHash common.Hash, additional map[string]interface{}) (map[string]interface{}, error) {
|
||||
fields, err := ethapi.RPCMarshalBlockEx(b, inclTx, fullTx, borTx, borTxHash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user