2020-06-04 10:40:21 +00:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
ethcmn "github.com/ethereum/go-ethereum/common"
|
|
|
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
2021-05-17 10:13:08 +00:00
|
|
|
|
2021-06-22 10:49:18 +00:00
|
|
|
ethermint "github.com/tharsis/ethermint/types"
|
2020-06-04 10:40:21 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// NewTransactionLogs creates a new NewTransactionLogs instance.
|
2021-04-17 10:00:07 +00:00
|
|
|
func NewTransactionLogs(hash ethcmn.Hash, logs []*Log) TransactionLogs { // nolint: interfacer
|
2020-06-04 10:40:21 +00:00
|
|
|
return TransactionLogs{
|
2021-01-06 20:56:40 +00:00
|
|
|
Hash: hash.String(),
|
2020-06-04 10:40:21 +00:00
|
|
|
Logs: logs,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-17 10:00:07 +00:00
|
|
|
// NewTransactionLogsFromEth creates a new NewTransactionLogs instance using []*ethtypes.Log.
|
|
|
|
func NewTransactionLogsFromEth(hash ethcmn.Hash, ethlogs []*ethtypes.Log) TransactionLogs { // nolint: interfacer
|
|
|
|
return TransactionLogs{
|
|
|
|
Hash: hash.String(),
|
2021-06-08 11:11:37 +00:00
|
|
|
Logs: NewLogsFromEth(ethlogs),
|
2021-04-17 10:00:07 +00:00
|
|
|
}
|
2020-06-04 10:40:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Validate performs a basic validation of a GenesisAccount fields.
|
|
|
|
func (tx TransactionLogs) Validate() error {
|
2021-05-31 14:54:59 +00:00
|
|
|
if ethermint.IsEmptyHash(tx.Hash) {
|
2021-01-06 20:56:40 +00:00
|
|
|
return fmt.Errorf("hash cannot be the empty %s", tx.Hash)
|
2020-06-04 10:40:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for i, log := range tx.Logs {
|
2021-04-17 10:00:07 +00:00
|
|
|
if log == nil {
|
|
|
|
return fmt.Errorf("log %d cannot be nil", i)
|
|
|
|
}
|
|
|
|
if err := log.Validate(); err != nil {
|
2020-06-04 10:40:21 +00:00
|
|
|
return fmt.Errorf("invalid log %d: %w", i, err)
|
|
|
|
}
|
2021-04-17 10:00:07 +00:00
|
|
|
if log.TxHash != tx.Hash {
|
|
|
|
return fmt.Errorf("log tx hash mismatch (%s ≠ %s)", log.TxHash, tx.Hash)
|
2020-06-04 10:40:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-04-17 10:00:07 +00:00
|
|
|
// EthLogs returns the Ethereum type Logs from the Transaction Logs.
|
|
|
|
func (tx TransactionLogs) EthLogs() []*ethtypes.Log {
|
|
|
|
return LogsToEthereum(tx.Logs)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate performs a basic validation of an ethereum Log fields.
|
|
|
|
func (log *Log) Validate() error {
|
2021-05-17 10:13:08 +00:00
|
|
|
if err := ethermint.ValidateAddress(log.Address); err != nil {
|
|
|
|
return fmt.Errorf("invalid log address %w", err)
|
2020-06-04 10:40:21 +00:00
|
|
|
}
|
2021-05-17 10:13:08 +00:00
|
|
|
if ethermint.IsEmptyHash(log.BlockHash) {
|
2021-04-17 10:00:07 +00:00
|
|
|
return fmt.Errorf("block hash cannot be the empty %s", log.BlockHash)
|
2020-06-04 10:40:21 +00:00
|
|
|
}
|
|
|
|
if log.BlockNumber == 0 {
|
|
|
|
return errors.New("block number cannot be zero")
|
|
|
|
}
|
2021-05-17 10:13:08 +00:00
|
|
|
if ethermint.IsEmptyHash(log.TxHash) {
|
2021-04-17 10:00:07 +00:00
|
|
|
return fmt.Errorf("tx hash cannot be the empty %s", log.TxHash)
|
2020-06-04 10:40:21 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2021-04-17 10:00:07 +00:00
|
|
|
|
2021-08-17 14:11:26 +00:00
|
|
|
// ToEthereum returns the Ethereum type Log from a Ethermint proto compatible Log.
|
2021-04-17 10:00:07 +00:00
|
|
|
func (log *Log) ToEthereum() *ethtypes.Log {
|
2021-06-02 08:06:12 +00:00
|
|
|
var topics []ethcmn.Hash // nolint: prealloc
|
2021-04-17 10:00:07 +00:00
|
|
|
for i := range log.Topics {
|
2021-06-02 08:06:12 +00:00
|
|
|
topics = append(topics, ethcmn.HexToHash(log.Topics[i]))
|
2021-04-17 10:00:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ðtypes.Log{
|
|
|
|
Address: ethcmn.HexToAddress(log.Address),
|
|
|
|
Topics: topics,
|
|
|
|
Data: log.Data,
|
|
|
|
BlockNumber: log.BlockNumber,
|
|
|
|
TxHash: ethcmn.HexToHash(log.TxHash),
|
|
|
|
TxIndex: uint(log.TxIndex),
|
2021-04-18 15:54:18 +00:00
|
|
|
Index: uint(log.Index),
|
2021-04-17 10:00:07 +00:00
|
|
|
BlockHash: ethcmn.HexToHash(log.BlockHash),
|
|
|
|
Removed: log.Removed,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-08 11:11:37 +00:00
|
|
|
func NewLogsFromEth(ethlogs []*ethtypes.Log) []*Log {
|
2021-06-08 17:10:29 +00:00
|
|
|
var logs []*Log // nolint: prealloc
|
2021-06-08 11:11:37 +00:00
|
|
|
for _, ethlog := range ethlogs {
|
|
|
|
logs = append(logs, NewLogFromEth(ethlog))
|
|
|
|
}
|
|
|
|
|
|
|
|
return logs
|
|
|
|
}
|
|
|
|
|
2021-04-17 10:00:07 +00:00
|
|
|
// LogsToEthereum casts the Ethermint Logs to a slice of Ethereum Logs.
|
|
|
|
func LogsToEthereum(logs []*Log) []*ethtypes.Log {
|
2021-06-02 08:06:12 +00:00
|
|
|
var ethLogs []*ethtypes.Log // nolint: prealloc
|
2021-04-17 10:00:07 +00:00
|
|
|
for i := range logs {
|
2021-06-02 08:06:12 +00:00
|
|
|
ethLogs = append(ethLogs, logs[i].ToEthereum())
|
2021-04-17 10:00:07 +00:00
|
|
|
}
|
|
|
|
return ethLogs
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewLogFromEth creates a new Log instance from a Ethereum type Log.
|
|
|
|
func NewLogFromEth(log *ethtypes.Log) *Log {
|
2021-06-02 08:06:12 +00:00
|
|
|
var topics []string // nolint: prealloc
|
|
|
|
for _, topic := range log.Topics {
|
|
|
|
topics = append(topics, topic.String())
|
2021-04-17 10:00:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &Log{
|
|
|
|
Address: log.Address.String(),
|
|
|
|
Topics: topics,
|
|
|
|
Data: log.Data,
|
|
|
|
BlockNumber: log.BlockNumber,
|
|
|
|
TxHash: log.TxHash.String(),
|
|
|
|
TxIndex: uint64(log.TxIndex),
|
2021-07-26 08:40:59 +00:00
|
|
|
Index: uint64(log.Index),
|
2021-04-17 10:00:07 +00:00
|
|
|
BlockHash: log.BlockHash.String(),
|
|
|
|
Removed: log.Removed,
|
|
|
|
}
|
|
|
|
}
|