-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CIP-64 / CIP-66 compatible TransactionArgs
#123
Changes from 10 commits
d434cce
577d152
526563d
8e46539
9f238e6
9d0aa80
815cb7c
7a87ae6
3689a77
27a328d
dbb2c57
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -154,14 +154,15 @@ func toWordSize(size uint64) uint64 { | |
// A Message contains the data derived from a single transaction that is relevant to state | ||
// processing. | ||
type Message struct { | ||
To *common.Address | ||
From common.Address | ||
Nonce uint64 | ||
Value *big.Int | ||
GasLimit uint64 | ||
GasPrice *big.Int | ||
GasFeeCap *big.Int | ||
GasTipCap *big.Int | ||
To *common.Address | ||
From common.Address | ||
Nonce uint64 | ||
Value *big.Int | ||
GasLimit uint64 | ||
GasPrice *big.Int | ||
GasFeeCap *big.Int | ||
GasTipCap *big.Int | ||
|
||
Data []byte | ||
AccessList types.AccessList | ||
BlobGasFeeCap *big.Int | ||
|
@@ -182,8 +183,7 @@ type Message struct { | |
// FeeCurrency specifies the currency for gas fees. | ||
// `nil` corresponds to Celo Gold (native currency). | ||
// All other values should correspond to ERC20 contract addresses. | ||
FeeCurrency *common.Address | ||
|
||
FeeCurrency *common.Address | ||
MaxFeeInFeeCurrency *big.Int // MaxFeeInFeeCurrency is the maximum fee that can be charged in the fee currency. | ||
} | ||
|
||
|
@@ -213,7 +213,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In | |
} | ||
// If baseFee provided, set gasPrice to effectiveGasPrice. | ||
if baseFee != nil { | ||
if msg.FeeCurrency != nil { | ||
if tx.Type() == types.CeloDynamicFeeTxType { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this change safe for the case where There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the |
||
var err error | ||
baseFee, err = exchange.ConvertGoldToCurrency(exchangeRates, msg.FeeCurrency, baseFee) | ||
if err != nil { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package types | ||
|
||
import ( | ||
"bytes" | ||
"math/big" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/rlp" | ||
) | ||
|
||
type CeloDenominatedTx struct { | ||
ChainID *big.Int | ||
Nonce uint64 | ||
GasTipCap *big.Int | ||
GasFeeCap *big.Int | ||
Gas uint64 | ||
To *common.Address `rlp:"nil"` // nil means contract creation | ||
Value *big.Int | ||
Data []byte | ||
AccessList AccessList | ||
|
||
FeeCurrency *common.Address | ||
MaxFeeInFeeCurrency *big.Int | ||
|
||
// Signature values | ||
V *big.Int `json:"v" gencodec:"required"` | ||
R *big.Int `json:"r" gencodec:"required"` | ||
S *big.Int `json:"s" gencodec:"required"` | ||
} | ||
|
||
// copy creates a deep copy of the transaction data and initializes all fields. | ||
func (tx *CeloDenominatedTx) copy() TxData { | ||
cpy := &CeloDenominatedTx{ | ||
Nonce: tx.Nonce, | ||
To: copyAddressPtr(tx.To), | ||
Data: common.CopyBytes(tx.Data), | ||
Gas: tx.Gas, | ||
FeeCurrency: copyAddressPtr(tx.FeeCurrency), | ||
// These are copied below. | ||
MaxFeeInFeeCurrency: new(big.Int), | ||
AccessList: make(AccessList, len(tx.AccessList)), | ||
Value: new(big.Int), | ||
ChainID: new(big.Int), | ||
GasTipCap: new(big.Int), | ||
GasFeeCap: new(big.Int), | ||
V: new(big.Int), | ||
R: new(big.Int), | ||
S: new(big.Int), | ||
} | ||
if tx.MaxFeeInFeeCurrency != nil { | ||
cpy.MaxFeeInFeeCurrency.Set(tx.MaxFeeInFeeCurrency) | ||
} | ||
copy(cpy.AccessList, tx.AccessList) | ||
if tx.Value != nil { | ||
cpy.Value.Set(tx.Value) | ||
} | ||
if tx.ChainID != nil { | ||
cpy.ChainID.Set(tx.ChainID) | ||
} | ||
if tx.GasTipCap != nil { | ||
cpy.GasTipCap.Set(tx.GasTipCap) | ||
} | ||
if tx.GasFeeCap != nil { | ||
cpy.GasFeeCap.Set(tx.GasFeeCap) | ||
} | ||
if tx.V != nil { | ||
cpy.V.Set(tx.V) | ||
} | ||
if tx.R != nil { | ||
cpy.R.Set(tx.R) | ||
} | ||
if tx.S != nil { | ||
cpy.S.Set(tx.S) | ||
} | ||
return cpy | ||
} | ||
|
||
// accessors for innerTx. | ||
func (tx *CeloDenominatedTx) txType() byte { return CeloDenominatedTxType } | ||
func (tx *CeloDenominatedTx) chainID() *big.Int { return tx.ChainID } | ||
func (tx *CeloDenominatedTx) accessList() AccessList { return tx.AccessList } | ||
func (tx *CeloDenominatedTx) data() []byte { return tx.Data } | ||
func (tx *CeloDenominatedTx) gas() uint64 { return tx.Gas } | ||
func (tx *CeloDenominatedTx) gasFeeCap() *big.Int { return tx.GasFeeCap } | ||
func (tx *CeloDenominatedTx) gasTipCap() *big.Int { return tx.GasTipCap } | ||
func (tx *CeloDenominatedTx) gasPrice() *big.Int { return tx.GasFeeCap } | ||
func (tx *CeloDenominatedTx) value() *big.Int { return tx.Value } | ||
func (tx *CeloDenominatedTx) nonce() uint64 { return tx.Nonce } | ||
func (tx *CeloDenominatedTx) to() *common.Address { return tx.To } | ||
func (tx *CeloDenominatedTx) isSystemTx() bool { return false } | ||
|
||
func (tx *CeloDenominatedTx) effectiveGasPrice(dst *big.Int, baseFee *big.Int) *big.Int { | ||
if baseFee == nil { | ||
return dst.Set(tx.GasFeeCap) | ||
} | ||
tip := dst.Sub(tx.GasFeeCap, baseFee) | ||
if tip.Cmp(tx.GasTipCap) > 0 { | ||
tip.Set(tx.GasTipCap) | ||
} | ||
return tip.Add(tip, baseFee) | ||
} | ||
|
||
func (tx *CeloDenominatedTx) rawSignatureValues() (v, r, s *big.Int) { | ||
return tx.V, tx.R, tx.S | ||
} | ||
|
||
func (tx *CeloDenominatedTx) setSignatureValues(chainID, v, r, s *big.Int) { | ||
tx.ChainID, tx.V, tx.R, tx.S = chainID, v, r, s | ||
} | ||
|
||
func (tx *CeloDenominatedTx) encode(b *bytes.Buffer) error { | ||
return rlp.Encode(b, tx) | ||
} | ||
|
||
func (tx *CeloDenominatedTx) decode(input []byte) error { | ||
return rlp.DecodeBytes(input, tx) | ||
} | ||
|
||
func (tx *CeloDenominatedTx) feeCurrency() *common.Address { return tx.FeeCurrency } | ||
|
||
func (tx *CeloDenominatedTx) maxFeeInFeeCurrency() *big.Int { return tx.MaxFeeInFeeCurrency } |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,7 +51,8 @@ const ( | |
DynamicFeeTxType = 0x02 | ||
BlobTxType = 0x03 | ||
// CeloDynamicFeeTxType = 0x7c old Celo tx type with gateway fee | ||
CeloDynamicFeeTxType = 0x7b | ||
CeloDynamicFeeTxType = 0x7b | ||
CeloDenominatedTxType = 0x7a | ||
) | ||
|
||
// Transaction is an Ethereum transaction. | ||
|
@@ -110,6 +111,7 @@ type TxData interface { | |
|
||
// Celo specific fields | ||
feeCurrency() *common.Address | ||
maxFeeInFeeCurrency() *big.Int | ||
Comment on lines
113
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC @piersy suggested that we can avoid extending TxData by checking the tx type and casting to a specific tx type whenever we want to use a tx-type-specific attribute. I think that can work, but for consistency it should either be done for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I generally don't like the concept of the TxData interface exposing the union of all struct fields. So do you suggest implementing this in this PR? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, let's keep it as it is. If we want to change it, we should do so in a separate PR. |
||
} | ||
|
||
// EncodeRLP implements rlp.Encoder | ||
|
@@ -216,6 +218,8 @@ func (tx *Transaction) decodeTyped(b []byte) (TxData, error) { | |
inner = new(DynamicFeeTx) | ||
case CeloDynamicFeeTxType: | ||
inner = new(CeloDynamicFeeTx) | ||
case CeloDenominatedTxType: | ||
inner = new(CeloDenominatedTx) | ||
case BlobTxType: | ||
inner = new(BlobTx) | ||
case DepositTxType: | ||
|
@@ -628,6 +632,15 @@ func (tx *Transaction) FeeCurrency() *common.Address { | |
return copyAddressPtr(tx.inner.feeCurrency()) | ||
} | ||
|
||
// MaxFeeInFeeCurrency returns the max fee in the fee_currency for celo denominated txs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment feels too much like the variable name. We can add some more information here. Suggestion:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in dbb2c57 |
||
func (tx *Transaction) MaxFeeInFeeCurrency() *big.Int { | ||
mfifc := tx.inner.maxFeeInFeeCurrency() | ||
if mfifc == nil { | ||
return nil | ||
} | ||
return new(big.Int).Set(mfifc) | ||
} | ||
|
||
// Transactions implements DerivableList for transactions. | ||
type Transactions []*Transaction | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like an unnecessary change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in dbb2c57