2018-08-09 01:06:34 +00:00
|
|
|
package types
|
|
|
|
|
|
|
|
import (
|
2021-07-12 17:42:53 +00:00
|
|
|
"fmt"
|
2021-10-26 11:13:27 +00:00
|
|
|
"math/big"
|
2021-07-12 17:42:53 +00:00
|
|
|
|
2021-04-17 10:00:07 +00:00
|
|
|
"github.com/gogo/protobuf/proto"
|
2020-07-02 15:19:48 +00:00
|
|
|
|
2021-04-18 15:54:18 +00:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2021-06-21 13:09:23 +00:00
|
|
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
2018-08-09 01:06:34 +00:00
|
|
|
|
2021-06-08 17:10:29 +00:00
|
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
|
|
)
|
2018-11-28 22:19:22 +00:00
|
|
|
|
2021-10-26 11:13:27 +00:00
|
|
|
const maxBitLen = 256
|
|
|
|
|
2021-06-08 17:10:29 +00:00
|
|
|
var EmptyCodeHash = crypto.Keccak256(nil)
|
2019-10-22 16:40:34 +00:00
|
|
|
|
2021-04-17 10:00:07 +00:00
|
|
|
// DecodeTxResponse decodes an protobuf-encoded byte slice into TxResponse
|
2021-04-18 15:54:18 +00:00
|
|
|
func DecodeTxResponse(in []byte) (*MsgEthereumTxResponse, error) {
|
|
|
|
var txMsgData sdk.TxMsgData
|
|
|
|
if err := proto.Unmarshal(in, &txMsgData); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-06-21 13:09:23 +00:00
|
|
|
data := txMsgData.GetData()
|
|
|
|
if len(data) == 0 {
|
2021-04-18 15:54:18 +00:00
|
|
|
return &MsgEthereumTxResponse{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var res MsgEthereumTxResponse
|
|
|
|
|
2021-06-21 13:09:23 +00:00
|
|
|
err := proto.Unmarshal(data[0].GetData(), &res)
|
2021-04-18 15:54:18 +00:00
|
|
|
if err != nil {
|
2021-06-21 13:09:23 +00:00
|
|
|
return nil, sdkerrors.Wrap(err, "failed to unmarshal tx response message data")
|
2021-04-18 15:54:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return &res, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// EncodeTransactionLogs encodes TransactionLogs slice into a protobuf-encoded byte slice.
|
|
|
|
func EncodeTransactionLogs(res *TransactionLogs) ([]byte, error) {
|
|
|
|
return proto.Marshal(res)
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodeTxResponse decodes an protobuf-encoded byte slice into TransactionLogs
|
|
|
|
func DecodeTransactionLogs(data []byte) (TransactionLogs, error) {
|
|
|
|
var logs TransactionLogs
|
|
|
|
err := proto.Unmarshal(data, &logs)
|
2020-04-01 18:49:21 +00:00
|
|
|
if err != nil {
|
2021-04-18 15:54:18 +00:00
|
|
|
return TransactionLogs{}, err
|
2019-10-22 16:40:34 +00:00
|
|
|
}
|
2021-04-18 15:54:18 +00:00
|
|
|
return logs, nil
|
2020-04-01 18:49:21 +00:00
|
|
|
}
|
2021-07-12 17:42:53 +00:00
|
|
|
|
|
|
|
// UnwrapEthereumMsg extract MsgEthereumTx from wrapping sdk.Tx
|
|
|
|
func UnwrapEthereumMsg(tx *sdk.Tx) (*MsgEthereumTx, error) {
|
|
|
|
if tx == nil {
|
|
|
|
return nil, fmt.Errorf("invalid tx: nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
if len((*tx).GetMsgs()) != 1 {
|
|
|
|
return nil, fmt.Errorf("invalid tx type: %T", tx)
|
|
|
|
}
|
|
|
|
msg, ok := (*tx).GetMsgs()[0].(*MsgEthereumTx)
|
|
|
|
if !ok {
|
|
|
|
return nil, fmt.Errorf("invalid tx type: %T", tx)
|
|
|
|
}
|
|
|
|
|
|
|
|
return msg, nil
|
|
|
|
}
|
2021-07-19 15:19:23 +00:00
|
|
|
|
|
|
|
// BinSearch execute the binary search and hone in on an executable gas limit
|
2021-09-05 11:03:06 +00:00
|
|
|
func BinSearch(lo, hi uint64, executable func(uint64) (bool, *MsgEthereumTxResponse, error)) (uint64, error) {
|
2021-07-19 15:19:23 +00:00
|
|
|
for lo+1 < hi {
|
|
|
|
mid := (hi + lo) / 2
|
|
|
|
failed, _, err := executable(mid)
|
|
|
|
// If the error is not nil(consensus error), it means the provided message
|
|
|
|
// call or transaction will never be accepted no matter how much gas it is
|
|
|
|
// assigned. Return the error directly, don't struggle any more.
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
if failed {
|
|
|
|
lo = mid
|
|
|
|
} else {
|
|
|
|
hi = mid
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return hi, nil
|
|
|
|
}
|
2021-10-26 11:13:27 +00:00
|
|
|
|
|
|
|
// SafeNewIntFromBigInt constructs Int from big.Int, return error if more than 256bits
|
|
|
|
func SafeNewIntFromBigInt(i *big.Int) (sdk.Int, error) {
|
|
|
|
if !IsValidInt256(i) {
|
2021-11-14 13:34:10 +00:00
|
|
|
return sdk.NewInt(0), fmt.Errorf("big int out of bound: %s", i)
|
2021-10-26 11:13:27 +00:00
|
|
|
}
|
|
|
|
return sdk.NewIntFromBigInt(i), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsValidInt256 check the bound of 256 bit number
|
|
|
|
func IsValidInt256(i *big.Int) bool {
|
|
|
|
return i == nil || i.BitLen() <= maxBitLen
|
|
|
|
}
|