diff --git a/core/types/arb_types.go b/core/types/arb_types.go index 00e8b9fc9a..fabd10b7e5 100644 --- a/core/types/arb_types.go +++ b/core/types/arb_types.go @@ -140,29 +140,33 @@ type ArbitrumRetryTx struct { Nonce uint64 From common.Address - GasFeeCap *big.Int // wei per gas - Gas uint64 // gas limit - To *common.Address `rlp:"nil"` // nil means contract creation - Value *big.Int // wei amount - Data []byte // contract invocation input data - TicketId common.Hash - RefundTo common.Address + GasFeeCap *big.Int // wei per gas + Gas uint64 // gas limit + To *common.Address `rlp:"nil"` // nil means contract creation + Value *big.Int // wei amount + Data []byte // contract invocation input data + TicketId common.Hash + RefundTo common.Address + MaxRefund *big.Int // the maximum refund sent to RefundTo (the rest goes to From) + SubmissionFeeRefund *big.Int // the submission fee to refund if successful (capped by MaxRefund) } func (tx *ArbitrumRetryTx) txType() byte { return ArbitrumRetryTxType } func (tx *ArbitrumRetryTx) copy() TxData { cpy := &ArbitrumRetryTx{ - ChainId: new(big.Int), - Nonce: tx.Nonce, - GasFeeCap: new(big.Int), - Gas: tx.Gas, - From: tx.From, - To: nil, - Value: new(big.Int), - Data: common.CopyBytes(tx.Data), - TicketId: tx.TicketId, - RefundTo: tx.RefundTo, + ChainId: new(big.Int), + Nonce: tx.Nonce, + GasFeeCap: new(big.Int), + Gas: tx.Gas, + From: tx.From, + To: nil, + Value: new(big.Int), + Data: common.CopyBytes(tx.Data), + TicketId: tx.TicketId, + RefundTo: tx.RefundTo, + MaxRefund: new(big.Int), + SubmissionFeeRefund: new(big.Int), } if tx.ChainId != nil { cpy.ChainId.Set(tx.ChainId) @@ -177,6 +181,12 @@ func (tx *ArbitrumRetryTx) copy() TxData { if tx.Value != nil { cpy.Value.Set(tx.Value) } + if tx.MaxRefund != nil { + cpy.MaxRefund.Set(tx.MaxRefund) + } + if tx.SubmissionFeeRefund != nil { + cpy.SubmissionFeeRefund.Set(tx.SubmissionFeeRefund) + } return cpy } diff --git a/core/types/transaction_marshalling.go b/core/types/transaction_marshalling.go index e4fde624a5..9ff27b3107 100644 --- a/core/types/transaction_marshalling.go +++ b/core/types/transaction_marshalling.go @@ -47,16 +47,18 @@ type txJSON struct { AccessList *AccessList `json:"accessList,omitempty"` // Arbitrum fields: - From *common.Address `json:"from,omitempty"` // Contract SubmitRetryable Unsigned Retry - RequestId *common.Hash `json:"requestId,omitempty"` // Contract SubmitRetryable Deposit - TicketId *common.Hash `json:"ticketId,omitempty"` // Retry - RefundTo *common.Address `json:"refundTo,omitempty"` // SubmitRetryable Retry - L1BaseFee *hexutil.Big `json:"l1BaseFee,omitempty"` // SubmitRetryable - DepositValue *hexutil.Big `json:"depositValue,omitempty"` // SubmitRetryable - RetryTo *common.Address `json:"retryTo,omitempty"` // SubmitRetryable - RetryData *hexutil.Bytes `json:"retryData,omitempty"` // SubmitRetryable - Beneficiary *common.Address `json:"beneficiary,omitempty"` // SubmitRetryable - MaxSubmissionFee *hexutil.Big `json:"maxSubmissionFee,omitempty"` // SubmitRetryable + From *common.Address `json:"from,omitempty"` // Contract SubmitRetryable Unsigned Retry + RequestId *common.Hash `json:"requestId,omitempty"` // Contract SubmitRetryable Deposit + TicketId *common.Hash `json:"ticketId,omitempty"` // Retry + MaxRefund *hexutil.Big `json:"maxRefund,omitempty"` // Retry + SubmissionFeeRefund *hexutil.Big `json:"submissionFeeRefund,omitempty"` // Retry + RefundTo *common.Address `json:"refundTo,omitempty"` // SubmitRetryable Retry + L1BaseFee *hexutil.Big `json:"l1BaseFee,omitempty"` // SubmitRetryable + DepositValue *hexutil.Big `json:"depositValue,omitempty"` // SubmitRetryable + RetryTo *common.Address `json:"retryTo,omitempty"` // SubmitRetryable + RetryData *hexutil.Bytes `json:"retryData,omitempty"` // SubmitRetryable + Beneficiary *common.Address `json:"beneficiary,omitempty"` // SubmitRetryable + MaxSubmissionFee *hexutil.Big `json:"maxSubmissionFee,omitempty"` // SubmitRetryable // Only used for encoding: Hash common.Hash `json:"hash"` @@ -163,6 +165,8 @@ func (t *Transaction) MarshalJSON() ([]byte, error) { enc.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap) enc.Value = (*hexutil.Big)(tx.Value) enc.Data = (*hexutil.Bytes)(&tx.Data) + enc.MaxRefund = (*hexutil.Big)(tx.MaxRefund) + enc.SubmissionFeeRefund = (*hexutil.Big)(tx.SubmissionFeeRefund) enc.To = t.To() case *ArbitrumSubmitRetryableTx: enc.RequestId = &tx.RequestId @@ -514,17 +518,25 @@ func (t *Transaction) UnmarshalJSON(input []byte) error { if dec.RefundTo == nil { return errors.New("missing required field 'refundTo' in transaction") } + if dec.MaxRefund == nil { + return errors.New("missing required field 'maxRefund' in transaction") + } + if dec.SubmissionFeeRefund == nil { + return errors.New("missing required field 'submissionFeeRefund' in transaction") + } inner = &ArbitrumRetryTx{ - ChainId: (*big.Int)(dec.ChainID), - Nonce: uint64(*dec.Nonce), - From: *dec.From, - GasFeeCap: (*big.Int)(dec.MaxFeePerGas), - Gas: uint64(*dec.Gas), - To: dec.To, - Value: (*big.Int)(dec.Value), - Data: *dec.Data, - TicketId: *dec.TicketId, - RefundTo: *dec.RefundTo, + ChainId: (*big.Int)(dec.ChainID), + Nonce: uint64(*dec.Nonce), + From: *dec.From, + GasFeeCap: (*big.Int)(dec.MaxFeePerGas), + Gas: uint64(*dec.Gas), + To: dec.To, + Value: (*big.Int)(dec.Value), + Data: *dec.Data, + TicketId: *dec.TicketId, + RefundTo: *dec.RefundTo, + MaxRefund: (*big.Int)(dec.MaxRefund), + SubmissionFeeRefund: (*big.Int)(dec.SubmissionFeeRefund), } case ArbitrumSubmitRetryableTxType: diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index c7de73ae50..22f55dc5cd 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1381,15 +1381,17 @@ type RPCTransaction struct { S *hexutil.Big `json:"s"` // Arbitrum fields: - RequestId *common.Hash `json:"requestId,omitempty"` // Contract SubmitRetryable Deposit - TicketId *common.Hash `json:"ticketId,omitempty"` // Retry - RefundTo *common.Address `json:"refundTo,omitempty"` // SubmitRetryable Retry - L1BaseFee *hexutil.Big `json:"l1BaseFee,omitempty"` // SubmitRetryable - DepositValue *hexutil.Big `json:"depositValue,omitempty"` // SubmitRetryable - RetryTo *common.Address `json:"retryTo,omitempty"` // SubmitRetryable - RetryData *hexutil.Bytes `json:"retryData,omitempty"` // SubmitRetryable - Beneficiary *common.Address `json:"beneficiary,omitempty"` // SubmitRetryable - MaxSubmissionFee *hexutil.Big `json:"maxSubmissionFee,omitempty"` // SubmitRetryable + RequestId *common.Hash `json:"requestId,omitempty"` // Contract SubmitRetryable Deposit + TicketId *common.Hash `json:"ticketId,omitempty"` // Retry + MaxRefund *hexutil.Big `json:"maxRefund,omitempty"` // Retry + SubmissionFeeRefund *hexutil.Big `json:"submissionFeeRefund,omitempty"` // Retry + RefundTo *common.Address `json:"refundTo,omitempty"` // SubmitRetryable Retry + L1BaseFee *hexutil.Big `json:"l1BaseFee,omitempty"` // SubmitRetryable + DepositValue *hexutil.Big `json:"depositValue,omitempty"` // SubmitRetryable + RetryTo *common.Address `json:"retryTo,omitempty"` // SubmitRetryable + RetryData *hexutil.Bytes `json:"retryData,omitempty"` // SubmitRetryable + Beneficiary *common.Address `json:"beneficiary,omitempty"` // SubmitRetryable + MaxSubmissionFee *hexutil.Big `json:"maxSubmissionFee,omitempty"` // SubmitRetryable } // newRPCTransaction returns a transaction that will serialize to the RPC @@ -1454,6 +1456,8 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber result.RefundTo = &inner.RefundTo result.GasFeeCap = (*hexutil.Big)(inner.GasFeeCap) result.ChainID = (*hexutil.Big)(inner.ChainId) + result.MaxRefund = (*hexutil.Big)(inner.MaxRefund) + result.SubmissionFeeRefund = (*hexutil.Big)(inner.SubmissionFeeRefund) case *types.ArbitrumSubmitRetryableTx: result.RequestId = &inner.RequestId result.L1BaseFee = (*hexutil.Big)(inner.L1BaseFee)