!feat(evm): Reject not replay-protected tx to prevent replay attack (#1124)
* Reject not replay-protected tx to prevent replay attack Closes: #1122 - reject such txs in ante handler * add reject unprotected parameter * Update CHANGELOG.md * Apply suggestions from code review Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * pr suggestions * add unit test case * Reject not replay-protected tx to prevent replay attack Closes: #1122 - reject such txs in ante handler add reject unprotected parameter Update CHANGELOG.md Apply suggestions from code review Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> pr suggestions add unit test case use var * add migrations * Apply suggestions from code review Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> * rename * update comments Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
82835307c7
commit
8f932ddc6a
@ -38,6 +38,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### State Machine Breaking
|
||||||
|
|
||||||
|
* (evm) [tharsis#1124](https://github.com/tharsis/ethermint/pull/1124) Reject non-replay-protected tx in ante handler to prevent replay attack
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* (evm) [tharsis#1118](https://github.com/tharsis/ethermint/pull/1118) Fix `Type()` `Account` method `EmptyCodeHash` comparison
|
* (evm) [tharsis#1118](https://github.com/tharsis/ethermint/pull/1118) Fix `Type()` `Account` method `EmptyCodeHash` comparison
|
||||||
|
@ -50,7 +50,12 @@ func (esvd EthSigVerificationDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, s
|
|||||||
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "invalid message type %T, expected %T", msg, (*evmtypes.MsgEthereumTx)(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
sender, err := signer.Sender(msgEthTx.AsTransaction())
|
ethTx := msgEthTx.AsTransaction()
|
||||||
|
if params.RejectUnprotectedTx && !ethTx.Protected() {
|
||||||
|
return ctx, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "eth tx is not replay-protected")
|
||||||
|
}
|
||||||
|
|
||||||
|
sender, err := signer.Sender(ethTx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx, sdkerrors.Wrapf(
|
return ctx, sdkerrors.Wrapf(
|
||||||
sdkerrors.ErrorInvalidSigner,
|
sdkerrors.ErrorInvalidSigner,
|
||||||
|
@ -15,7 +15,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestEthSigVerificationDecorator() {
|
func (suite AnteTestSuite) TestEthSigVerificationDecorator() {
|
||||||
dec := ante.NewEthSigVerificationDecorator(suite.app.EvmKeeper)
|
|
||||||
addr, privKey := tests.NewAddrKey()
|
addr, privKey := tests.NewAddrKey()
|
||||||
|
|
||||||
signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
signedTx := evmtypes.NewTxContract(suite.app.EvmKeeper.ChainID(), 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
@ -23,25 +22,39 @@ func (suite AnteTestSuite) TestEthSigVerificationDecorator() {
|
|||||||
err := signedTx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
err := signedTx.Sign(suite.ethSigner, tests.NewSigner(privKey))
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
unprotectedTx := evmtypes.NewTxContract(nil, 1, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil)
|
||||||
|
unprotectedTx.From = addr.Hex()
|
||||||
|
err = unprotectedTx.Sign(ethtypes.HomesteadSigner{}, tests.NewSigner(privKey))
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
tx sdk.Tx
|
tx sdk.Tx
|
||||||
|
rejectUnprotectedTx bool
|
||||||
reCheckTx bool
|
reCheckTx bool
|
||||||
expPass bool
|
expPass bool
|
||||||
}{
|
}{
|
||||||
{"ReCheckTx", &invalidTx{}, true, false},
|
{"ReCheckTx", &invalidTx{}, true, true, false},
|
||||||
{"invalid transaction type", &invalidTx{}, false, false},
|
{"invalid transaction type", &invalidTx{}, true, false, false},
|
||||||
{
|
{
|
||||||
"invalid sender",
|
"invalid sender",
|
||||||
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &addr, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
|
evmtypes.NewTx(suite.app.EvmKeeper.ChainID(), 1, &addr, big.NewInt(10), 1000, big.NewInt(1), nil, nil, nil, nil),
|
||||||
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
{"successful signature verification", signedTx, false, true},
|
{"successful signature verification", signedTx, true, false, true},
|
||||||
|
{"invalid, not replay-protected", unprotectedTx, true, false, false},
|
||||||
|
{"successful, don't reject unprotected", unprotectedTx, false, false, true},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
suite.Run(tc.name, func() {
|
suite.Run(tc.name, func() {
|
||||||
|
suite.evmParamsOption = func(params *evmtypes.Params) {
|
||||||
|
params.RejectUnprotectedTx = tc.rejectUnprotectedTx
|
||||||
|
}
|
||||||
|
suite.SetupTest()
|
||||||
|
dec := ante.NewEthSigVerificationDecorator(suite.app.EvmKeeper)
|
||||||
_, err := dec.AnteHandle(suite.ctx.WithIsReCheckTx(tc.reCheckTx), tc.tx, false, NextFn)
|
_, err := dec.AnteHandle(suite.ctx.WithIsReCheckTx(tc.reCheckTx), tc.tx, false, NextFn)
|
||||||
|
|
||||||
if tc.expPass {
|
if tc.expPass {
|
||||||
@ -51,6 +64,7 @@ func (suite AnteTestSuite) TestEthSigVerificationDecorator() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
suite.evmParamsOption = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
func (suite AnteTestSuite) TestNewEthAccountVerificationDecorator() {
|
||||||
|
@ -76,6 +76,7 @@ func (suite *AnteTestSuite) SetupTest() {
|
|||||||
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
genesis[feemarkettypes.ModuleName] = app.AppCodec().MustMarshalJSON(feemarketGenesis)
|
||||||
}
|
}
|
||||||
evmGenesis := evmtypes.DefaultGenesisState()
|
evmGenesis := evmtypes.DefaultGenesisState()
|
||||||
|
evmGenesis.Params.RejectUnprotectedTx = true
|
||||||
if !suite.enableLondonHF {
|
if !suite.enableLondonHF {
|
||||||
maxInt := sdk.NewInt(math.MaxInt64)
|
maxInt := sdk.NewInt(math.MaxInt64)
|
||||||
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
|
evmGenesis.Params.ChainConfig.LondonBlock = &maxInt
|
||||||
|
@ -227,6 +227,7 @@ Params defines the EVM module parameters
|
|||||||
| `enable_call` | [bool](#bool) | | enable call toggles state transitions that use the vm.Call function |
|
| `enable_call` | [bool](#bool) | | enable call toggles state transitions that use the vm.Call function |
|
||||||
| `extra_eips` | [int64](#int64) | repeated | extra eips defines the additional EIPs for the vm.Config |
|
| `extra_eips` | [int64](#int64) | repeated | extra eips defines the additional EIPs for the vm.Config |
|
||||||
| `chain_config` | [ChainConfig](#ethermint.evm.v1.ChainConfig) | | chain config defines the EVM chain configuration parameters |
|
| `chain_config` | [ChainConfig](#ethermint.evm.v1.ChainConfig) | | chain config defines the EVM chain configuration parameters |
|
||||||
|
| `reject_unprotected_tx` | [bool](#bool) | | reject replay-unprotected transactions |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -443,6 +444,7 @@ DynamicFeeTx is the data of EIP-1559 dinamic fee transactions.
|
|||||||
|
|
||||||
### LegacyTx
|
### LegacyTx
|
||||||
LegacyTx is the transaction data of regular Ethereum transactions.
|
LegacyTx is the transaction data of regular Ethereum transactions.
|
||||||
|
NOTE: All non-protected transactions (i.e non EIP155 signed) will fail if the RejectUnprotectedTx parameter is enabled.
|
||||||
|
|
||||||
|
|
||||||
| Field | Type | Label | Description |
|
| Field | Type | Label | Description |
|
||||||
|
@ -24,6 +24,8 @@ message Params {
|
|||||||
(gogoproto.moretags) = "yaml:\"chain_config\"",
|
(gogoproto.moretags) = "yaml:\"chain_config\"",
|
||||||
(gogoproto.nullable) = false
|
(gogoproto.nullable) = false
|
||||||
];
|
];
|
||||||
|
// reject replay-unprotected transactions
|
||||||
|
bool reject_unprotected_tx = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int values
|
// ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int values
|
||||||
|
@ -36,6 +36,7 @@ message MsgEthereumTx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// LegacyTx is the transaction data of regular Ethereum transactions.
|
// LegacyTx is the transaction data of regular Ethereum transactions.
|
||||||
|
// NOTE: All non-protected transactions (i.e non EIP155 signed) will fail if the RejectUnprotectedTx parameter is enabled.
|
||||||
message LegacyTx {
|
message LegacyTx {
|
||||||
option (gogoproto.goproto_getters) = false;
|
option (gogoproto.goproto_getters) = false;
|
||||||
option (cosmos_proto.implements_interface) = "TxData";
|
option (cosmos_proto.implements_interface) = "TxData";
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
package keeper
|
package keeper
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
v2 "github.com/tharsis/ethermint/x/evm/migrations/v2"
|
||||||
|
)
|
||||||
|
|
||||||
// Migrator is a struct for handling in-place store migrations.
|
// Migrator is a struct for handling in-place store migrations.
|
||||||
type Migrator struct {
|
type Migrator struct {
|
||||||
keeper Keeper
|
keeper Keeper
|
||||||
@ -11,3 +16,8 @@ func NewMigrator(keeper Keeper) Migrator {
|
|||||||
keeper: keeper,
|
keeper: keeper,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Migrate1to2 migrates the store from consensus version v1 to v2
|
||||||
|
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
|
||||||
|
return v2.MigrateStore(ctx, &m.keeper.paramSpace)
|
||||||
|
}
|
||||||
|
19
x/evm/migrations/v2/migrate.go
Normal file
19
x/evm/migrations/v2/migrate.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
|
"github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MigrateStore add the default RejectUnprotected parameter.
|
||||||
|
func MigrateStore(ctx sdk.Context, paramstore *paramtypes.Subspace) error {
|
||||||
|
if !paramstore.HasKeyTable() {
|
||||||
|
ps := paramstore.WithKeyTable(types.ParamKeyTable())
|
||||||
|
paramstore = &ps
|
||||||
|
}
|
||||||
|
|
||||||
|
// add RejectUnprotected
|
||||||
|
paramstore.Set(ctx, types.ParamStoreKeyRejectUnprotectedTx, types.DefaultParams().RejectUnprotectedTx)
|
||||||
|
return nil
|
||||||
|
}
|
47
x/evm/migrations/v2/migrate_test.go
Normal file
47
x/evm/migrations/v2/migrate_test.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package v2_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/testutil"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/encoding"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/app"
|
||||||
|
v2 "github.com/tharsis/ethermint/x/evm/migrations/v2"
|
||||||
|
v2types "github.com/tharsis/ethermint/x/evm/migrations/v2/types"
|
||||||
|
"github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMigrateStore(t *testing.T) {
|
||||||
|
encCfg := encoding.MakeConfig(app.ModuleBasics)
|
||||||
|
feemarketKey := sdk.NewKVStoreKey(types.StoreKey)
|
||||||
|
tFeeMarketKey := sdk.NewTransientStoreKey(fmt.Sprintf("%s_test", types.StoreKey))
|
||||||
|
ctx := testutil.DefaultContext(feemarketKey, tFeeMarketKey)
|
||||||
|
paramstore := paramtypes.NewSubspace(
|
||||||
|
encCfg.Marshaler, encCfg.Amino, feemarketKey, tFeeMarketKey, "evm",
|
||||||
|
).WithKeyTable(v2types.ParamKeyTable())
|
||||||
|
|
||||||
|
params := v2types.DefaultParams()
|
||||||
|
paramstore.SetParamSet(ctx, ¶ms)
|
||||||
|
|
||||||
|
require.Panics(t, func() {
|
||||||
|
var result bool
|
||||||
|
paramstore.Get(ctx, types.ParamStoreKeyRejectUnprotectedTx, &result)
|
||||||
|
})
|
||||||
|
|
||||||
|
paramstore = paramtypes.NewSubspace(
|
||||||
|
encCfg.Marshaler, encCfg.Amino, feemarketKey, tFeeMarketKey, "evm",
|
||||||
|
).WithKeyTable(types.ParamKeyTable())
|
||||||
|
err := v2.MigrateStore(ctx, ¶mstore)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var result bool
|
||||||
|
paramstore.Get(ctx, types.ParamStoreKeyRejectUnprotectedTx, &result)
|
||||||
|
require.Equal(t, types.DefaultRejectUnprotectedTx, result)
|
||||||
|
}
|
165
x/evm/migrations/v2/types/chain_config.go
Normal file
165
x/evm/migrations/v2/types/chain_config.go
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/x/evm/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EthereumConfig returns an Ethereum ChainConfig for EVM state transitions.
|
||||||
|
// All the negative or nil values are converted to nil
|
||||||
|
func (cc ChainConfig) EthereumConfig(chainID *big.Int) *params.ChainConfig {
|
||||||
|
return ¶ms.ChainConfig{
|
||||||
|
ChainID: chainID,
|
||||||
|
HomesteadBlock: getBlockValue(cc.HomesteadBlock),
|
||||||
|
DAOForkBlock: getBlockValue(cc.DAOForkBlock),
|
||||||
|
DAOForkSupport: cc.DAOForkSupport,
|
||||||
|
EIP150Block: getBlockValue(cc.EIP150Block),
|
||||||
|
EIP150Hash: common.HexToHash(cc.EIP150Hash),
|
||||||
|
EIP155Block: getBlockValue(cc.EIP155Block),
|
||||||
|
EIP158Block: getBlockValue(cc.EIP158Block),
|
||||||
|
ByzantiumBlock: getBlockValue(cc.ByzantiumBlock),
|
||||||
|
ConstantinopleBlock: getBlockValue(cc.ConstantinopleBlock),
|
||||||
|
PetersburgBlock: getBlockValue(cc.PetersburgBlock),
|
||||||
|
IstanbulBlock: getBlockValue(cc.IstanbulBlock),
|
||||||
|
MuirGlacierBlock: getBlockValue(cc.MuirGlacierBlock),
|
||||||
|
BerlinBlock: getBlockValue(cc.BerlinBlock),
|
||||||
|
LondonBlock: getBlockValue(cc.LondonBlock),
|
||||||
|
ArrowGlacierBlock: getBlockValue(cc.ArrowGlacierBlock),
|
||||||
|
MergeForkBlock: getBlockValue(cc.MergeForkBlock),
|
||||||
|
TerminalTotalDifficulty: nil,
|
||||||
|
Ethash: nil,
|
||||||
|
Clique: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultChainConfig returns default evm parameters.
|
||||||
|
func DefaultChainConfig() ChainConfig {
|
||||||
|
homesteadBlock := sdk.ZeroInt()
|
||||||
|
daoForkBlock := sdk.ZeroInt()
|
||||||
|
eip150Block := sdk.ZeroInt()
|
||||||
|
eip155Block := sdk.ZeroInt()
|
||||||
|
eip158Block := sdk.ZeroInt()
|
||||||
|
byzantiumBlock := sdk.ZeroInt()
|
||||||
|
constantinopleBlock := sdk.ZeroInt()
|
||||||
|
petersburgBlock := sdk.ZeroInt()
|
||||||
|
istanbulBlock := sdk.ZeroInt()
|
||||||
|
muirGlacierBlock := sdk.ZeroInt()
|
||||||
|
berlinBlock := sdk.ZeroInt()
|
||||||
|
londonBlock := sdk.ZeroInt()
|
||||||
|
arrowGlacierBlock := sdk.ZeroInt()
|
||||||
|
mergeForkBlock := sdk.ZeroInt()
|
||||||
|
|
||||||
|
return ChainConfig{
|
||||||
|
HomesteadBlock: &homesteadBlock,
|
||||||
|
DAOForkBlock: &daoForkBlock,
|
||||||
|
DAOForkSupport: true,
|
||||||
|
EIP150Block: &eip150Block,
|
||||||
|
EIP150Hash: common.Hash{}.String(),
|
||||||
|
EIP155Block: &eip155Block,
|
||||||
|
EIP158Block: &eip158Block,
|
||||||
|
ByzantiumBlock: &byzantiumBlock,
|
||||||
|
ConstantinopleBlock: &constantinopleBlock,
|
||||||
|
PetersburgBlock: &petersburgBlock,
|
||||||
|
IstanbulBlock: &istanbulBlock,
|
||||||
|
MuirGlacierBlock: &muirGlacierBlock,
|
||||||
|
BerlinBlock: &berlinBlock,
|
||||||
|
LondonBlock: &londonBlock,
|
||||||
|
ArrowGlacierBlock: &arrowGlacierBlock,
|
||||||
|
MergeForkBlock: &mergeForkBlock,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBlockValue(block *sdk.Int) *big.Int {
|
||||||
|
if block == nil || block.IsNegative() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return block.BigInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate performs a basic validation of the ChainConfig params. The function will return an error
|
||||||
|
// if any of the block values is uninitialized (i.e nil) or if the EIP150Hash is an invalid hash.
|
||||||
|
func (cc ChainConfig) Validate() error {
|
||||||
|
if err := validateBlock(cc.HomesteadBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "homesteadBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.DAOForkBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "daoForkBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.EIP150Block); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "eip150Block")
|
||||||
|
}
|
||||||
|
if err := validateHash(cc.EIP150Hash); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.EIP155Block); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "eip155Block")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.EIP158Block); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "eip158Block")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.ByzantiumBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "byzantiumBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.ConstantinopleBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "constantinopleBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.PetersburgBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "petersburgBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.IstanbulBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "istanbulBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.MuirGlacierBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "muirGlacierBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.BerlinBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "berlinBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.LondonBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "londonBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.ArrowGlacierBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "arrowGlacierBlock")
|
||||||
|
}
|
||||||
|
if err := validateBlock(cc.MergeForkBlock); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "mergeForkBlock")
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: chain ID is not needed to check config order
|
||||||
|
if err := cc.EthereumConfig(nil).CheckConfigForkOrder(); err != nil {
|
||||||
|
return sdkerrors.Wrap(err, "invalid config fork order")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateHash(hex string) error {
|
||||||
|
if hex != "" && strings.TrimSpace(hex) == "" {
|
||||||
|
return sdkerrors.Wrap(types.ErrInvalidChainConfig, "hash cannot be blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateBlock(block *sdk.Int) error {
|
||||||
|
// nil value means that the fork has not yet been applied
|
||||||
|
if block == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if block.IsNegative() {
|
||||||
|
return sdkerrors.Wrapf(
|
||||||
|
types.ErrInvalidChainConfig, "block value cannot be negative: %s", block,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
3781
x/evm/migrations/v2/types/evm.pb.go
generated
Normal file
3781
x/evm/migrations/v2/types/evm.pb.go
generated
Normal file
File diff suppressed because it is too large
Load Diff
145
x/evm/migrations/v2/types/params.go
Normal file
145
x/evm/migrations/v2/types/params.go
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||||
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
|
"github.com/tharsis/ethermint/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ paramtypes.ParamSet = &Params{}
|
||||||
|
|
||||||
|
const (
|
||||||
|
DefaultEVMDenom = types.AttoPhoton
|
||||||
|
)
|
||||||
|
|
||||||
|
// DefaultMinGasMultiplier is 0.5 or 50%
|
||||||
|
var DefaultMinGasMultiplier = sdk.NewDecWithPrec(50, 2)
|
||||||
|
|
||||||
|
// Parameter keys
|
||||||
|
var (
|
||||||
|
ParamStoreKeyEVMDenom = []byte("EVMDenom")
|
||||||
|
ParamStoreKeyEnableCreate = []byte("EnableCreate")
|
||||||
|
ParamStoreKeyEnableCall = []byte("EnableCall")
|
||||||
|
ParamStoreKeyExtraEIPs = []byte("EnableExtraEIPs")
|
||||||
|
ParamStoreKeyChainConfig = []byte("ChainConfig")
|
||||||
|
|
||||||
|
// AvailableExtraEIPs define the list of all EIPs that can be enabled by the
|
||||||
|
// EVM interpreter. These EIPs are applied in order and can override the
|
||||||
|
// instruction sets from the latest hard fork enabled by the ChainConfig. For
|
||||||
|
// more info check:
|
||||||
|
// https://github.com/ethereum/go-ethereum/blob/master/core/vm/interpreter.go#L97
|
||||||
|
AvailableExtraEIPs = []int64{1344, 1884, 2200, 2929, 3198, 3529}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParamKeyTable returns the parameter key table.
|
||||||
|
func ParamKeyTable() paramtypes.KeyTable {
|
||||||
|
return paramtypes.NewKeyTable().RegisterParamSet(&Params{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewParams creates a new Params instance
|
||||||
|
func NewParams(evmDenom string, enableCreate, enableCall bool, config ChainConfig, extraEIPs ...int64) Params {
|
||||||
|
return Params{
|
||||||
|
EvmDenom: evmDenom,
|
||||||
|
EnableCreate: enableCreate,
|
||||||
|
EnableCall: enableCall,
|
||||||
|
ExtraEIPs: extraEIPs,
|
||||||
|
ChainConfig: config,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultParams returns default evm parameters
|
||||||
|
// ExtraEIPs is empty to prevent overriding the latest hard fork instruction set
|
||||||
|
func DefaultParams() Params {
|
||||||
|
return Params{
|
||||||
|
EvmDenom: DefaultEVMDenom,
|
||||||
|
EnableCreate: true,
|
||||||
|
EnableCall: true,
|
||||||
|
ChainConfig: DefaultChainConfig(),
|
||||||
|
ExtraEIPs: nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParamSetPairs returns the parameter set pairs.
|
||||||
|
func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
|
||||||
|
return paramtypes.ParamSetPairs{
|
||||||
|
paramtypes.NewParamSetPair(ParamStoreKeyEVMDenom, &p.EvmDenom, validateEVMDenom),
|
||||||
|
paramtypes.NewParamSetPair(ParamStoreKeyEnableCreate, &p.EnableCreate, validateBool),
|
||||||
|
paramtypes.NewParamSetPair(ParamStoreKeyEnableCall, &p.EnableCall, validateBool),
|
||||||
|
paramtypes.NewParamSetPair(ParamStoreKeyExtraEIPs, &p.ExtraEIPs, validateEIPs),
|
||||||
|
paramtypes.NewParamSetPair(ParamStoreKeyChainConfig, &p.ChainConfig, validateChainConfig),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate performs basic validation on evm parameters.
|
||||||
|
func (p Params) Validate() error {
|
||||||
|
if err := sdk.ValidateDenom(p.EvmDenom); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateEIPs(p.ExtraEIPs); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return p.ChainConfig.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// EIPs returns the ExtraEips as a int slice
|
||||||
|
func (p Params) EIPs() []int {
|
||||||
|
eips := make([]int, len(p.ExtraEIPs))
|
||||||
|
for i, eip := range p.ExtraEIPs {
|
||||||
|
eips[i] = int(eip)
|
||||||
|
}
|
||||||
|
return eips
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateEVMDenom(i interface{}) error {
|
||||||
|
denom, ok := i.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid parameter EVM denom type: %T", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return sdk.ValidateDenom(denom)
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateBool(i interface{}) error {
|
||||||
|
_, ok := i.(bool)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid parameter type: %T", i)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateEIPs(i interface{}) error {
|
||||||
|
eips, ok := i.([]int64)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid EIP slice type: %T", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, eip := range eips {
|
||||||
|
if !vm.ValidEip(int(eip)) {
|
||||||
|
return fmt.Errorf("EIP %d is not activateable, valid EIPS are: %s", eip, vm.ActivateableEips())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateChainConfig(i interface{}) error {
|
||||||
|
cfg, ok := i.(ChainConfig)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("invalid chain config type: %T", i)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg.Validate()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsLondon returns if london hardfork is enabled.
|
||||||
|
func IsLondon(ethConfig *params.ChainConfig, height int64) bool {
|
||||||
|
return ethConfig.IsLondon(big.NewInt(height))
|
||||||
|
}
|
@ -44,7 +44,7 @@ func (AppModuleBasic) RegisterLegacyAminoCodec(_ *codec.LegacyAmino) {
|
|||||||
|
|
||||||
// ConsensusVersion returns the consensus state-breaking version for the module.
|
// ConsensusVersion returns the consensus state-breaking version for the module.
|
||||||
func (AppModuleBasic) ConsensusVersion() uint64 {
|
func (AppModuleBasic) ConsensusVersion() uint64 {
|
||||||
return 1
|
return 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultGenesis returns default genesis state as raw bytes for the evm
|
// DefaultGenesis returns default genesis state as raw bytes for the evm
|
||||||
@ -123,7 +123,11 @@ func (am AppModule) RegisterServices(cfg module.Configurator) {
|
|||||||
types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
|
types.RegisterMsgServer(cfg.MsgServer(), am.keeper)
|
||||||
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
|
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
|
||||||
|
|
||||||
_ = keeper.NewMigrator(*am.keeper)
|
m := keeper.NewMigrator(*am.keeper)
|
||||||
|
err := cfg.RegisterMigration(types.ModuleName, 1, m.Migrate1to2)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route returns the message routing key for the evm module.
|
// Route returns the message routing key for the evm module.
|
||||||
|
231
x/evm/types/evm.pb.go
generated
231
x/evm/types/evm.pb.go
generated
@ -37,6 +37,8 @@ type Params struct {
|
|||||||
ExtraEIPs []int64 `protobuf:"varint,4,rep,packed,name=extra_eips,json=extraEips,proto3" json:"extra_eips,omitempty" yaml:"extra_eips"`
|
ExtraEIPs []int64 `protobuf:"varint,4,rep,packed,name=extra_eips,json=extraEips,proto3" json:"extra_eips,omitempty" yaml:"extra_eips"`
|
||||||
// chain config defines the EVM chain configuration parameters
|
// chain config defines the EVM chain configuration parameters
|
||||||
ChainConfig ChainConfig `protobuf:"bytes,5,opt,name=chain_config,json=chainConfig,proto3" json:"chain_config" yaml:"chain_config"`
|
ChainConfig ChainConfig `protobuf:"bytes,5,opt,name=chain_config,json=chainConfig,proto3" json:"chain_config" yaml:"chain_config"`
|
||||||
|
// reject replay-unprotected transactions
|
||||||
|
RejectUnprotectedTx bool `protobuf:"varint,6,opt,name=reject_unprotected_tx,json=rejectUnprotectedTx,proto3" json:"reject_unprotected_tx,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Params) Reset() { *m = Params{} }
|
func (m *Params) Reset() { *m = Params{} }
|
||||||
@ -107,6 +109,13 @@ func (m *Params) GetChainConfig() ChainConfig {
|
|||||||
return ChainConfig{}
|
return ChainConfig{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Params) GetRejectUnprotectedTx() bool {
|
||||||
|
if m != nil {
|
||||||
|
return m.RejectUnprotectedTx
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int values
|
// ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int values
|
||||||
// instead of *big.Int.
|
// instead of *big.Int.
|
||||||
type ChainConfig struct {
|
type ChainConfig struct {
|
||||||
@ -657,100 +666,101 @@ func init() {
|
|||||||
func init() { proto.RegisterFile("ethermint/evm/v1/evm.proto", fileDescriptor_d21ecc92c8c8583e) }
|
func init() { proto.RegisterFile("ethermint/evm/v1/evm.proto", fileDescriptor_d21ecc92c8c8583e) }
|
||||||
|
|
||||||
var fileDescriptor_d21ecc92c8c8583e = []byte{
|
var fileDescriptor_d21ecc92c8c8583e = []byte{
|
||||||
// 1475 bytes of a gzipped FileDescriptorProto
|
// 1504 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdf, 0x6e, 0xdb, 0xb6,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xcf, 0x6e, 0x1b, 0x37,
|
||||||
0x1a, 0x4f, 0x62, 0x27, 0x91, 0x69, 0xc7, 0x56, 0x98, 0x34, 0xc7, 0x4d, 0x71, 0xa2, 0x1c, 0x5d,
|
0x1a, 0xb7, 0x2d, 0xd9, 0x1e, 0x51, 0xb2, 0x34, 0xa6, 0x1d, 0xaf, 0xe2, 0x60, 0x3d, 0xde, 0x39,
|
||||||
0x1c, 0xe4, 0x00, 0x6d, 0xdc, 0xa4, 0x08, 0x4e, 0xd1, 0x62, 0x17, 0x51, 0x92, 0xb6, 0xc9, 0xba,
|
0x2c, 0xbc, 0x40, 0x62, 0xc5, 0x0e, 0x8c, 0x0d, 0x12, 0xec, 0xc1, 0x63, 0x3b, 0x89, 0xbd, 0xd9,
|
||||||
0x2d, 0x60, 0x32, 0x0c, 0x18, 0x30, 0x08, 0xb4, 0xc4, 0xca, 0x5a, 0x24, 0xd1, 0x20, 0x29, 0xd7,
|
0xad, 0x41, 0x3b, 0x28, 0x50, 0xa0, 0x18, 0x50, 0x33, 0xcc, 0x68, 0xe2, 0x99, 0xa1, 0x40, 0x72,
|
||||||
0x1e, 0xf6, 0x00, 0x03, 0x76, 0xb3, 0x47, 0xd8, 0x2b, 0xec, 0x2d, 0x8a, 0x5d, 0xf5, 0x66, 0xc0,
|
0x14, 0xa9, 0xe8, 0x03, 0xb4, 0xe8, 0xa5, 0x8f, 0xd0, 0x57, 0xe8, 0x5b, 0x04, 0x3d, 0xe5, 0x58,
|
||||||
0xb0, 0x0b, 0xa1, 0x48, 0xef, 0x72, 0xe9, 0x27, 0x18, 0x44, 0xd2, 0x7f, 0x13, 0x6c, 0x4b, 0xae,
|
0xf4, 0x30, 0x08, 0x9c, 0x9b, 0x8f, 0x7a, 0x82, 0x62, 0x48, 0xea, 0xaf, 0x8d, 0xb6, 0xf6, 0x49,
|
||||||
0xcc, 0xdf, 0xf7, 0xe7, 0xf7, 0x23, 0x3f, 0x7e, 0x14, 0x69, 0xb0, 0x4e, 0x44, 0x8b, 0xb0, 0x38,
|
0xfc, 0x7d, 0x7f, 0x7e, 0x3f, 0xf2, 0xe3, 0x37, 0x24, 0x05, 0xd6, 0x89, 0x68, 0x11, 0x16, 0x87,
|
||||||
0x4c, 0x44, 0x83, 0x74, 0xe2, 0x46, 0x67, 0x27, 0xff, 0xd9, 0x6e, 0x33, 0x2a, 0x28, 0x34, 0x87,
|
0x89, 0x68, 0x90, 0x4e, 0xdc, 0xe8, 0xec, 0xe4, 0x3f, 0xdb, 0x6d, 0x46, 0x05, 0x85, 0xe6, 0xd0,
|
||||||
0xbe, 0xed, 0xdc, 0xd8, 0xd9, 0x59, 0x5f, 0x0d, 0x68, 0x40, 0xa5, 0xb3, 0x91, 0x8f, 0x54, 0x9c,
|
0xb7, 0x9d, 0x1b, 0x3b, 0x3b, 0xeb, 0xab, 0x01, 0x0d, 0xa8, 0x74, 0x36, 0xf2, 0x91, 0x8a, 0xb3,
|
||||||
0xfd, 0xdb, 0x1c, 0x58, 0x38, 0xc5, 0x0c, 0xc7, 0x1c, 0xee, 0x80, 0x12, 0xe9, 0xc4, 0xae, 0x4f,
|
0xbf, 0x2f, 0x80, 0x85, 0x53, 0xcc, 0x70, 0xcc, 0xe1, 0x0e, 0x28, 0x91, 0x4e, 0xec, 0xfa, 0x24,
|
||||||
0x12, 0x1a, 0xd7, 0x67, 0x37, 0x67, 0xb7, 0x4a, 0xce, 0x6a, 0x3f, 0xb3, 0xcc, 0x1e, 0x8e, 0xa3,
|
0xa1, 0x71, 0x7d, 0x76, 0x73, 0x76, 0xab, 0xe4, 0xac, 0xf6, 0x33, 0xcb, 0xec, 0xe1, 0x38, 0x7a,
|
||||||
0x67, 0xf6, 0xd0, 0x65, 0x23, 0x83, 0x74, 0xe2, 0xc3, 0x7c, 0x08, 0x3f, 0x01, 0x4b, 0x24, 0xc1,
|
0x66, 0x0f, 0x5d, 0x36, 0x32, 0x48, 0x27, 0x3e, 0xcc, 0x87, 0xf0, 0x3f, 0x60, 0x89, 0x24, 0xb8,
|
||||||
0xcd, 0x88, 0xb8, 0x1e, 0x23, 0x58, 0x90, 0xfa, 0xdc, 0xe6, 0xec, 0x96, 0xe1, 0xd4, 0xfb, 0x99,
|
0x19, 0x11, 0xd7, 0x63, 0x04, 0x0b, 0x52, 0x9f, 0xdb, 0x9c, 0xdd, 0x32, 0x9c, 0x7a, 0x3f, 0xb3,
|
||||||
0xb5, 0xaa, 0xd3, 0xc6, 0xdd, 0x36, 0xaa, 0x28, 0x7c, 0x20, 0x21, 0xfc, 0x3f, 0x28, 0x0f, 0xfc,
|
0x56, 0x75, 0xda, 0xb8, 0xdb, 0x46, 0x15, 0x85, 0x0f, 0x24, 0x84, 0xff, 0x06, 0xe5, 0x81, 0x1f,
|
||||||
0x38, 0x8a, 0xea, 0x05, 0x99, 0xbc, 0xd6, 0xcf, 0x2c, 0x38, 0x99, 0x8c, 0xa3, 0xc8, 0x46, 0x40,
|
0x47, 0x51, 0xbd, 0x20, 0x93, 0xd7, 0xfa, 0x99, 0x05, 0x27, 0x93, 0x71, 0x14, 0xd9, 0x08, 0xe8,
|
||||||
0xa7, 0xe2, 0x28, 0x82, 0xfb, 0x00, 0x90, 0xae, 0x60, 0xd8, 0x25, 0x61, 0x9b, 0xd7, 0x8b, 0x9b,
|
0x54, 0x1c, 0x45, 0x70, 0x1f, 0x00, 0xd2, 0x15, 0x0c, 0xbb, 0x24, 0x6c, 0xf3, 0x7a, 0x71, 0xb3,
|
||||||
0x85, 0xad, 0x82, 0x63, 0x5f, 0x66, 0x56, 0xe9, 0x28, 0xb7, 0x1e, 0x1d, 0x9f, 0xf2, 0x7e, 0x66,
|
0xb0, 0x55, 0x70, 0xec, 0xcb, 0xcc, 0x2a, 0x1d, 0xe5, 0xd6, 0xa3, 0xe3, 0x53, 0xde, 0xcf, 0xac,
|
||||||
0x2d, 0x6b, 0x92, 0x61, 0xa0, 0x8d, 0x4a, 0x12, 0x1c, 0x85, 0x6d, 0x0e, 0xbf, 0x01, 0x15, 0xaf,
|
0x65, 0x4d, 0x32, 0x0c, 0xb4, 0x51, 0x49, 0x82, 0xa3, 0xb0, 0xcd, 0xe1, 0xd7, 0xa0, 0xe2, 0xb5,
|
||||||
0x85, 0xc3, 0xc4, 0xf5, 0x68, 0xf2, 0x26, 0x0c, 0xea, 0xf3, 0x9b, 0xb3, 0x5b, 0xe5, 0xdd, 0x7f,
|
0x70, 0x98, 0xb8, 0x1e, 0x4d, 0xde, 0x86, 0x41, 0x7d, 0x7e, 0x73, 0x76, 0xab, 0xbc, 0xfb, 0xf7,
|
||||||
0x6f, 0x4f, 0xd7, 0x6d, 0xfb, 0x20, 0x8f, 0x3a, 0x90, 0x41, 0xce, 0x83, 0x77, 0x99, 0x35, 0xd3,
|
0xed, 0xe9, 0xba, 0x6d, 0x1f, 0xe4, 0x51, 0x07, 0x32, 0xc8, 0x79, 0xf0, 0x21, 0xb3, 0x66, 0xfa,
|
||||||
0xcf, 0xac, 0x15, 0x45, 0x3d, 0x4e, 0x60, 0xa3, 0xb2, 0x37, 0x8a, 0xb4, 0x7f, 0xa9, 0x82, 0xf2,
|
0x99, 0xb5, 0xa2, 0xa8, 0xc7, 0x09, 0x6c, 0x54, 0xf6, 0x46, 0x91, 0x70, 0x17, 0xdc, 0x63, 0xe4,
|
||||||
0x58, 0x26, 0x8c, 0x41, 0xad, 0x45, 0x63, 0xc2, 0x05, 0xc1, 0xbe, 0xdb, 0x8c, 0xa8, 0x77, 0xa1,
|
0x1d, 0xf1, 0x84, 0x9b, 0x26, 0x79, 0xa5, 0x89, 0x27, 0x88, 0xef, 0x8a, 0x6e, 0x7d, 0x21, 0x5f,
|
||||||
0x4b, 0x7c, 0xf8, 0x47, 0x66, 0xfd, 0x37, 0x08, 0x45, 0x2b, 0x6d, 0x6e, 0x7b, 0x34, 0x6e, 0x78,
|
0x24, 0x5a, 0x51, 0xce, 0x37, 0x23, 0xdf, 0x79, 0xd7, 0xfe, 0xb9, 0x0a, 0xca, 0x63, 0x6a, 0x30,
|
||||||
0x94, 0xc7, 0x94, 0xeb, 0x9f, 0x47, 0xdc, 0xbf, 0x68, 0x88, 0x5e, 0x9b, 0xf0, 0xed, 0xe3, 0x44,
|
0x06, 0xb5, 0x16, 0x8d, 0x09, 0x17, 0x04, 0xfb, 0x6e, 0x33, 0xa2, 0xde, 0x85, 0xde, 0x96, 0xc3,
|
||||||
0xf4, 0x33, 0x6b, 0x4d, 0x09, 0x4f, 0x51, 0xd9, 0xa8, 0x3a, 0xb4, 0x38, 0xb9, 0x01, 0xf6, 0x40,
|
0xdf, 0x32, 0xeb, 0x9f, 0x41, 0x28, 0x5a, 0x69, 0x73, 0xdb, 0xa3, 0x71, 0xc3, 0xa3, 0x3c, 0xa6,
|
||||||
0xd5, 0xc7, 0xd4, 0x7d, 0x43, 0xd9, 0x85, 0x56, 0x9b, 0x93, 0x6a, 0x67, 0xff, 0x5c, 0xed, 0x32,
|
0x5c, 0xff, 0x3c, 0xe2, 0xfe, 0x45, 0x43, 0xf4, 0xda, 0x84, 0x6f, 0x1f, 0x27, 0xa2, 0x9f, 0x59,
|
||||||
0xb3, 0x2a, 0x87, 0xfb, 0x5f, 0xbc, 0xa0, 0xec, 0x42, 0x72, 0xf6, 0x33, 0xeb, 0x9e, 0x52, 0x9f,
|
0x6b, 0x6a, 0xb2, 0x53, 0x54, 0x36, 0xaa, 0x0e, 0x2d, 0x4e, 0x6e, 0x80, 0x3d, 0x50, 0xf5, 0x31,
|
||||||
0x64, 0xb6, 0x51, 0xc5, 0xc7, 0x74, 0x18, 0x06, 0xbf, 0x02, 0xe6, 0x30, 0x80, 0xa7, 0xed, 0x36,
|
0x75, 0xdf, 0x52, 0x76, 0xa1, 0xd5, 0xe6, 0xa4, 0xda, 0xd9, 0x5f, 0x57, 0xbb, 0xcc, 0xac, 0xca,
|
||||||
0x65, 0x42, 0xef, 0xec, 0xa3, 0xcb, 0xcc, 0xaa, 0x6a, 0xca, 0x33, 0xe5, 0xe9, 0x67, 0xd6, 0xbf,
|
0xe1, 0xfe, 0x17, 0x2f, 0x28, 0xbb, 0x90, 0x9c, 0xfd, 0xcc, 0xba, 0xa7, 0xd4, 0x27, 0x99, 0x6d,
|
||||||
0xa6, 0x48, 0x75, 0x8e, 0x8d, 0xaa, 0x9a, 0x56, 0x87, 0x42, 0x0e, 0x2a, 0x24, 0x6c, 0xef, 0xec,
|
0x54, 0xf1, 0x31, 0x1d, 0x86, 0xc1, 0x2f, 0x81, 0x39, 0x0c, 0xe0, 0x69, 0xbb, 0x4d, 0x99, 0xd0,
|
||||||
0x3d, 0xd6, 0x2b, 0x2a, 0xca, 0x15, 0x9d, 0xde, 0x6a, 0x45, 0xe5, 0xa3, 0xe3, 0xd3, 0x9d, 0xbd,
|
0xdd, 0xf0, 0xe8, 0x32, 0xb3, 0xaa, 0x9a, 0xf2, 0x4c, 0x79, 0xfa, 0x99, 0xf5, 0xb7, 0x29, 0x52,
|
||||||
0xc7, 0x83, 0x05, 0xe9, 0x7d, 0x1c, 0xa7, 0xb5, 0x51, 0x59, 0x41, 0xb5, 0x9a, 0x63, 0xa0, 0xa1,
|
0x9d, 0x63, 0xa3, 0xaa, 0xa6, 0xd5, 0xa1, 0x90, 0x83, 0x0a, 0x09, 0xdb, 0x3b, 0x7b, 0x8f, 0xf5,
|
||||||
0xdb, 0xc2, 0xbc, 0x25, 0xbb, 0xa4, 0xe4, 0x6c, 0x5d, 0x66, 0x16, 0x50, 0x4c, 0xaf, 0x30, 0x6f,
|
0x8a, 0x8a, 0x72, 0x45, 0xa7, 0xb7, 0x5a, 0x51, 0xf9, 0xe8, 0xf8, 0x74, 0x67, 0xef, 0xf1, 0x60,
|
||||||
0x8d, 0xf6, 0xa5, 0xd9, 0xfb, 0x0e, 0x27, 0x22, 0x4c, 0xe3, 0x01, 0x17, 0x50, 0xc9, 0x79, 0xd4,
|
0x41, 0x7a, 0xef, 0xc7, 0x69, 0x6d, 0x54, 0x56, 0x50, 0xad, 0xe6, 0x18, 0x68, 0xe8, 0xb6, 0x30,
|
||||||
0x70, 0xfe, 0x7b, 0x7a, 0xfe, 0x0b, 0x77, 0x9e, 0xff, 0xde, 0x4d, 0xf3, 0xdf, 0x9b, 0x9c, 0xbf,
|
0x6f, 0xc9, 0xce, 0x2a, 0x39, 0x5b, 0x97, 0x99, 0x05, 0x14, 0xd3, 0x2b, 0xcc, 0x5b, 0xa3, 0x7d,
|
||||||
0x8a, 0x19, 0x8a, 0x3e, 0xd5, 0xa2, 0x8b, 0x77, 0x16, 0x7d, 0x7a, 0x93, 0xe8, 0xd3, 0x49, 0x51,
|
0x69, 0xf6, 0xbe, 0xc1, 0x89, 0x08, 0xd3, 0x78, 0xc0, 0x05, 0x54, 0x72, 0x1e, 0x35, 0x9c, 0xff,
|
||||||
0x15, 0x93, 0x37, 0xfb, 0x54, 0x25, 0xea, 0xc6, 0xdd, 0x9b, 0xfd, 0x5a, 0x51, 0xab, 0x43, 0x8b,
|
0x9e, 0x9e, 0xff, 0xc2, 0x9d, 0xe7, 0xbf, 0x77, 0xd3, 0xfc, 0xf7, 0x26, 0xe7, 0xaf, 0x62, 0x86,
|
||||||
0x92, 0xfb, 0x1e, 0xac, 0x7a, 0x34, 0xe1, 0x22, 0xb7, 0x25, 0xb4, 0x1d, 0x11, 0xad, 0x59, 0x92,
|
0xa2, 0x4f, 0xb5, 0xe8, 0xe2, 0x9d, 0x45, 0x9f, 0xde, 0x24, 0xfa, 0x74, 0x52, 0x54, 0xc5, 0xe4,
|
||||||
0x9a, 0xc7, 0xb7, 0xd2, 0x7c, 0xa0, 0x4f, 0xf6, 0x0d, 0x7c, 0x36, 0x5a, 0x99, 0x34, 0x2b, 0xf5,
|
0xcd, 0x3e, 0x55, 0x89, 0xba, 0x71, 0xf7, 0x66, 0xbf, 0x56, 0xd4, 0xea, 0xd0, 0xa2, 0xe4, 0xbe,
|
||||||
0x36, 0x30, 0xdb, 0x44, 0x10, 0xc6, 0x9b, 0x29, 0x0b, 0xb4, 0x32, 0x90, 0xca, 0x47, 0xb7, 0x52,
|
0x05, 0xab, 0x1e, 0x4d, 0xb8, 0xc8, 0x6d, 0x09, 0x6d, 0x47, 0x44, 0x6b, 0x96, 0xa4, 0xe6, 0xf1,
|
||||||
0xd6, 0xe7, 0x60, 0x9a, 0xcb, 0x46, 0xb5, 0x91, 0x49, 0x29, 0x7e, 0x0b, 0xaa, 0x61, 0x3e, 0x8d,
|
0xad, 0x34, 0x1f, 0xe8, 0xd3, 0xe0, 0x06, 0x3e, 0x1b, 0xad, 0x4c, 0x9a, 0x95, 0x7a, 0x1b, 0x98,
|
||||||
0x66, 0x1a, 0x69, 0xbd, 0xb2, 0xd4, 0x3b, 0xb8, 0x95, 0x9e, 0x3e, 0xcc, 0x93, 0x4c, 0x36, 0x5a,
|
0x6d, 0x22, 0x08, 0xe3, 0xcd, 0x94, 0x05, 0x5a, 0x19, 0x48, 0xe5, 0xa3, 0x5b, 0x29, 0xeb, 0xef,
|
||||||
0x1a, 0x18, 0x94, 0x56, 0x0a, 0x60, 0x9c, 0x86, 0xcc, 0x0d, 0x22, 0xec, 0x85, 0x84, 0x69, 0xbd,
|
0x60, 0x9a, 0xcb, 0x46, 0xb5, 0x91, 0x49, 0x29, 0xbe, 0x03, 0xd5, 0x30, 0x9f, 0x46, 0x33, 0x8d,
|
||||||
0x8a, 0xd4, 0x7b, 0x79, 0x2b, 0xbd, 0xfb, 0x4a, 0xef, 0x3a, 0x9b, 0x8d, 0xcc, 0xdc, 0xf8, 0x52,
|
0xb4, 0x5e, 0x59, 0xea, 0x1d, 0xdc, 0x4a, 0x4f, 0x7f, 0xcc, 0x93, 0x4c, 0x36, 0x5a, 0x1a, 0x18,
|
||||||
0xd9, 0x94, 0xac, 0x0f, 0x2a, 0x4d, 0xc2, 0xa2, 0x30, 0xd1, 0x82, 0x4b, 0x52, 0x70, 0xff, 0x56,
|
0x94, 0x56, 0x0a, 0x60, 0x9c, 0x86, 0xcc, 0x0d, 0x22, 0xec, 0x85, 0x84, 0x69, 0xbd, 0x8a, 0xd4,
|
||||||
0x82, 0xba, 0x4f, 0xc7, 0x79, 0x6c, 0x54, 0x56, 0x70, 0xa8, 0x12, 0xd1, 0xc4, 0xa7, 0x03, 0x95,
|
0x7b, 0x79, 0x2b, 0xbd, 0xfb, 0x4a, 0xef, 0x3a, 0x9b, 0x8d, 0xcc, 0xdc, 0xf8, 0x52, 0xd9, 0x94,
|
||||||
0xe5, 0xbb, 0xab, 0x8c, 0xf3, 0xd8, 0xa8, 0xac, 0xa0, 0x52, 0xe9, 0x82, 0x15, 0xcc, 0x18, 0x7d,
|
0xac, 0x0f, 0x2a, 0x4d, 0xc2, 0xa2, 0x30, 0xd1, 0x82, 0x4b, 0x52, 0x70, 0xff, 0x56, 0x82, 0xba,
|
||||||
0x3b, 0x55, 0x43, 0x28, 0xc5, 0x5e, 0xdd, 0x4a, 0x6c, 0x5d, 0x89, 0xdd, 0x40, 0x67, 0xa3, 0x65,
|
0x4f, 0xc7, 0x79, 0x6c, 0x54, 0x56, 0x70, 0xa8, 0x12, 0xd1, 0xc4, 0xa7, 0x03, 0x95, 0xe5, 0xbb,
|
||||||
0x69, 0x9d, 0xa8, 0x22, 0x05, 0x66, 0x4c, 0x58, 0x40, 0xc6, 0xef, 0x81, 0x95, 0xbb, 0xb7, 0xe6,
|
0xab, 0x8c, 0xf3, 0xd8, 0xa8, 0xac, 0xa0, 0x52, 0xe9, 0x82, 0x15, 0xcc, 0x18, 0x7d, 0x3f, 0x55,
|
||||||
0x34, 0x97, 0x8d, 0xaa, 0xd2, 0x34, 0xfc, 0xf6, 0x9f, 0x14, 0x8d, 0xaa, 0x59, 0x3b, 0x29, 0x1a,
|
0x43, 0x28, 0xc5, 0x5e, 0xdd, 0x4a, 0x6c, 0x5d, 0x89, 0xdd, 0x40, 0x67, 0xa3, 0x65, 0x69, 0x9d,
|
||||||
0x35, 0xd3, 0x3c, 0x29, 0x1a, 0xa6, 0xb9, 0x8c, 0x96, 0x7a, 0x34, 0xa2, 0x6e, 0xe7, 0x89, 0xca,
|
0xa8, 0x22, 0x05, 0x66, 0x4c, 0x58, 0x40, 0xc6, 0xef, 0x81, 0x95, 0xbb, 0xb7, 0xe6, 0x34, 0x97,
|
||||||
0x40, 0x65, 0xf2, 0x16, 0x73, 0x7d, 0x90, 0x51, 0xd5, 0xc3, 0x02, 0x47, 0x3d, 0x2e, 0x34, 0x5d,
|
0x8d, 0xaa, 0xd2, 0x34, 0x3c, 0xfb, 0x4f, 0x8a, 0x46, 0xd5, 0xac, 0x9d, 0x14, 0x8d, 0x9a, 0x69,
|
||||||
0x03, 0xcc, 0x9f, 0x89, 0xfc, 0x5d, 0x60, 0x82, 0xc2, 0x05, 0xe9, 0xa9, 0x0b, 0x12, 0xe5, 0x43,
|
0x9e, 0x14, 0x0d, 0xd3, 0x5c, 0x46, 0x4b, 0x3d, 0x1a, 0x51, 0xb7, 0xf3, 0x44, 0x65, 0xa0, 0x32,
|
||||||
0xb8, 0x0a, 0xe6, 0x3b, 0x38, 0x4a, 0xd5, 0x03, 0xa3, 0x84, 0x14, 0xb0, 0x4f, 0x41, 0xed, 0x9c,
|
0x79, 0x8f, 0xb9, 0xfe, 0x90, 0x51, 0xd5, 0xc3, 0x02, 0x47, 0x3d, 0x2e, 0x34, 0x5d, 0x03, 0xcc,
|
||||||
0xe1, 0x84, 0x63, 0x4f, 0x84, 0x34, 0x79, 0x4d, 0x03, 0x0e, 0x21, 0x28, 0xca, 0x0f, 0xb5, 0xca,
|
0x9f, 0x89, 0xfc, 0x2d, 0x61, 0x82, 0xc2, 0x05, 0xe9, 0xa9, 0x0b, 0x12, 0xe5, 0x43, 0xb8, 0x0a,
|
||||||
0x95, 0x63, 0xf8, 0x3f, 0x50, 0x8c, 0x68, 0xc0, 0xeb, 0x73, 0x9b, 0x85, 0xad, 0xf2, 0xee, 0xbd,
|
0xe6, 0x3b, 0x38, 0x4a, 0xd5, 0xa3, 0xa4, 0x84, 0x14, 0xb0, 0x4f, 0x41, 0xed, 0x9c, 0xe1, 0x84,
|
||||||
0xeb, 0x57, 0xfc, 0x6b, 0x1a, 0x20, 0x19, 0x62, 0xff, 0x3a, 0x07, 0x0a, 0xaf, 0x69, 0x00, 0xeb,
|
0x63, 0x4f, 0x84, 0x34, 0x79, 0x4d, 0x03, 0x0e, 0x21, 0x28, 0xca, 0x83, 0x5a, 0xe5, 0xca, 0x31,
|
||||||
0x60, 0x11, 0xfb, 0x3e, 0x23, 0x9c, 0x6b, 0xa6, 0x01, 0x84, 0x6b, 0x60, 0x41, 0xd0, 0x76, 0xe8,
|
0xfc, 0x17, 0x28, 0x46, 0x34, 0xe0, 0xf5, 0xb9, 0xcd, 0xc2, 0x56, 0x79, 0xf7, 0xde, 0xf5, 0x67,
|
||||||
0x29, 0xba, 0x12, 0xd2, 0x28, 0x17, 0xf6, 0xb1, 0xc0, 0xf2, 0xaa, 0xab, 0x20, 0x39, 0x86, 0xbb,
|
0xc1, 0x6b, 0x1a, 0x20, 0x19, 0x62, 0xff, 0x32, 0x07, 0x0a, 0xaf, 0x69, 0x00, 0xeb, 0x60, 0x11,
|
||||||
0xa0, 0x22, 0x57, 0xe6, 0x26, 0x69, 0xdc, 0x24, 0x4c, 0xde, 0x58, 0x45, 0xa7, 0x76, 0x95, 0x59,
|
0xfb, 0x3e, 0x23, 0x9c, 0x6b, 0xa6, 0x01, 0x84, 0x6b, 0x60, 0x41, 0xd0, 0x76, 0xe8, 0x29, 0xba,
|
||||||
0x65, 0x69, 0xff, 0x5c, 0x9a, 0xd1, 0x38, 0x80, 0x0f, 0xc1, 0xa2, 0xe8, 0x8e, 0x5f, 0x36, 0x2b,
|
0x12, 0xd2, 0x28, 0x17, 0xf6, 0xb1, 0xc0, 0xf2, 0xaa, 0xab, 0x20, 0x39, 0x86, 0xbb, 0xa0, 0x22,
|
||||||
0x57, 0x99, 0x55, 0x13, 0xa3, 0x65, 0xe6, 0x77, 0x09, 0x5a, 0x10, 0x5d, 0x79, 0xa7, 0x34, 0x80,
|
0x57, 0xe6, 0x26, 0x69, 0xdc, 0x24, 0x4c, 0xde, 0x58, 0x45, 0xa7, 0x76, 0x95, 0x59, 0x65, 0x69,
|
||||||
0x21, 0xba, 0x6e, 0x98, 0xf8, 0xa4, 0x2b, 0xef, 0x93, 0xa2, 0xb3, 0x7a, 0x95, 0x59, 0xe6, 0x58,
|
0xff, 0xbf, 0x34, 0xa3, 0x71, 0x00, 0x1f, 0x82, 0x45, 0xd1, 0x1d, 0xbf, 0x6c, 0x56, 0xae, 0x32,
|
||||||
0xf8, 0x71, 0xee, 0x43, 0x8b, 0xa2, 0x2b, 0x07, 0xf0, 0x21, 0x00, 0x6a, 0x4a, 0x52, 0x41, 0xdd,
|
0xab, 0x26, 0x46, 0xcb, 0xcc, 0xef, 0x12, 0xb4, 0x20, 0xba, 0xf2, 0x4e, 0x69, 0x00, 0x43, 0x74,
|
||||||
0x06, 0x4b, 0x57, 0x99, 0x55, 0x92, 0x56, 0xc9, 0x3d, 0x1a, 0x42, 0x1b, 0xcc, 0x2b, 0x6e, 0x43,
|
0xdd, 0x30, 0xf1, 0x89, 0x7a, 0x8d, 0x14, 0x9d, 0xd5, 0xab, 0xcc, 0x32, 0xc7, 0xc2, 0x8f, 0x73,
|
||||||
0x72, 0x57, 0xae, 0x32, 0xcb, 0x88, 0x68, 0xa0, 0x38, 0x95, 0x2b, 0x2f, 0x15, 0x23, 0x31, 0xed,
|
0x1f, 0x5a, 0x14, 0x5d, 0x39, 0x80, 0x0f, 0x01, 0x50, 0x53, 0x92, 0x0a, 0xea, 0x36, 0x58, 0xba,
|
||||||
0x10, 0x5f, 0x7e, 0x70, 0x0d, 0x34, 0x80, 0xf6, 0x8f, 0x73, 0xc0, 0x38, 0xef, 0x22, 0xc2, 0xd3,
|
0xca, 0xac, 0x92, 0xb4, 0x4a, 0xee, 0xd1, 0x10, 0xda, 0x60, 0x5e, 0x71, 0x1b, 0x92, 0xbb, 0x72,
|
||||||
0x48, 0xc0, 0x17, 0xc0, 0xf4, 0x68, 0x22, 0x18, 0xf6, 0x84, 0x3b, 0x51, 0x5a, 0xe7, 0xc1, 0xa8,
|
0x95, 0x59, 0x46, 0x44, 0x03, 0xc5, 0xa9, 0x5c, 0x79, 0xa9, 0x18, 0x89, 0x69, 0x87, 0xf8, 0xf2,
|
||||||
0xc3, 0xa6, 0x23, 0x6c, 0x54, 0x1b, 0x98, 0xf6, 0x75, 0xfd, 0x57, 0xc1, 0x7c, 0x33, 0xa2, 0x34,
|
0xc0, 0x35, 0xd0, 0x00, 0xda, 0x3f, 0xcc, 0x01, 0xe3, 0xbc, 0x8b, 0x08, 0x4f, 0x23, 0x01, 0x5f,
|
||||||
0x96, 0x9d, 0x50, 0x41, 0x0a, 0x40, 0x24, 0xab, 0x26, 0x77, 0xb9, 0x20, 0x1f, 0x72, 0xff, 0xb9,
|
0x00, 0xd3, 0xa3, 0x89, 0x60, 0xd8, 0x13, 0xee, 0x44, 0x69, 0x9d, 0x07, 0xa3, 0x0e, 0x9b, 0x8e,
|
||||||
0xbe, 0xcb, 0x53, 0xad, 0xe2, 0xac, 0xe9, 0xc7, 0x5c, 0x55, 0x69, 0xeb, 0x7c, 0x3b, 0xaf, 0xad,
|
0xb0, 0x51, 0x6d, 0x60, 0xda, 0xd7, 0xf5, 0x5f, 0x05, 0xf3, 0xcd, 0x88, 0xd2, 0x58, 0x76, 0x42,
|
||||||
0x6c, 0x25, 0x13, 0x14, 0x18, 0x11, 0x72, 0xd3, 0x2a, 0x28, 0x1f, 0xc2, 0x75, 0x60, 0x30, 0xd2,
|
0x05, 0x29, 0x00, 0x91, 0xac, 0x9a, 0xdc, 0xe5, 0x82, 0x7c, 0xfc, 0xfd, 0xe3, 0xfa, 0x2e, 0x4f,
|
||||||
0x21, 0x4c, 0x10, 0x5f, 0x6e, 0x8e, 0x81, 0x86, 0x18, 0xde, 0x07, 0x46, 0x80, 0xb9, 0x9b, 0x72,
|
0xb5, 0x8a, 0xb3, 0xa6, 0x1f, 0x80, 0x55, 0xa5, 0xad, 0xf3, 0xed, 0xbc, 0xb6, 0xb2, 0x95, 0x4c,
|
||||||
0xe2, 0xab, 0x9d, 0x40, 0x8b, 0x01, 0xe6, 0x5f, 0x72, 0xe2, 0x3f, 0x2b, 0xfe, 0xf0, 0xb3, 0x35,
|
0x50, 0x60, 0x44, 0xc8, 0x4d, 0xab, 0xa0, 0x7c, 0x08, 0xd7, 0x81, 0xc1, 0x48, 0x87, 0x30, 0x41,
|
||||||
0x63, 0x63, 0x50, 0xde, 0xf7, 0x3c, 0xc2, 0xf9, 0x79, 0xda, 0x8e, 0xc8, 0x5f, 0x74, 0xd8, 0x2e,
|
0x7c, 0xb9, 0x39, 0x06, 0x1a, 0x62, 0x78, 0x1f, 0x18, 0x01, 0xe6, 0x6e, 0xca, 0x89, 0xaf, 0x76,
|
||||||
0xa8, 0x70, 0x41, 0x19, 0x0e, 0x88, 0x7b, 0x41, 0x7a, 0xba, 0xcf, 0x54, 0xd7, 0x68, 0xfb, 0xa7,
|
0x02, 0x2d, 0x06, 0x98, 0xbf, 0xe1, 0xc4, 0x7f, 0x56, 0xfc, 0xee, 0x27, 0x6b, 0xc6, 0xc6, 0xa0,
|
||||||
0xa4, 0xc7, 0xd1, 0x38, 0xd0, 0x12, 0x1f, 0x0a, 0xa0, 0x7c, 0xce, 0xb0, 0x47, 0xf4, 0xa3, 0x33,
|
0xbc, 0xef, 0x79, 0x84, 0xf3, 0xf3, 0xb4, 0x1d, 0x91, 0x3f, 0xe8, 0xb0, 0x5d, 0x50, 0xe1, 0x82,
|
||||||
0xef, 0xd5, 0x1c, 0x32, 0x2d, 0xa1, 0x51, 0xae, 0x2d, 0xc2, 0x98, 0xd0, 0x54, 0xe8, 0xf3, 0x34,
|
0x32, 0x1c, 0x10, 0xf7, 0x82, 0xf4, 0x74, 0x9f, 0xa9, 0xae, 0xd1, 0xf6, 0xff, 0x92, 0x1e, 0x47,
|
||||||
0x80, 0x79, 0x06, 0x23, 0xa4, 0x4b, 0x3c, 0x59, 0xc6, 0x22, 0xd2, 0x08, 0xee, 0x81, 0x25, 0x3f,
|
0xe3, 0x40, 0x4b, 0x7c, 0x2a, 0x80, 0xf2, 0x39, 0xc3, 0x1e, 0xd1, 0x8f, 0xce, 0xbc, 0x57, 0x73,
|
||||||
0xe4, 0xf2, 0x35, 0xce, 0x05, 0xf6, 0x2e, 0xd4, 0xf2, 0x1d, 0xf3, 0x2a, 0xb3, 0x2a, 0xda, 0x71,
|
0xc8, 0xb4, 0x84, 0x46, 0xb9, 0xb6, 0x08, 0x63, 0x42, 0x53, 0xa1, 0xbf, 0xa7, 0x01, 0xcc, 0x33,
|
||||||
0x96, 0xdb, 0xd1, 0x04, 0x82, 0xcf, 0x41, 0x6d, 0x94, 0x26, 0x67, 0x2b, 0x6b, 0x63, 0x38, 0xf0,
|
0x18, 0x21, 0x5d, 0xe2, 0xc9, 0x32, 0x16, 0x91, 0x46, 0x70, 0x0f, 0x2c, 0xf9, 0x21, 0x97, 0x2f,
|
||||||
0x2a, 0xb3, 0xaa, 0xc3, 0x50, 0xe9, 0x41, 0x53, 0x38, 0xdf, 0x69, 0x9f, 0x34, 0xd3, 0x40, 0x36,
|
0x78, 0x2e, 0xb0, 0x77, 0xa1, 0x96, 0xef, 0x98, 0x57, 0x99, 0x55, 0xd1, 0x8e, 0xb3, 0xdc, 0x8e,
|
||||||
0x9f, 0x81, 0x14, 0xc8, 0xad, 0x51, 0x18, 0x87, 0x42, 0x36, 0xdb, 0x3c, 0x52, 0x00, 0x3e, 0x07,
|
0x26, 0x10, 0x7c, 0x0e, 0x6a, 0xa3, 0x34, 0x39, 0x5b, 0xf5, 0x66, 0x76, 0xe0, 0x55, 0x66, 0x55,
|
||||||
0x25, 0xda, 0x21, 0x8c, 0x85, 0x3e, 0xe1, 0xf2, 0xf6, 0xfd, 0xbb, 0xa7, 0x3c, 0x1a, 0xc5, 0xe7,
|
0x87, 0xa1, 0xd2, 0x83, 0xa6, 0x70, 0xbe, 0xd3, 0x3e, 0x69, 0xa6, 0x81, 0x6c, 0x3e, 0x03, 0x29,
|
||||||
0x8b, 0xd3, 0xff, 0x34, 0x62, 0x12, 0x53, 0xd6, 0x93, 0xd7, 0xa9, 0x5e, 0x9c, 0x72, 0x7c, 0x26,
|
0x90, 0x5b, 0xa3, 0x30, 0x0e, 0x85, 0x6c, 0xb6, 0x79, 0xa4, 0x00, 0x7c, 0x0e, 0x4a, 0xb4, 0x43,
|
||||||
0xed, 0x68, 0x02, 0x41, 0x07, 0x40, 0x9d, 0xc6, 0x88, 0x48, 0x59, 0xe2, 0xca, 0xf3, 0x5f, 0x91,
|
0x18, 0x0b, 0x7d, 0xc2, 0xe5, 0xed, 0xfb, 0x67, 0xcf, 0x7f, 0x34, 0x8a, 0xcf, 0x17, 0xa7, 0xff,
|
||||||
0xb9, 0xf2, 0x14, 0x2a, 0x2f, 0x92, 0xce, 0x43, 0x2c, 0x30, 0xba, 0x66, 0x39, 0x29, 0x1a, 0x45,
|
0x9d, 0xc4, 0x24, 0xa6, 0xac, 0x27, 0xaf, 0x53, 0xbd, 0x38, 0xe5, 0xf8, 0x9f, 0xb4, 0xa3, 0x09,
|
||||||
0x73, 0xfe, 0xa4, 0x68, 0x2c, 0x9a, 0xc6, 0x70, 0xfd, 0x7a, 0x16, 0x68, 0x65, 0x80, 0xc7, 0xe8,
|
0x04, 0x1d, 0x00, 0x75, 0x1a, 0x23, 0x22, 0x65, 0x89, 0x2b, 0xbf, 0xff, 0x8a, 0xcc, 0x95, 0x5f,
|
||||||
0x1d, 0xe7, 0xdd, 0xe5, 0xc6, 0xec, 0xfb, 0xcb, 0x8d, 0xd9, 0x0f, 0x97, 0x1b, 0xb3, 0x3f, 0x7d,
|
0xa1, 0xf2, 0x22, 0xe9, 0x3c, 0xc4, 0x02, 0xa3, 0x6b, 0x96, 0x93, 0xa2, 0x51, 0x34, 0xe7, 0x4f,
|
||||||
0xdc, 0x98, 0x79, 0xff, 0x71, 0x63, 0xe6, 0xf7, 0x8f, 0x1b, 0x33, 0x5f, 0x6f, 0x8d, 0x7d, 0xce,
|
0x8a, 0xc6, 0xa2, 0x69, 0x0c, 0xd7, 0xaf, 0x67, 0x81, 0x56, 0x06, 0x78, 0x8c, 0xde, 0x71, 0x3e,
|
||||||
0x45, 0x0b, 0x33, 0x1e, 0xf2, 0xc6, 0xe8, 0x0f, 0x62, 0x57, 0xfe, 0x45, 0x94, 0x1f, 0xf5, 0xe6,
|
0x5c, 0x6e, 0xcc, 0x7e, 0xbc, 0xdc, 0x98, 0xfd, 0x74, 0xb9, 0x31, 0xfb, 0xe3, 0xe7, 0x8d, 0x99,
|
||||||
0x82, 0xfc, 0xeb, 0xf7, 0xe4, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x69, 0xef, 0x82, 0x39, 0x40,
|
0x8f, 0x9f, 0x37, 0x66, 0x7e, 0xfd, 0xbc, 0x31, 0xf3, 0xd5, 0xd6, 0xd8, 0x71, 0x2e, 0x5a, 0x98,
|
||||||
0x0e, 0x00, 0x00,
|
0xf1, 0x90, 0x37, 0x46, 0x7f, 0x2a, 0xbb, 0xf2, 0x6f, 0xa5, 0x3c, 0xd4, 0x9b, 0x0b, 0xf2, 0xef,
|
||||||
|
0xe2, 0x93, 0xdf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xd7, 0x80, 0xdd, 0x60, 0x74, 0x0e, 0x00, 0x00,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Params) Marshal() (dAtA []byte, err error) {
|
func (m *Params) Marshal() (dAtA []byte, err error) {
|
||||||
@ -773,6 +783,16 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
|||||||
_ = i
|
_ = i
|
||||||
var l int
|
var l int
|
||||||
_ = l
|
_ = l
|
||||||
|
if m.RejectUnprotectedTx {
|
||||||
|
i--
|
||||||
|
if m.RejectUnprotectedTx {
|
||||||
|
dAtA[i] = 1
|
||||||
|
} else {
|
||||||
|
dAtA[i] = 0
|
||||||
|
}
|
||||||
|
i--
|
||||||
|
dAtA[i] = 0x30
|
||||||
|
}
|
||||||
{
|
{
|
||||||
size, err := m.ChainConfig.MarshalToSizedBuffer(dAtA[:i])
|
size, err := m.ChainConfig.MarshalToSizedBuffer(dAtA[:i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1465,6 +1485,9 @@ func (m *Params) Size() (n int) {
|
|||||||
}
|
}
|
||||||
l = m.ChainConfig.Size()
|
l = m.ChainConfig.Size()
|
||||||
n += 1 + l + sovEvm(uint64(l))
|
n += 1 + l + sovEvm(uint64(l))
|
||||||
|
if m.RejectUnprotectedTx {
|
||||||
|
n += 2
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1925,6 +1948,26 @@ func (m *Params) Unmarshal(dAtA []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
iNdEx = postIndex
|
iNdEx = postIndex
|
||||||
|
case 6:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field RejectUnprotectedTx", wireType)
|
||||||
|
}
|
||||||
|
var v int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowEvm
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
v |= int(b&0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.RejectUnprotectedTx = bool(v != 0)
|
||||||
default:
|
default:
|
||||||
iNdEx = preIndex
|
iNdEx = preIndex
|
||||||
skippy, err := skipEvm(dAtA[iNdEx:])
|
skippy, err := skipEvm(dAtA[iNdEx:])
|
||||||
|
@ -18,8 +18,12 @@ const (
|
|||||||
DefaultEVMDenom = types.AttoPhoton
|
DefaultEVMDenom = types.AttoPhoton
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
// DefaultMinGasMultiplier is 0.5 or 50%
|
// DefaultMinGasMultiplier is 0.5 or 50%
|
||||||
var DefaultMinGasMultiplier = sdk.NewDecWithPrec(50, 2)
|
DefaultMinGasMultiplier = sdk.NewDecWithPrec(50, 2)
|
||||||
|
|
||||||
|
DefaultRejectUnprotectedTx = false
|
||||||
|
)
|
||||||
|
|
||||||
// Parameter keys
|
// Parameter keys
|
||||||
var (
|
var (
|
||||||
@ -28,6 +32,7 @@ var (
|
|||||||
ParamStoreKeyEnableCall = []byte("EnableCall")
|
ParamStoreKeyEnableCall = []byte("EnableCall")
|
||||||
ParamStoreKeyExtraEIPs = []byte("EnableExtraEIPs")
|
ParamStoreKeyExtraEIPs = []byte("EnableExtraEIPs")
|
||||||
ParamStoreKeyChainConfig = []byte("ChainConfig")
|
ParamStoreKeyChainConfig = []byte("ChainConfig")
|
||||||
|
ParamStoreKeyRejectUnprotectedTx = []byte("RejectUnprotectedTx")
|
||||||
|
|
||||||
// AvailableExtraEIPs define the list of all EIPs that can be enabled by the
|
// AvailableExtraEIPs define the list of all EIPs that can be enabled by the
|
||||||
// EVM interpreter. These EIPs are applied in order and can override the
|
// EVM interpreter. These EIPs are applied in order and can override the
|
||||||
@ -62,6 +67,7 @@ func DefaultParams() Params {
|
|||||||
EnableCall: true,
|
EnableCall: true,
|
||||||
ChainConfig: DefaultChainConfig(),
|
ChainConfig: DefaultChainConfig(),
|
||||||
ExtraEIPs: nil,
|
ExtraEIPs: nil,
|
||||||
|
RejectUnprotectedTx: DefaultRejectUnprotectedTx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +79,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs {
|
|||||||
paramtypes.NewParamSetPair(ParamStoreKeyEnableCall, &p.EnableCall, validateBool),
|
paramtypes.NewParamSetPair(ParamStoreKeyEnableCall, &p.EnableCall, validateBool),
|
||||||
paramtypes.NewParamSetPair(ParamStoreKeyExtraEIPs, &p.ExtraEIPs, validateEIPs),
|
paramtypes.NewParamSetPair(ParamStoreKeyExtraEIPs, &p.ExtraEIPs, validateEIPs),
|
||||||
paramtypes.NewParamSetPair(ParamStoreKeyChainConfig, &p.ChainConfig, validateChainConfig),
|
paramtypes.NewParamSetPair(ParamStoreKeyChainConfig, &p.ChainConfig, validateChainConfig),
|
||||||
|
paramtypes.NewParamSetPair(ParamStoreKeyRejectUnprotectedTx, &p.RejectUnprotectedTx, validateBool),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
x/evm/types/tx.pb.go
generated
1
x/evm/types/tx.pb.go
generated
@ -81,6 +81,7 @@ func (m *MsgEthereumTx) XXX_DiscardUnknown() {
|
|||||||
var xxx_messageInfo_MsgEthereumTx proto.InternalMessageInfo
|
var xxx_messageInfo_MsgEthereumTx proto.InternalMessageInfo
|
||||||
|
|
||||||
// LegacyTx is the transaction data of regular Ethereum transactions.
|
// LegacyTx is the transaction data of regular Ethereum transactions.
|
||||||
|
// NOTE: All non-protected transactions (i.e non EIP155 signed) will fail if the RejectUnprotectedTx parameter is enabled.
|
||||||
type LegacyTx struct {
|
type LegacyTx struct {
|
||||||
// nonce corresponds to the account nonce (transaction sequence).
|
// nonce corresponds to the account nonce (transaction sequence).
|
||||||
Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
|
Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
|
||||||
|
@ -46,6 +46,7 @@ type TxData interface {
|
|||||||
EffectiveCost(baseFee *big.Int) *big.Int
|
EffectiveCost(baseFee *big.Int) *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: All non-protected transactions (i.e non EIP155 signed) will fail if the RejectUnprotectedTx parameter is enabled.
|
||||||
func NewTxDataFromTx(tx *ethtypes.Transaction) (TxData, error) {
|
func NewTxDataFromTx(tx *ethtypes.Transaction) (TxData, error) {
|
||||||
var txData TxData
|
var txData TxData
|
||||||
var err error
|
var err error
|
||||||
|
@ -112,8 +112,8 @@ func (AppModule) Name() string {
|
|||||||
// as the fee market module doesn't expose invariants.
|
// as the fee market module doesn't expose invariants.
|
||||||
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {}
|
func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) {}
|
||||||
|
|
||||||
// RegisterQueryService registers a GRPC query service to respond to the
|
// RegisterServices registers the GRPC query service and migrator service to respond to the
|
||||||
// module-specific GRPC queries.
|
// module-specific GRPC queries and handle the upgrade store migration for the module.
|
||||||
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
func (am AppModule) RegisterServices(cfg module.Configurator) {
|
||||||
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
|
types.RegisterQueryServer(cfg.QueryServer(), am.keeper)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user