mirror of
https://gitlab.com/pulsechaincom/erigon-pulse.git
synced 2024-12-22 03:30:37 +00:00
eip-4844: RPCTransactions to support BlobTx (#7407)
Small additions to support eip-4844 transaction marshalling
This commit is contained in:
parent
f31d2b097d
commit
726ce264ef
@ -343,25 +343,27 @@ func NewEthAPI(base *BaseAPI, db kv.RoDB, eth rpchelper.ApiBackend, txPool txpoo
|
||||
|
||||
// RPCTransaction represents a transaction that will serialize to the RPC representation of a transaction
|
||||
type RPCTransaction struct {
|
||||
BlockHash *common.Hash `json:"blockHash"`
|
||||
BlockNumber *hexutil.Big `json:"blockNumber"`
|
||||
From common.Address `json:"from"`
|
||||
Gas hexutil.Uint64 `json:"gas"`
|
||||
GasPrice *hexutil.Big `json:"gasPrice,omitempty"`
|
||||
Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
|
||||
FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
|
||||
Hash common.Hash `json:"hash"`
|
||||
Input hexutility.Bytes `json:"input"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
To *common.Address `json:"to"`
|
||||
TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
|
||||
Value *hexutil.Big `json:"value"`
|
||||
Type hexutil.Uint64 `json:"type"`
|
||||
Accesses *types2.AccessList `json:"accessList,omitempty"`
|
||||
ChainID *hexutil.Big `json:"chainId,omitempty"`
|
||||
V *hexutil.Big `json:"v"`
|
||||
R *hexutil.Big `json:"r"`
|
||||
S *hexutil.Big `json:"s"`
|
||||
BlockHash *common.Hash `json:"blockHash"`
|
||||
BlockNumber *hexutil.Big `json:"blockNumber"`
|
||||
From common.Address `json:"from"`
|
||||
Gas hexutil.Uint64 `json:"gas"`
|
||||
GasPrice *hexutil.Big `json:"gasPrice,omitempty"`
|
||||
Tip *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"`
|
||||
FeeCap *hexutil.Big `json:"maxFeePerGas,omitempty"`
|
||||
Hash common.Hash `json:"hash"`
|
||||
Input hexutility.Bytes `json:"input"`
|
||||
Nonce hexutil.Uint64 `json:"nonce"`
|
||||
To *common.Address `json:"to"`
|
||||
TransactionIndex *hexutil.Uint64 `json:"transactionIndex"`
|
||||
Value *hexutil.Big `json:"value"`
|
||||
Type hexutil.Uint64 `json:"type"`
|
||||
Accesses *types2.AccessList `json:"accessList,omitempty"`
|
||||
ChainID *hexutil.Big `json:"chainId,omitempty"`
|
||||
MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas,omitempty"`
|
||||
BlobVersionedHashes []common.Hash `json:"blobVersionedHashes,omitempty"`
|
||||
V *hexutil.Big `json:"v"`
|
||||
R *hexutil.Big `json:"r"`
|
||||
S *hexutil.Big `json:"s"`
|
||||
}
|
||||
|
||||
// newRPCTransaction returns a transaction that will serialize to the RPC
|
||||
@ -409,14 +411,17 @@ func newRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber
|
||||
result.R = (*hexutil.Big)(t.R.ToBig())
|
||||
result.S = (*hexutil.Big)(t.S.ToBig())
|
||||
result.Accesses = &t.AccessList
|
||||
baseFee, overflow := uint256.FromBig(baseFee)
|
||||
if baseFee != nil && !overflow && blockHash != (common.Hash{}) {
|
||||
// price = min(tip + baseFee, gasFeeCap)
|
||||
price := math.Min256(new(uint256.Int).Add(tx.GetTip(), baseFee), tx.GetFeeCap())
|
||||
result.GasPrice = (*hexutil.Big)(price.ToBig())
|
||||
} else {
|
||||
result.GasPrice = nil
|
||||
}
|
||||
result.GasPrice = computeGasPrice(tx, blockHash, baseFee)
|
||||
case *types.SignedBlobTx:
|
||||
result.Tip = (*hexutil.Big)(t.GetTip().ToBig())
|
||||
result.FeeCap = (*hexutil.Big)(t.GetFeeCap().ToBig())
|
||||
result.MaxFeePerDataGas = (*hexutil.Big)(t.GetMaxFeePerDataGas().ToBig())
|
||||
result.V = (*hexutil.Big)(t.Signature.GetV().ToBig())
|
||||
result.R = (*hexutil.Big)(t.Signature.GetR().ToBig())
|
||||
result.S = (*hexutil.Big)(t.Signature.GetS().ToBig())
|
||||
al := t.GetAccessList()
|
||||
result.Accesses = &al
|
||||
result.GasPrice = computeGasPrice(tx, blockHash, baseFee)
|
||||
}
|
||||
signer := types.LatestSignerForChainID(chainId.ToBig())
|
||||
result.From, _ = tx.Sender(*signer)
|
||||
@ -428,6 +433,16 @@ func newRPCTransaction(tx types.Transaction, blockHash common.Hash, blockNumber
|
||||
return result
|
||||
}
|
||||
|
||||
func computeGasPrice(tx types.Transaction, blockHash common.Hash, baseFee *big.Int) *hexutil.Big {
|
||||
fee, overflow := uint256.FromBig(baseFee)
|
||||
if fee != nil && !overflow && blockHash != (common.Hash{}) {
|
||||
// price = min(tip + baseFee, gasFeeCap)
|
||||
price := math.Min256(new(uint256.Int).Add(tx.GetTip(), fee), tx.GetFeeCap())
|
||||
return (*hexutil.Big)(price.ToBig())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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, chainId *big.Int) *RPCTransaction {
|
||||
|
@ -743,6 +743,8 @@ func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig *
|
||||
chainId = t.ChainID.ToBig()
|
||||
case *types.DynamicFeeTransaction:
|
||||
chainId = t.ChainID.ToBig()
|
||||
// case *types.SignedBlobTx: // TODO: needs eip-4844 signer
|
||||
// chainId = t.GetChainID().ToBig()
|
||||
}
|
||||
|
||||
var from common.Address
|
||||
|
@ -316,22 +316,22 @@ func toProofs(_proofs KZGProofs) []gokzg4844.KZGProof {
|
||||
// BlobTxWrapper is the "network representation" of a Blob transaction, that is it includes not
|
||||
// only the SignedBlobTx but also all the associated blob data.
|
||||
type BlobTxWrapper struct {
|
||||
Tx SignedBlobTx
|
||||
BlobKzgs BlobKzgs
|
||||
Blobs Blobs
|
||||
Proofs KZGProofs
|
||||
Tx SignedBlobTx
|
||||
Commitments BlobKzgs
|
||||
Blobs Blobs
|
||||
Proofs KZGProofs
|
||||
}
|
||||
|
||||
func (txw *BlobTxWrapper) Deserialize(dr *codec.DecodingReader) error {
|
||||
return dr.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)
|
||||
return dr.Container(&txw.Tx, &txw.Commitments, &txw.Blobs, &txw.Proofs)
|
||||
}
|
||||
|
||||
func (txw *BlobTxWrapper) Serialize(w *codec.EncodingWriter) error {
|
||||
return w.Container(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)
|
||||
return w.Container(&txw.Tx, &txw.Commitments, &txw.Blobs, &txw.Proofs)
|
||||
}
|
||||
|
||||
func (txw *BlobTxWrapper) ByteLength() uint64 {
|
||||
return codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs)
|
||||
return codec.ContainerLength(&txw.Tx, &txw.Commitments, &txw.Blobs, &txw.Proofs)
|
||||
}
|
||||
|
||||
func (txw *BlobTxWrapper) FixedLength() uint64 {
|
||||
@ -345,7 +345,7 @@ func (txw *BlobTxWrapper) ValidateBlobTransactionWrapper() error {
|
||||
if l1 == 0 {
|
||||
return fmt.Errorf("a blob tx must contain at least one blob")
|
||||
}
|
||||
l2 := len(txw.BlobKzgs)
|
||||
l2 := len(txw.Commitments)
|
||||
l3 := len(txw.Blobs)
|
||||
l4 := len(txw.Proofs)
|
||||
if l1 != l2 || l2 != l3 || l1 != l4 {
|
||||
@ -358,12 +358,12 @@ func (txw *BlobTxWrapper) ValidateBlobTransactionWrapper() error {
|
||||
return fmt.Errorf("number of blobs exceeds max: %v", l1)
|
||||
}
|
||||
cryptoCtx := kzg.CrpytoCtx()
|
||||
err := cryptoCtx.VerifyBlobKZGProofBatch(toBlobs(txw.Blobs), toComms(txw.BlobKzgs), toProofs(txw.Proofs))
|
||||
err := cryptoCtx.VerifyBlobKZGProofBatch(toBlobs(txw.Blobs), toComms(txw.Commitments), toProofs(txw.Proofs))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error during proof verification: %v", err)
|
||||
}
|
||||
for i, h := range blobTx.BlobVersionedHashes {
|
||||
if computed := txw.BlobKzgs[i].ComputeVersionedHash(); computed != h {
|
||||
if computed := txw.Commitments[i].ComputeVersionedHash(); computed != h {
|
||||
return fmt.Errorf("versioned hash %d supposedly %s but does not match computed %s", i, h, computed)
|
||||
}
|
||||
}
|
||||
@ -413,7 +413,7 @@ func (txw *BlobTxWrapper) IsContractDeploy() bool { return t
|
||||
func (txw *BlobTxWrapper) Unwrap() Transaction { return &txw.Tx }
|
||||
|
||||
func (txw BlobTxWrapper) EncodingSize() int {
|
||||
envelopeSize := int(codec.ContainerLength(&txw.Tx, &txw.BlobKzgs, &txw.Blobs, &txw.Proofs))
|
||||
envelopeSize := int(codec.ContainerLength(&txw.Tx, &txw.Commitments, &txw.Blobs, &txw.Proofs))
|
||||
// Add type byte
|
||||
envelopeSize++
|
||||
return envelopeSize
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
. "github.com/protolambda/ztyp/view"
|
||||
"github.com/valyala/fastjson"
|
||||
|
||||
libcommon "github.com/ledgerwatch/erigon-lib/common"
|
||||
@ -36,6 +37,14 @@ type txJSON struct {
|
||||
ChainID *hexutil.Big `json:"chainId,omitempty"`
|
||||
AccessList *types2.AccessList `json:"accessList,omitempty"`
|
||||
|
||||
// Blob transaction fields:
|
||||
MaxFeePerDataGas *hexutil.Big `json:"maxFeePerDataGas,omitempty"`
|
||||
BlobVersionedHashes []libcommon.Hash `json:"blobVersionedHashes,omitempty"`
|
||||
// Blob wrapper fields:
|
||||
Blobs Blobs `json:"blobs,omitempty"`
|
||||
Commitments BlobKzgs `json:"commitments,omitempty"`
|
||||
Proofs KZGProofs `json:"proofs,omitempty"`
|
||||
|
||||
// Only used for encoding:
|
||||
Hash libcommon.Hash `json:"hash"`
|
||||
}
|
||||
@ -96,6 +105,45 @@ func (tx DynamicFeeTransaction) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(&enc)
|
||||
}
|
||||
|
||||
func toSignedBlobTxJSON(tx *SignedBlobTx) *txJSON {
|
||||
var enc txJSON
|
||||
// These are set for all tx types.
|
||||
enc.Hash = tx.Hash()
|
||||
enc.Type = hexutil.Uint64(tx.Type())
|
||||
enc.ChainID = (*hexutil.Big)(tx.GetChainID().ToBig())
|
||||
accessList := tx.GetAccessList()
|
||||
enc.AccessList = &accessList
|
||||
nonce := tx.GetNonce()
|
||||
enc.Nonce = (*hexutil.Uint64)(&nonce)
|
||||
gas := tx.GetGas()
|
||||
enc.Gas = (*hexutil.Uint64)(&gas)
|
||||
enc.FeeCap = (*hexutil.Big)(tx.GetFeeCap().ToBig())
|
||||
enc.Tip = (*hexutil.Big)(tx.GetTip().ToBig())
|
||||
enc.Value = (*hexutil.Big)(tx.GetValue().ToBig())
|
||||
enc.Data = (*hexutility.Bytes)(&tx.Message.Data)
|
||||
enc.To = tx.GetTo()
|
||||
enc.V = (*hexutil.Big)(tx.Signature.GetV().ToBig())
|
||||
enc.R = (*hexutil.Big)(tx.Signature.GetR().ToBig())
|
||||
enc.S = (*hexutil.Big)(tx.Signature.GetS().ToBig())
|
||||
enc.MaxFeePerDataGas = (*hexutil.Big)(tx.GetMaxFeePerDataGas().ToBig())
|
||||
enc.BlobVersionedHashes = tx.GetDataHashes()
|
||||
return &enc
|
||||
}
|
||||
|
||||
func (tx SignedBlobTx) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(toSignedBlobTxJSON(&tx))
|
||||
}
|
||||
|
||||
func (tx BlobTxWrapper) MarshalJSON() ([]byte, error) {
|
||||
enc := toSignedBlobTxJSON(&tx.Tx)
|
||||
|
||||
enc.Blobs = tx.Blobs
|
||||
enc.Commitments = tx.Commitments
|
||||
enc.Proofs = tx.Proofs
|
||||
|
||||
return json.Marshal(enc)
|
||||
}
|
||||
|
||||
func UnmarshalTransactionFromJSON(input []byte) (Transaction, error) {
|
||||
var p fastjson.Parser
|
||||
v, err := p.ParseBytes(input)
|
||||
@ -129,6 +177,12 @@ func UnmarshalTransactionFromJSON(input []byte) (Transaction, error) {
|
||||
return nil, err
|
||||
}
|
||||
return tx, nil
|
||||
case BlobTxType:
|
||||
tx, err := UnmarshalBlobTxJSON(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tx, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown transaction type: %v", txType)
|
||||
}
|
||||
@ -360,3 +414,131 @@ func (tx *DynamicFeeTransaction) UnmarshalJSON(input []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func UnmarshalBlobTxJSON(input []byte) (Transaction, error) {
|
||||
var dec txJSON
|
||||
if err := json.Unmarshal(input, &dec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tx := SignedBlobTx{}
|
||||
if dec.AccessList != nil {
|
||||
tx.Message.AccessList = AccessListView(*dec.AccessList)
|
||||
} else {
|
||||
tx.Message.AccessList = AccessListView([]types2.AccessTuple{})
|
||||
}
|
||||
if dec.ChainID == nil {
|
||||
return nil, errors.New("missing required field 'chainId' in transaction")
|
||||
}
|
||||
chainID, overflow := uint256.FromBig(dec.ChainID.ToInt())
|
||||
if overflow {
|
||||
return nil, errors.New("'chainId' in transaction does not fit in 256 bits")
|
||||
}
|
||||
tx.Message.ChainID = Uint256View(*chainID)
|
||||
if dec.To != nil {
|
||||
address := AddressSSZ(*dec.To)
|
||||
tx.Message.To = AddressOptionalSSZ{Address: &address}
|
||||
}
|
||||
if dec.Nonce == nil {
|
||||
return nil, errors.New("missing required field 'nonce' in transaction")
|
||||
}
|
||||
tx.Message.Nonce = Uint64View(uint64(*dec.Nonce))
|
||||
tip, overflow := uint256.FromBig(dec.Tip.ToInt())
|
||||
if overflow {
|
||||
return nil, errors.New("'tip' in transaction does not fit in 256 bits")
|
||||
}
|
||||
tx.Message.GasTipCap = Uint256View(*tip)
|
||||
feeCap, overflow := uint256.FromBig(dec.FeeCap.ToInt())
|
||||
if overflow {
|
||||
return nil, errors.New("'feeCap' in transaction does not fit in 256 bits")
|
||||
}
|
||||
tx.Message.GasFeeCap = Uint256View(*feeCap)
|
||||
if dec.Gas == nil {
|
||||
return nil, errors.New("missing required field 'gas' in transaction")
|
||||
}
|
||||
tx.Message.Gas = Uint64View(uint64(*dec.Gas))
|
||||
if dec.Value == nil {
|
||||
return nil, errors.New("missing required field 'value' in transaction")
|
||||
}
|
||||
value, overflow := uint256.FromBig(dec.Value.ToInt())
|
||||
if overflow {
|
||||
return nil, errors.New("'value' in transaction does not fit in 256 bits")
|
||||
}
|
||||
tx.Message.Value = Uint256View(*value)
|
||||
if dec.Data == nil {
|
||||
return nil, errors.New("missing required field 'input' in transaction")
|
||||
}
|
||||
tx.Message.Data = TxDataView(*dec.Data)
|
||||
|
||||
if dec.MaxFeePerDataGas == nil {
|
||||
return nil, errors.New("missing required field 'maxFeePerDataGas' in transaction")
|
||||
}
|
||||
maxFeePerDataGas, overflow := uint256.FromBig(dec.MaxFeePerDataGas.ToInt())
|
||||
if overflow {
|
||||
return nil, errors.New("'maxFeePerDataGas' in transaction does not fit in 256 bits")
|
||||
}
|
||||
tx.Message.MaxFeePerDataGas = Uint256View(*maxFeePerDataGas)
|
||||
|
||||
if dec.BlobVersionedHashes != nil {
|
||||
tx.Message.BlobVersionedHashes = VersionedHashesView(dec.BlobVersionedHashes)
|
||||
} else {
|
||||
tx.Message.BlobVersionedHashes = VersionedHashesView([]libcommon.Hash{})
|
||||
}
|
||||
|
||||
if dec.V == nil {
|
||||
return nil, errors.New("missing required field 'v' in transaction")
|
||||
}
|
||||
var v uint256.Int
|
||||
overflow = v.SetFromBig(dec.V.ToInt())
|
||||
if overflow {
|
||||
return nil, fmt.Errorf("dec.V higher than 2^256-1")
|
||||
}
|
||||
if v.Uint64() > 255 {
|
||||
return nil, fmt.Errorf("dev.V higher than 2^8 - 1")
|
||||
}
|
||||
|
||||
tx.Signature.V = Uint8View(v.Uint64())
|
||||
|
||||
if dec.R == nil {
|
||||
return nil, errors.New("missing required field 'r' in transaction")
|
||||
}
|
||||
var r uint256.Int
|
||||
overflow = r.SetFromBig(dec.R.ToInt())
|
||||
if overflow {
|
||||
return nil, fmt.Errorf("dec.R higher than 2^256-1")
|
||||
}
|
||||
tx.Signature.R = Uint256View(r)
|
||||
|
||||
if dec.S == nil {
|
||||
return nil, errors.New("missing required field 's' in transaction")
|
||||
}
|
||||
var s uint256.Int
|
||||
overflow = s.SetFromBig(dec.S.ToInt())
|
||||
if overflow {
|
||||
return nil, errors.New("'s' in transaction does not fit in 256 bits")
|
||||
}
|
||||
tx.Signature.S = Uint256View(s)
|
||||
|
||||
withSignature := !v.IsZero() || !r.IsZero() || !s.IsZero()
|
||||
if withSignature {
|
||||
if err := sanityCheckSignature(&v, &r, &s, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(dec.Blobs) == 0 {
|
||||
// if no blobs are specified in the json we assume it is an unwrapped blob tx
|
||||
return &tx, nil
|
||||
}
|
||||
|
||||
btx := BlobTxWrapper{
|
||||
Tx: tx,
|
||||
Commitments: dec.Commitments,
|
||||
Blobs: dec.Blobs,
|
||||
Proofs: dec.Proofs,
|
||||
}
|
||||
err := btx.ValidateBlobTransactionWrapper()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &btx, nil
|
||||
}
|
||||
|
@ -297,6 +297,7 @@ func (s *EthBackendServer) checkWithdrawalsPresence(time uint64, withdrawals []*
|
||||
}
|
||||
|
||||
func (s *EthBackendServer) EngineGetBlobsBundleV1(ctx context.Context, req *remote.EngineGetBlobsBundleRequest) (*types2.BlobsBundleV1, error) {
|
||||
// TODO: get the latest update on this function (it was replaced)
|
||||
if !s.proposing {
|
||||
return nil, fmt.Errorf("execution layer not running as a proposer. enable proposer by taking out the --proposer.disable flag on startup")
|
||||
}
|
||||
@ -333,7 +334,7 @@ func (s *EthBackendServer) EngineGetBlobsBundleV1(ctx context.Context, req *remo
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("expected blob transaction to be type BlobTxWrapper, got: %T", blobtx)
|
||||
}
|
||||
versionedHashes, kzgs, blobs, proofs := blobtx.GetDataHashes(), blobtx.BlobKzgs, blobtx.Blobs, blobtx.Proofs
|
||||
versionedHashes, kzgs, blobs, proofs := blobtx.GetDataHashes(), blobtx.Commitments, blobtx.Blobs, blobtx.Proofs
|
||||
lenCheck := len(versionedHashes)
|
||||
if lenCheck != len(kzgs) || lenCheck != len(blobs) || lenCheck != len(blobtx.Proofs) {
|
||||
return nil, fmt.Errorf("tx %d in block %s has inconsistent blobs (%d) / kzgs (%d) / proofs (%d)"+
|
||||
|
@ -395,6 +395,8 @@ type RPCTransaction struct {
|
||||
V *hexutil.Big `json:"v"`
|
||||
R *hexutil.Big `json:"r"`
|
||||
S *hexutil.Big `json:"s"`
|
||||
|
||||
BlobVersionedHashes []libcommon.Hash `json:"blobVersionedHashes,omitempty"`
|
||||
}
|
||||
|
||||
// newRPCTransaction returns a transaction that will serialize to the RPC
|
||||
@ -443,14 +445,22 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb
|
||||
result.S = (*hexutil.Big)(t.S.ToBig())
|
||||
result.Accesses = &t.AccessList
|
||||
// if the transaction has been mined, compute the effective gas price
|
||||
if baseFee != nil && blockHash != (libcommon.Hash{}) {
|
||||
// price = min(tip, gasFeeCap - baseFee) + baseFee
|
||||
price := math.BigMin(new(big.Int).Add(t.Tip.ToBig(), baseFee), t.FeeCap.ToBig())
|
||||
result.GasPrice = (*hexutil.Big)(price)
|
||||
} else {
|
||||
result.GasPrice = nil
|
||||
}
|
||||
// case *types.SignedBlobTx: // TODO
|
||||
result.GasPrice = computeGasPrice(tx, blockHash, baseFee)
|
||||
case *types.SignedBlobTx:
|
||||
chainId.Set(t.GetChainID())
|
||||
result.ChainID = (*hexutil.Big)(chainId.ToBig())
|
||||
result.Tip = (*hexutil.Big)(t.GetTip().ToBig())
|
||||
result.FeeCap = (*hexutil.Big)(t.GetFeeCap().ToBig())
|
||||
v, r, s := t.RawSignatureValues()
|
||||
result.V = (*hexutil.Big)(v.ToBig())
|
||||
result.R = (*hexutil.Big)(r.ToBig())
|
||||
result.S = (*hexutil.Big)(s.ToBig())
|
||||
al := t.GetAccessList()
|
||||
result.Accesses = &al
|
||||
// if the transaction has been mined, compute the effective gas price
|
||||
result.GasPrice = computeGasPrice(tx, blockHash, baseFee)
|
||||
result.MaxFeePerDataGas = (*hexutil.Big)(t.GetMaxFeePerDataGas().ToBig())
|
||||
result.BlobVersionedHashes = t.GetDataHashes()
|
||||
}
|
||||
signer := types.LatestSignerForChainID(chainId.ToBig())
|
||||
var err error
|
||||
@ -466,6 +476,15 @@ func newRPCTransaction(tx types.Transaction, blockHash libcommon.Hash, blockNumb
|
||||
return result
|
||||
}
|
||||
|
||||
func computeGasPrice(tx types.Transaction, blockHash libcommon.Hash, baseFee *big.Int) *hexutil.Big {
|
||||
if baseFee != nil && blockHash != (libcommon.Hash{}) {
|
||||
// price = min(tip + baseFee, gasFeeCap)
|
||||
price := math.BigMin(new(big.Int).Add(tx.GetTip().ToBig(), baseFee), tx.GetFeeCap().ToBig())
|
||||
return (*hexutil.Big)(price)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 libcommon.Hash, blockHash libcommon.Hash, blockNumber uint64, index uint64, baseFee *big.Int) *RPCTransaction {
|
||||
|
Loading…
Reference in New Issue
Block a user