|
| 1 | +package types |
| 2 | + |
| 3 | +import ( |
| 4 | + "math/big" |
| 5 | + |
| 6 | + errorsmod "cosmossdk.io/errors" |
| 7 | + sdkmath "cosmossdk.io/math" |
| 8 | + errortypes "github.com/cosmos/cosmos-sdk/types/errors" |
| 9 | + |
| 10 | + "github.com/ethereum/go-ethereum/common" |
| 11 | + ethtypes "github.com/ethereum/go-ethereum/core/types" |
| 12 | + |
| 13 | + "github.com/InjectiveLabs/injective-core/injective-chain/types" |
| 14 | +) |
| 15 | + |
| 16 | +func NewAccessListTx(tx *ethtypes.Transaction) (*AccessListTx, error) { |
| 17 | + txData := &AccessListTx{ |
| 18 | + Nonce: tx.Nonce(), |
| 19 | + Data: tx.Data(), |
| 20 | + GasLimit: tx.Gas(), |
| 21 | + } |
| 22 | + |
| 23 | + v, r, s := tx.RawSignatureValues() |
| 24 | + if to := tx.To(); to != nil { |
| 25 | + txData.To = to.Hex() |
| 26 | + } |
| 27 | + |
| 28 | + if tx.Value() != nil { |
| 29 | + amountInt, err := types.SafeNewIntFromBigInt(tx.Value()) |
| 30 | + if err != nil { |
| 31 | + return nil, err |
| 32 | + } |
| 33 | + txData.Amount = &amountInt |
| 34 | + } |
| 35 | + |
| 36 | + if tx.GasPrice() != nil { |
| 37 | + gasPriceInt, err := types.SafeNewIntFromBigInt(tx.GasPrice()) |
| 38 | + if err != nil { |
| 39 | + return nil, err |
| 40 | + } |
| 41 | + txData.GasPrice = &gasPriceInt |
| 42 | + } |
| 43 | + |
| 44 | + if tx.AccessList() != nil { |
| 45 | + al := tx.AccessList() |
| 46 | + txData.Accesses = NewAccessList(&al) |
| 47 | + } |
| 48 | + |
| 49 | + txData.SetSignatureValues(tx.ChainId(), v, r, s) |
| 50 | + return txData, nil |
| 51 | +} |
| 52 | + |
| 53 | +// TxType returns the tx type |
| 54 | +func (tx *AccessListTx) TxType() uint8 { |
| 55 | + return ethtypes.AccessListTxType |
| 56 | +} |
| 57 | + |
| 58 | +// Copy returns an instance with the same field values |
| 59 | +func (tx *AccessListTx) Copy() TxData { |
| 60 | + return &AccessListTx{ |
| 61 | + ChainID: tx.ChainID, |
| 62 | + Nonce: tx.Nonce, |
| 63 | + GasPrice: tx.GasPrice, |
| 64 | + GasLimit: tx.GasLimit, |
| 65 | + To: tx.To, |
| 66 | + Amount: tx.Amount, |
| 67 | + Data: common.CopyBytes(tx.Data), |
| 68 | + Accesses: tx.Accesses, |
| 69 | + V: common.CopyBytes(tx.V), |
| 70 | + R: common.CopyBytes(tx.R), |
| 71 | + S: common.CopyBytes(tx.S), |
| 72 | + } |
| 73 | +} |
| 74 | + |
| 75 | +// GetChainID returns the chain id field from the AccessListTx |
| 76 | +func (tx *AccessListTx) GetChainID() *big.Int { |
| 77 | + if tx.ChainID == nil { |
| 78 | + return nil |
| 79 | + } |
| 80 | + |
| 81 | + return tx.ChainID.BigInt() |
| 82 | +} |
| 83 | + |
| 84 | +// GetAccessList returns the AccessList field. |
| 85 | +func (tx *AccessListTx) GetAccessList() ethtypes.AccessList { |
| 86 | + if tx.Accesses == nil { |
| 87 | + return nil |
| 88 | + } |
| 89 | + return *tx.Accesses.ToEthAccessList() |
| 90 | +} |
| 91 | + |
| 92 | +// GetData returns the a copy of the input data bytes. |
| 93 | +func (tx *AccessListTx) GetData() []byte { |
| 94 | + return common.CopyBytes(tx.Data) |
| 95 | +} |
| 96 | + |
| 97 | +// GetGas returns the gas limit. |
| 98 | +func (tx *AccessListTx) GetGas() uint64 { |
| 99 | + return tx.GasLimit |
| 100 | +} |
| 101 | + |
| 102 | +// GetGasPrice returns the gas price field. |
| 103 | +func (tx *AccessListTx) GetGasPrice() *big.Int { |
| 104 | + if tx.GasPrice == nil { |
| 105 | + return nil |
| 106 | + } |
| 107 | + return tx.GasPrice.BigInt() |
| 108 | +} |
| 109 | + |
| 110 | +// GetGasTipCap returns the gas price field. |
| 111 | +func (tx *AccessListTx) GetGasTipCap() *big.Int { |
| 112 | + return tx.GetGasPrice() |
| 113 | +} |
| 114 | + |
| 115 | +// GetGasFeeCap returns the gas price field. |
| 116 | +func (tx *AccessListTx) GetGasFeeCap() *big.Int { |
| 117 | + return tx.GetGasPrice() |
| 118 | +} |
| 119 | + |
| 120 | +// GetValue returns the tx amount. |
| 121 | +func (tx *AccessListTx) GetValue() *big.Int { |
| 122 | + if tx.Amount == nil { |
| 123 | + return nil |
| 124 | + } |
| 125 | + |
| 126 | + return tx.Amount.BigInt() |
| 127 | +} |
| 128 | + |
| 129 | +// GetNonce returns the account sequence for the transaction. |
| 130 | +func (tx *AccessListTx) GetNonce() uint64 { return tx.Nonce } |
| 131 | + |
| 132 | +// GetTo returns the pointer to the recipient address. |
| 133 | +func (tx *AccessListTx) GetTo() *common.Address { |
| 134 | + if tx.To == "" { |
| 135 | + return nil |
| 136 | + } |
| 137 | + to := common.HexToAddress(tx.To) |
| 138 | + return &to |
| 139 | +} |
| 140 | + |
| 141 | +// AsEthereumData returns an AccessListTx transaction tx from the proto-formatted |
| 142 | +// TxData defined on the Cosmos EVM. |
| 143 | +func (tx *AccessListTx) AsEthereumData() ethtypes.TxData { |
| 144 | + v, r, s := tx.GetRawSignatureValues() |
| 145 | + return ðtypes.AccessListTx{ |
| 146 | + ChainID: tx.GetChainID(), |
| 147 | + Nonce: tx.GetNonce(), |
| 148 | + GasPrice: tx.GetGasPrice(), |
| 149 | + Gas: tx.GetGas(), |
| 150 | + To: tx.GetTo(), |
| 151 | + Value: tx.GetValue(), |
| 152 | + Data: tx.GetData(), |
| 153 | + AccessList: tx.GetAccessList(), |
| 154 | + V: v, |
| 155 | + R: r, |
| 156 | + S: s, |
| 157 | + } |
| 158 | +} |
| 159 | + |
| 160 | +// GetRawSignatureValues returns the V, R, S signature values of the transaction. |
| 161 | +// The return values should not be modified by the caller. |
| 162 | +func (tx *AccessListTx) GetRawSignatureValues() (v, r, s *big.Int) { |
| 163 | + return rawSignatureValues(tx.V, tx.R, tx.S) |
| 164 | +} |
| 165 | + |
| 166 | +// SetSignatureValues sets the signature values to the transaction. |
| 167 | +func (tx *AccessListTx) SetSignatureValues(chainID, v, r, s *big.Int) { |
| 168 | + if v != nil { |
| 169 | + tx.V = v.Bytes() |
| 170 | + } |
| 171 | + if r != nil { |
| 172 | + tx.R = r.Bytes() |
| 173 | + } |
| 174 | + if s != nil { |
| 175 | + tx.S = s.Bytes() |
| 176 | + } |
| 177 | + if chainID != nil { |
| 178 | + chainIDInt := sdkmath.NewIntFromBigInt(chainID) |
| 179 | + tx.ChainID = &chainIDInt |
| 180 | + } |
| 181 | +} |
| 182 | + |
| 183 | +// Validate performs a stateless validation of the tx fields. |
| 184 | +func (tx AccessListTx) Validate() error { |
| 185 | + gasPrice := tx.GetGasPrice() |
| 186 | + if gasPrice == nil { |
| 187 | + return errorsmod.Wrap(ErrInvalidGasPrice, "cannot be nil") |
| 188 | + } |
| 189 | + if !types.IsValidInt256(gasPrice) { |
| 190 | + return errorsmod.Wrap(ErrInvalidGasPrice, "out of bound") |
| 191 | + } |
| 192 | + |
| 193 | + if gasPrice.Sign() == -1 { |
| 194 | + return errorsmod.Wrapf(ErrInvalidGasPrice, "gas price cannot be negative %s", gasPrice) |
| 195 | + } |
| 196 | + |
| 197 | + amount := tx.GetValue() |
| 198 | + // Amount can be 0 |
| 199 | + if amount != nil && amount.Sign() == -1 { |
| 200 | + return errorsmod.Wrapf(ErrInvalidAmount, "amount cannot be negative %s", amount) |
| 201 | + } |
| 202 | + if !types.IsValidInt256(amount) { |
| 203 | + return errorsmod.Wrap(ErrInvalidAmount, "out of bound") |
| 204 | + } |
| 205 | + |
| 206 | + if !types.IsValidInt256(tx.Fee()) { |
| 207 | + return errorsmod.Wrap(ErrInvalidGasFee, "out of bound") |
| 208 | + } |
| 209 | + |
| 210 | + if tx.To != "" { |
| 211 | + if err := types.ValidateAddress(tx.To); err != nil { |
| 212 | + return errorsmod.Wrap(err, "invalid to address") |
| 213 | + } |
| 214 | + } |
| 215 | + |
| 216 | + if tx.GetChainID() == nil { |
| 217 | + return errorsmod.Wrap( |
| 218 | + errortypes.ErrInvalidChainID, |
| 219 | + "chain ID must be present on AccessList txs", |
| 220 | + ) |
| 221 | + } |
| 222 | + |
| 223 | + return nil |
| 224 | +} |
| 225 | + |
| 226 | +// Fee returns gasprice * gaslimit. |
| 227 | +func (tx AccessListTx) Fee() *big.Int { |
| 228 | + return fee(tx.GetGasPrice(), tx.GetGas()) |
| 229 | +} |
| 230 | + |
| 231 | +// Cost returns amount + gasprice * gaslimit. |
| 232 | +func (tx AccessListTx) Cost() *big.Int { |
| 233 | + return cost(tx.Fee(), tx.GetValue()) |
| 234 | +} |
| 235 | + |
| 236 | +// EffectiveGasPrice is the same as GasPrice for AccessListTx |
| 237 | +func (tx AccessListTx) EffectiveGasPrice(_ *big.Int) *big.Int { |
| 238 | + return tx.GetGasPrice() |
| 239 | +} |
| 240 | + |
| 241 | +// EffectiveFee is the same as Fee for AccessListTx |
| 242 | +func (tx AccessListTx) EffectiveFee(_ *big.Int) *big.Int { |
| 243 | + return tx.Fee() |
| 244 | +} |
| 245 | + |
| 246 | +// EffectiveCost is the same as Cost for AccessListTx |
| 247 | +func (tx AccessListTx) EffectiveCost(_ *big.Int) *big.Int { |
| 248 | + return tx.Cost() |
| 249 | +} |
0 commit comments