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:
Levi Aul 2022-07-08 20:15:22 -07:00 committed by GitHub
parent 63f6eab6c7
commit 8de866028a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 201 additions and 134 deletions

View File

@ -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

View File

@ -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

View File

@ -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(),

View File

@ -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

View File

@ -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
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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

View File

@ -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 {

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -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
}