246 lines
5.9 KiB
Go
246 lines
5.9 KiB
Go
|
package types
|
||
|
|
||
|
import (
|
||
|
"math/big"
|
||
|
|
||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||
|
"github.com/ethereum/go-ethereum/common"
|
||
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||
|
"github.com/tharsis/ethermint/types"
|
||
|
)
|
||
|
|
||
|
// nolint: deadcode, unused
|
||
|
func newDynamicFeeTx(tx *ethtypes.Transaction) *DynamicFeeTx {
|
||
|
txData := &DynamicFeeTx{
|
||
|
Nonce: tx.Nonce(),
|
||
|
Data: tx.Data(),
|
||
|
GasLimit: tx.Gas(),
|
||
|
}
|
||
|
|
||
|
v, r, s := tx.RawSignatureValues()
|
||
|
if tx.To() != nil {
|
||
|
txData.To = tx.To().Hex()
|
||
|
}
|
||
|
|
||
|
if tx.Value() != nil {
|
||
|
amountInt := sdk.NewIntFromBigInt(tx.Value())
|
||
|
txData.Amount = &amountInt
|
||
|
}
|
||
|
// TODO:
|
||
|
|
||
|
// if tx.GasFeeCap() != nil {
|
||
|
// gasFeeCapInt := sdk.NewIntFromBigInt(tx.GasFeeCap())
|
||
|
// txData.GasFeeCap = &gasFeeCapInt
|
||
|
// }
|
||
|
|
||
|
// if tx.GasTipCap() != nil {
|
||
|
// gasTipCapInt := sdk.NewIntFromBigInt(tx.GasTipCap())
|
||
|
// txData.GasTipCap = &gasTipCapInt
|
||
|
// }
|
||
|
|
||
|
if tx.AccessList() != nil {
|
||
|
al := tx.AccessList()
|
||
|
txData.Accesses = NewAccessList(&al)
|
||
|
}
|
||
|
|
||
|
txData.SetSignatureValues(tx.ChainId(), v, r, s)
|
||
|
return txData
|
||
|
}
|
||
|
|
||
|
// TxType returns the tx type
|
||
|
func (tx *DynamicFeeTx) TxType() uint8 {
|
||
|
// TODO
|
||
|
return 0
|
||
|
// return ethtypes.DynamicFeeTxType
|
||
|
}
|
||
|
|
||
|
// Copy returns an instance with the same field values
|
||
|
func (tx *DynamicFeeTx) Copy() TxData {
|
||
|
return &DynamicFeeTx{
|
||
|
ChainID: tx.ChainID,
|
||
|
Nonce: tx.Nonce,
|
||
|
GasTipCap: tx.GasTipCap,
|
||
|
GasFeeCap: tx.GasFeeCap,
|
||
|
GasLimit: tx.GasLimit,
|
||
|
To: tx.To,
|
||
|
Amount: tx.Amount,
|
||
|
Data: common.CopyBytes(tx.Data),
|
||
|
Accesses: tx.Accesses,
|
||
|
V: common.CopyBytes(tx.V),
|
||
|
R: common.CopyBytes(tx.R),
|
||
|
S: common.CopyBytes(tx.S),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// GetChainID returns the chain id field from the DynamicFeeTx
|
||
|
func (tx *DynamicFeeTx) GetChainID() *big.Int {
|
||
|
if tx.ChainID == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return tx.ChainID.BigInt()
|
||
|
}
|
||
|
|
||
|
// GetAccessList returns the AccessList field.
|
||
|
func (tx *DynamicFeeTx) GetAccessList() ethtypes.AccessList {
|
||
|
if tx.Accesses == nil {
|
||
|
return nil
|
||
|
}
|
||
|
return *tx.Accesses.ToEthAccessList()
|
||
|
}
|
||
|
|
||
|
// GetData returns the a copy of the input data bytes.
|
||
|
func (tx *DynamicFeeTx) GetData() []byte {
|
||
|
return common.CopyBytes(tx.Data)
|
||
|
}
|
||
|
|
||
|
// GetGas returns the gas limit.
|
||
|
func (tx *DynamicFeeTx) GetGas() uint64 {
|
||
|
return tx.GasLimit
|
||
|
}
|
||
|
|
||
|
// GetGasPrice returns the gas fee cap field.
|
||
|
func (tx *DynamicFeeTx) GetGasPrice() *big.Int {
|
||
|
return tx.GetGasFeeCap()
|
||
|
}
|
||
|
|
||
|
// GetGasTipCap returns the gas price field.
|
||
|
func (tx *DynamicFeeTx) GetGasTipCap() *big.Int {
|
||
|
if tx.GasTipCap == nil {
|
||
|
return nil
|
||
|
}
|
||
|
return tx.GasTipCap.BigInt()
|
||
|
}
|
||
|
|
||
|
// GetGasFeeCap returns the gas price field.
|
||
|
func (tx *DynamicFeeTx) GetGasFeeCap() *big.Int {
|
||
|
if tx.GasFeeCap == nil {
|
||
|
return nil
|
||
|
}
|
||
|
return tx.GasFeeCap.BigInt()
|
||
|
}
|
||
|
|
||
|
// GetValue returns the tx amount.
|
||
|
func (tx *DynamicFeeTx) GetValue() *big.Int {
|
||
|
if tx.Amount == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return tx.Amount.BigInt()
|
||
|
}
|
||
|
|
||
|
// GetNonce returns the account sequence for the transaction.
|
||
|
func (tx *DynamicFeeTx) GetNonce() uint64 { return tx.Nonce }
|
||
|
|
||
|
// GetTo returns the pointer to the recipient address.
|
||
|
func (tx *DynamicFeeTx) GetTo() *common.Address {
|
||
|
if tx.To == "" {
|
||
|
return nil
|
||
|
}
|
||
|
to := common.HexToAddress(tx.To)
|
||
|
return &to
|
||
|
}
|
||
|
|
||
|
// AsEthereumData returns an DynamicFeeTx transaction tx from the proto-formatted
|
||
|
// TxData defined on the Cosmos EVM.
|
||
|
func (tx *DynamicFeeTx) AsEthereumData() ethtypes.TxData {
|
||
|
return nil
|
||
|
// TODO:
|
||
|
// v, r, s := tx.GetRawSignatureValues()
|
||
|
// return ðtypes.DynamicFeeTx{
|
||
|
// ChainID: tx.GetChainID(),
|
||
|
// Nonce: tx.GetNonce(),
|
||
|
// GasTipCap: tx.GetGasTipCap(),
|
||
|
// GasFeeCap: tx.GetGasFeeCap(),
|
||
|
// Gas: tx.GetGas(),
|
||
|
// To: tx.GetTo(),
|
||
|
// Value: tx.GetValue(),
|
||
|
// Data: tx.GetData(),
|
||
|
// AccessList: tx.GetAccessList(),
|
||
|
// V: v,
|
||
|
// R: r,
|
||
|
// S: s,
|
||
|
// }
|
||
|
}
|
||
|
|
||
|
// GetRawSignatureValues returns the V, R, S signature values of the transaction.
|
||
|
// The return values should not be modified by the caller.
|
||
|
func (tx *DynamicFeeTx) GetRawSignatureValues() (v, r, s *big.Int) {
|
||
|
return rawSignatureValues(tx.V, tx.R, tx.S)
|
||
|
}
|
||
|
|
||
|
// SetSignatureValues sets the signature values to the transaction.
|
||
|
func (tx *DynamicFeeTx) SetSignatureValues(chainID, v, r, s *big.Int) {
|
||
|
if v != nil {
|
||
|
tx.V = v.Bytes()
|
||
|
}
|
||
|
if r != nil {
|
||
|
tx.R = r.Bytes()
|
||
|
}
|
||
|
if s != nil {
|
||
|
tx.S = s.Bytes()
|
||
|
}
|
||
|
if chainID != nil {
|
||
|
chainIDInt := sdk.NewIntFromBigInt(chainID)
|
||
|
tx.ChainID = &chainIDInt
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Validate performs a stateless validation of the tx fields.
|
||
|
func (tx DynamicFeeTx) Validate() error {
|
||
|
if tx.GasTipCap == nil {
|
||
|
return sdkerrors.Wrap(ErrInvalidGasCap, "gas tip cap cannot nil")
|
||
|
}
|
||
|
|
||
|
if tx.GasFeeCap == nil {
|
||
|
return sdkerrors.Wrap(ErrInvalidGasCap, "gas fee cap cannot nil")
|
||
|
}
|
||
|
|
||
|
if tx.GasTipCap.IsNegative() {
|
||
|
return sdkerrors.Wrapf(ErrInvalidGasCap, "gas tip cap cannot be negative %s", tx.GasTipCap)
|
||
|
}
|
||
|
|
||
|
if tx.GasFeeCap.IsNegative() {
|
||
|
return sdkerrors.Wrapf(ErrInvalidGasCap, "gas fee cap cannot be negative %s", tx.GasFeeCap)
|
||
|
}
|
||
|
|
||
|
if tx.GasFeeCap.LT(*tx.GasTipCap) {
|
||
|
return sdkerrors.Wrapf(
|
||
|
ErrInvalidGasCap, "max priority fee per gas higher than max fee per gas (%s > %s)",
|
||
|
tx.GasTipCap, tx.GasFeeCap,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
amount := tx.GetValue()
|
||
|
// Amount can be 0
|
||
|
if amount != nil && amount.Sign() == -1 {
|
||
|
return sdkerrors.Wrapf(ErrInvalidAmount, "amount cannot be negative %s", amount)
|
||
|
}
|
||
|
|
||
|
if tx.To != "" {
|
||
|
if err := types.ValidateAddress(tx.To); err != nil {
|
||
|
return sdkerrors.Wrap(err, "invalid to address")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if tx.GetChainID() == nil {
|
||
|
return sdkerrors.Wrap(
|
||
|
sdkerrors.ErrInvalidChainID,
|
||
|
"chain ID must be present on AccessList txs",
|
||
|
)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Fee panics as it requires the base fee amount to calculate
|
||
|
func (tx DynamicFeeTx) Fee() *big.Int {
|
||
|
panic("fee can only be called manually by providing the base fee")
|
||
|
}
|
||
|
|
||
|
// Cost returns amount + gasprice * gaslimit.
|
||
|
func (tx DynamicFeeTx) Cost() *big.Int {
|
||
|
panic("cost can only be called manually by providing the base fee")
|
||
|
}
|