laconicd/x/evm/types/utils.go

105 lines
2.7 KiB
Go
Raw Normal View History

package types
import (
"fmt"
"math/big"
2021-04-17 10:00:07 +00:00
"github.com/gogo/protobuf/proto"
2021-04-18 15:54:18 +00:00
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/ethereum/go-ethereum/crypto"
)
2018-11-28 22:19:22 +00:00
const maxBitLen = 256
var EmptyCodeHash = crypto.Keccak256(nil)
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
}
data := txMsgData.GetData()
if len(data) == 0 {
2021-04-18 15:54:18 +00:00
return &MsgEthereumTxResponse{}, nil
}
var res MsgEthereumTxResponse
err := proto.Unmarshal(data[0].GetData(), &res)
2021-04-18 15:54:18 +00:00
if err != nil {
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)
if err != nil {
2021-04-18 15:54:18 +00:00
return TransactionLogs{}, err
}
2021-04-18 15:54:18 +00:00
return logs, nil
}
// 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
}
// BinSearch execute the binary search and hone in on an executable gas limit
func BinSearch(lo, hi uint64, executable func(uint64) (bool, *MsgEthereumTxResponse, error)) (uint64, error) {
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
}
// SafeNewIntFromBigInt constructs Int from big.Int, return error if more than 256bits
func SafeNewIntFromBigInt(i *big.Int) (sdk.Int, error) {
if !IsValidInt256(i) {
return sdk.NewInt(0), fmt.Errorf("big int out of bound: %s", i)
}
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
}