2021-07-05 16:39:08 +00:00
|
|
|
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"
|
|
|
|
)
|
|
|
|
|
|
|
|
func newLegacyTx(tx *ethtypes.Transaction) *LegacyTx {
|
|
|
|
txData := &LegacyTx{
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
if tx.GasPrice() != nil {
|
|
|
|
gasPriceInt := sdk.NewIntFromBigInt(tx.GasPrice())
|
|
|
|
txData.GasPrice = &gasPriceInt
|
|
|
|
}
|
|
|
|
|
|
|
|
txData.SetSignatureValues(tx.ChainId(), v, r, s)
|
|
|
|
return txData
|
|
|
|
}
|
|
|
|
|
|
|
|
// TxType returns the tx type
|
|
|
|
func (tx *LegacyTx) TxType() uint8 {
|
|
|
|
return ethtypes.LegacyTxType
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy returns an instance with the same field values
|
|
|
|
func (tx *LegacyTx) Copy() TxData {
|
|
|
|
return &LegacyTx{
|
|
|
|
Nonce: tx.Nonce,
|
|
|
|
GasPrice: tx.GasPrice,
|
|
|
|
GasLimit: tx.GasLimit,
|
|
|
|
To: tx.To,
|
|
|
|
Amount: tx.Amount,
|
|
|
|
Data: common.CopyBytes(tx.Data),
|
|
|
|
V: common.CopyBytes(tx.V),
|
|
|
|
R: common.CopyBytes(tx.R),
|
|
|
|
S: common.CopyBytes(tx.S),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetChainID returns the chain id field from the derived signature values
|
|
|
|
func (tx *LegacyTx) GetChainID() *big.Int {
|
|
|
|
v, _, _ := tx.GetRawSignatureValues()
|
|
|
|
return DeriveChainID(v)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetAccessList returns nil
|
|
|
|
func (tx *LegacyTx) GetAccessList() ethtypes.AccessList {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetData returns the a copy of the input data bytes.
|
|
|
|
func (tx *LegacyTx) GetData() []byte {
|
|
|
|
return common.CopyBytes(tx.Data)
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetGas returns the gas limit.
|
|
|
|
func (tx *LegacyTx) GetGas() uint64 {
|
|
|
|
return tx.GasLimit
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetGasPrice returns the gas price field.
|
|
|
|
func (tx *LegacyTx) GetGasPrice() *big.Int {
|
|
|
|
if tx.GasPrice == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return tx.GasPrice.BigInt()
|
|
|
|
}
|
|
|
|
|
2021-07-30 11:40:17 +00:00
|
|
|
// GetGasTipCap returns the gas price field.
|
|
|
|
func (tx *LegacyTx) GetGasTipCap() *big.Int {
|
|
|
|
return tx.GetGasPrice()
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetGasFeeCap returns the gas price field.
|
|
|
|
func (tx *LegacyTx) GetGasFeeCap() *big.Int {
|
|
|
|
return tx.GetGasPrice()
|
|
|
|
}
|
|
|
|
|
2021-07-05 16:39:08 +00:00
|
|
|
// GetValue returns the tx amount.
|
|
|
|
func (tx *LegacyTx) GetValue() *big.Int {
|
|
|
|
if tx.Amount == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return tx.Amount.BigInt()
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNonce returns the account sequence for the transaction.
|
|
|
|
func (tx *LegacyTx) GetNonce() uint64 { return tx.Nonce }
|
|
|
|
|
|
|
|
// GetTo returns the pointer to the recipient address.
|
|
|
|
func (tx *LegacyTx) GetTo() *common.Address {
|
|
|
|
if tx.To == "" {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
to := common.HexToAddress(tx.To)
|
|
|
|
return &to
|
|
|
|
}
|
|
|
|
|
|
|
|
// AsEthereumData returns an AccessListTx transaction tx from the proto-formatted
|
|
|
|
// TxData defined on the Cosmos EVM.
|
|
|
|
func (tx *LegacyTx) AsEthereumData() ethtypes.TxData {
|
|
|
|
v, r, s := tx.GetRawSignatureValues()
|
|
|
|
return ðtypes.LegacyTx{
|
|
|
|
Nonce: tx.GetNonce(),
|
|
|
|
GasPrice: tx.GetGasPrice(),
|
|
|
|
Gas: tx.GetGas(),
|
|
|
|
To: tx.GetTo(),
|
|
|
|
Value: tx.GetValue(),
|
|
|
|
Data: tx.GetData(),
|
|
|
|
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 *LegacyTx) GetRawSignatureValues() (v, r, s *big.Int) {
|
|
|
|
return rawSignatureValues(tx.V, tx.R, tx.S)
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetSignatureValues sets the signature values to the transaction.
|
|
|
|
func (tx *LegacyTx) SetSignatureValues(_, 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()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate performs a stateless validation of the tx fields.
|
|
|
|
func (tx LegacyTx) Validate() error {
|
|
|
|
gasPrice := tx.GetGasPrice()
|
|
|
|
if gasPrice == nil {
|
2021-10-08 11:11:19 +00:00
|
|
|
return sdkerrors.Wrap(ErrInvalidGasPrice, "gas price cannot be nil")
|
2021-07-05 16:39:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if gasPrice.Sign() == -1 {
|
|
|
|
return sdkerrors.Wrapf(ErrInvalidGasPrice, "gas price cannot be negative %s", gasPrice)
|
|
|
|
}
|
|
|
|
|
|
|
|
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")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fee returns gasprice * gaslimit.
|
|
|
|
func (tx LegacyTx) Fee() *big.Int {
|
|
|
|
return fee(tx.GetGasPrice(), tx.GetGas())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cost returns amount + gasprice * gaslimit.
|
|
|
|
func (tx LegacyTx) Cost() *big.Int {
|
|
|
|
return cost(tx.Fee(), tx.GetValue())
|
|
|
|
}
|