chore(v0.50.0): Migrating codebase to latest SDK version (#215)
This commit is contained in:
+91
-72
@@ -1,16 +1,24 @@
|
||||
package app
|
||||
|
||||
//nolint:revive
|
||||
import (
|
||||
_ "embed"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
"cosmossdk.io/math"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
|
||||
"cosmossdk.io/depinject"
|
||||
dbm "github.com/cometbft/cometbft-db"
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
circuitkeeper "cosmossdk.io/x/circuit/keeper"
|
||||
"cosmossdk.io/x/upgrade"
|
||||
upgradekeeper "cosmossdk.io/x/upgrade/keeper"
|
||||
|
||||
feegrantkeeper "cosmossdk.io/x/feegrant/keeper"
|
||||
feegrantmodule "cosmossdk.io/x/feegrant/module"
|
||||
cometabci "github.com/cometbft/cometbft/abci/types"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
tmtypes "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
@@ -20,31 +28,22 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/server/api"
|
||||
"github.com/cosmos/cosmos-sdk/server/config"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
"github.com/cosmos/cosmos-sdk/store/streaming"
|
||||
storetypes "github.com/cosmos/cosmos-sdk/store/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/ante"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
||||
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/capability"
|
||||
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
|
||||
consensus "github.com/cosmos/cosmos-sdk/x/consensus"
|
||||
"github.com/cosmos/cosmos-sdk/x/consensus"
|
||||
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
|
||||
distr "github.com/cosmos/cosmos-sdk/x/distribution"
|
||||
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/evidence"
|
||||
evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
|
||||
feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
|
||||
feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
@@ -54,7 +53,6 @@ import (
|
||||
groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/mint"
|
||||
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
|
||||
nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
|
||||
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
|
||||
@@ -63,9 +61,8 @@ import (
|
||||
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
||||
"github.com/cosmos/cosmos-sdk/x/upgrade"
|
||||
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
|
||||
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
|
||||
|
||||
veabci "github.com/skip-mev/pob/abci"
|
||||
"github.com/skip-mev/pob/blockbuster"
|
||||
"github.com/skip-mev/pob/blockbuster/abci"
|
||||
"github.com/skip-mev/pob/blockbuster/lanes/auction"
|
||||
@@ -92,29 +89,24 @@ var (
|
||||
auth.AppModuleBasic{},
|
||||
genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
|
||||
bank.AppModuleBasic{},
|
||||
capability.AppModuleBasic{},
|
||||
staking.AppModuleBasic{},
|
||||
mint.AppModuleBasic{},
|
||||
distr.AppModuleBasic{},
|
||||
gov.NewAppModuleBasic(
|
||||
[]govclient.ProposalHandler{
|
||||
paramsclient.ProposalHandler,
|
||||
upgradeclient.LegacyProposalHandler,
|
||||
upgradeclient.LegacyCancelProposalHandler,
|
||||
},
|
||||
),
|
||||
params.AppModuleBasic{},
|
||||
crisis.AppModuleBasic{},
|
||||
slashing.AppModuleBasic{},
|
||||
feegrantmodule.AppModuleBasic{},
|
||||
upgrade.AppModuleBasic{},
|
||||
evidence.AppModuleBasic{},
|
||||
authzmodule.AppModuleBasic{},
|
||||
groupmodule.AppModuleBasic{},
|
||||
vesting.AppModuleBasic{},
|
||||
nftmodule.AppModuleBasic{},
|
||||
consensus.AppModuleBasic{},
|
||||
buildermodule.AppModuleBasic{},
|
||||
feegrantmodule.AppModuleBasic{},
|
||||
)
|
||||
)
|
||||
|
||||
@@ -125,7 +117,6 @@ var (
|
||||
|
||||
type TestApp struct {
|
||||
*runtime.App
|
||||
|
||||
legacyAmino *codec.LegacyAmino
|
||||
appCodec codec.Codec
|
||||
txConfig client.TxConfig
|
||||
@@ -134,7 +125,6 @@ type TestApp struct {
|
||||
// keepers
|
||||
AccountKeeper authkeeper.AccountKeeper
|
||||
BankKeeper bankkeeper.Keeper
|
||||
CapabilityKeeper *capabilitykeeper.Keeper
|
||||
StakingKeeper *stakingkeeper.Keeper
|
||||
SlashingKeeper slashingkeeper.Keeper
|
||||
MintKeeper mintkeeper.Keeper
|
||||
@@ -144,11 +134,11 @@ type TestApp struct {
|
||||
UpgradeKeeper *upgradekeeper.Keeper
|
||||
ParamsKeeper paramskeeper.Keeper
|
||||
AuthzKeeper authzkeeper.Keeper
|
||||
EvidenceKeeper evidencekeeper.Keeper
|
||||
FeeGrantKeeper feegrantkeeper.Keeper
|
||||
GroupKeeper groupkeeper.Keeper
|
||||
ConsensusParamsKeeper consensuskeeper.Keeper
|
||||
CircuitBreakerKeeper circuitkeeper.Keeper
|
||||
BuilderKeeper builderkeeper.Keeper
|
||||
FeeGrantKeeper feegrantkeeper.Keeper
|
||||
|
||||
// custom checkTx handler
|
||||
checkTxHandler abci.CheckTx
|
||||
@@ -182,6 +172,8 @@ func New(
|
||||
// supply the application options
|
||||
appOpts,
|
||||
|
||||
logger,
|
||||
|
||||
// ADVANCED CONFIGURATION
|
||||
|
||||
//
|
||||
@@ -216,7 +208,6 @@ func New(
|
||||
&app.interfaceRegistry,
|
||||
&app.AccountKeeper,
|
||||
&app.BankKeeper,
|
||||
&app.CapabilityKeeper,
|
||||
&app.StakingKeeper,
|
||||
&app.SlashingKeeper,
|
||||
&app.MintKeeper,
|
||||
@@ -226,11 +217,11 @@ func New(
|
||||
&app.UpgradeKeeper,
|
||||
&app.ParamsKeeper,
|
||||
&app.AuthzKeeper,
|
||||
&app.EvidenceKeeper,
|
||||
&app.FeeGrantKeeper,
|
||||
&app.GroupKeeper,
|
||||
&app.BuilderKeeper,
|
||||
&app.ConsensusParamsKeeper,
|
||||
&app.FeeGrantKeeper,
|
||||
&app.CircuitBreakerKeeper,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -261,35 +252,42 @@ func New(
|
||||
// }
|
||||
// baseAppOptions = append(baseAppOptions, prepareOpt)
|
||||
|
||||
app.App = appBuilder.Build(logger, db, traceStore, baseAppOptions...)
|
||||
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
|
||||
|
||||
// ---------------------------------------------------------------------------- //
|
||||
// ------------------------- Begin Custom Code -------------------------------- //
|
||||
// ---------------------------------------------------------------------------- //
|
||||
|
||||
// Set POB's mempool into the app.
|
||||
config := blockbuster.BaseLaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: sdk.ZeroDec(),
|
||||
}
|
||||
|
||||
// Create the lanes.
|
||||
//
|
||||
// NOTE: The lanes are ordered by priority. The first lane is the highest priority
|
||||
// lane and the last lane is the lowest priority lane.
|
||||
|
||||
// Top of block lane allows transactions to bid for inclusion at the top of the next block.
|
||||
tobConfig := blockbuster.BaseLaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
}
|
||||
tobLane := auction.NewTOBLane(
|
||||
config,
|
||||
tobConfig,
|
||||
0,
|
||||
auction.NewDefaultAuctionFactory(app.txConfig.TxDecoder()),
|
||||
)
|
||||
|
||||
// Free lane allows transactions to be included in the next block for free.
|
||||
freeConfig := blockbuster.BaseLaneConfig{
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []blockbuster.Lane{
|
||||
tobLane,
|
||||
},
|
||||
}
|
||||
freeLane := free.NewFreeLane(
|
||||
config,
|
||||
freeConfig,
|
||||
free.NewDefaultFreeFactory(app.txConfig.TxDecoder()),
|
||||
)
|
||||
|
||||
@@ -298,19 +296,20 @@ func New(
|
||||
Logger: app.Logger(),
|
||||
TxEncoder: app.txConfig.TxEncoder(),
|
||||
TxDecoder: app.txConfig.TxDecoder(),
|
||||
MaxBlockSpace: sdk.ZeroDec(),
|
||||
MaxBlockSpace: math.LegacyZeroDec(),
|
||||
IgnoreList: []blockbuster.Lane{
|
||||
tobLane,
|
||||
freeLane,
|
||||
},
|
||||
}
|
||||
defaultLane := base.NewDefaultLane(defaultConfig)
|
||||
|
||||
// Set the lanes into the mempool.
|
||||
lanes := []blockbuster.Lane{
|
||||
tobLane,
|
||||
freeLane,
|
||||
defaultLane,
|
||||
}
|
||||
|
||||
mempool := blockbuster.NewMempool(lanes...)
|
||||
app.App.SetMempool(mempool)
|
||||
|
||||
@@ -338,24 +337,36 @@ func New(
|
||||
for _, lane := range lanes {
|
||||
lane.SetAnteHandler(anteHandler)
|
||||
}
|
||||
|
||||
// Set the proposal handlers on the BaseApp along with the custom antehandler.
|
||||
proposalHandlers := abci.NewProposalHandler(
|
||||
app.Logger(),
|
||||
app.txConfig.TxDecoder(),
|
||||
mempool,
|
||||
)
|
||||
app.App.SetPrepareProposal(proposalHandlers.PrepareProposalHandler())
|
||||
app.App.SetProcessProposal(proposalHandlers.ProcessProposalHandler())
|
||||
app.App.SetAnteHandler(anteHandler)
|
||||
|
||||
// Set the proposal handlers on base app
|
||||
proposalHandler := veabci.NewProposalHandler(
|
||||
lanes,
|
||||
tobLane,
|
||||
app.Logger(),
|
||||
app.txConfig.TxEncoder(),
|
||||
app.txConfig.TxDecoder(),
|
||||
veabci.NoOpValidateVoteExtensionsFn(),
|
||||
)
|
||||
app.App.SetPrepareProposal(proposalHandler.PrepareProposalHandler())
|
||||
app.App.SetProcessProposal(proposalHandler.ProcessProposalHandler())
|
||||
|
||||
// Set the vote extension handler on the app.
|
||||
voteExtensionHandler := veabci.NewVoteExtensionHandler(
|
||||
app.Logger(),
|
||||
tobLane,
|
||||
app.txConfig.TxDecoder(),
|
||||
app.txConfig.TxEncoder(),
|
||||
)
|
||||
app.App.SetExtendVoteHandler(voteExtensionHandler.ExtendVoteHandler())
|
||||
app.App.SetVerifyVoteExtensionHandler(voteExtensionHandler.VerifyVoteExtensionHandler())
|
||||
|
||||
// Set the custom CheckTx handler on BaseApp.
|
||||
checkTxHandler := abci.NewCheckTxHandler(
|
||||
app.App,
|
||||
app.txConfig.TxDecoder(),
|
||||
tobLane,
|
||||
anteHandler,
|
||||
ChainID,
|
||||
)
|
||||
app.SetCheckTx(checkTxHandler.CheckTx())
|
||||
|
||||
@@ -363,12 +374,6 @@ func New(
|
||||
// ------------------------- End Custom Code ---------------------------------- //
|
||||
// ---------------------------------------------------------------------------- //
|
||||
|
||||
// load state streaming if enabled
|
||||
if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
|
||||
logger.Error("failed to load state streaming", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
/**** Module Options ****/
|
||||
|
||||
app.ModuleManager.RegisterInvariants(app.CrisisKeeper)
|
||||
@@ -401,7 +406,7 @@ func New(
|
||||
// handler so that we can verify bid transactions before they are inserted into the mempool.
|
||||
// With the POB CheckTx, we can verify the bid transaction and all of the bundled transactions
|
||||
// before inserting the bid transaction into the mempool.
|
||||
func (app *TestApp) CheckTx(req cometabci.RequestCheckTx) cometabci.ResponseCheckTx {
|
||||
func (app *TestApp) CheckTx(req *cometabci.RequestCheckTx) (*cometabci.ResponseCheckTx, error) {
|
||||
return app.checkTxHandler(req)
|
||||
}
|
||||
|
||||
@@ -410,6 +415,31 @@ func (app *TestApp) SetCheckTx(handler abci.CheckTx) {
|
||||
app.checkTxHandler = handler
|
||||
}
|
||||
|
||||
// TODO: remove this once we have a proper config file
|
||||
func (app *TestApp) InitChain(req *cometabci.RequestInitChain) (*cometabci.ResponseInitChain, error) {
|
||||
req.ConsensusParams.Abci.VoteExtensionsEnableHeight = 2
|
||||
resp, err := app.App.InitChain(req)
|
||||
if resp == nil {
|
||||
resp = &cometabci.ResponseInitChain{}
|
||||
}
|
||||
resp.ConsensusParams = &tmtypes.ConsensusParams{
|
||||
Abci: &tmtypes.ABCIParams{
|
||||
VoteExtensionsEnableHeight: 2,
|
||||
},
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// TODO: remove this once we have a proper config file
|
||||
func (app *TestApp) FinalizeBlock(req *cometabci.RequestFinalizeBlock) (*cometabci.ResponseFinalizeBlock, error) {
|
||||
resp, err := app.App.FinalizeBlock(req)
|
||||
if resp != nil {
|
||||
resp.ConsensusParamUpdates = nil
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Name returns the name of the App
|
||||
func (app *TestApp) Name() string { return app.BaseApp.Name() }
|
||||
|
||||
@@ -451,17 +481,6 @@ func (app *TestApp) GetKey(storeKey string) *storetypes.KVStoreKey {
|
||||
return kvStoreKey
|
||||
}
|
||||
|
||||
func (app *TestApp) kvStoreKeys() map[string]*storetypes.KVStoreKey {
|
||||
keys := make(map[string]*storetypes.KVStoreKey)
|
||||
for _, k := range app.GetStoreKeys() {
|
||||
if kv, ok := k.(*storetypes.KVStoreKey); ok {
|
||||
keys[kv.Name()] = kv
|
||||
}
|
||||
}
|
||||
|
||||
return keys
|
||||
}
|
||||
|
||||
// GetSubspace returns a param subspace for a given module name.
|
||||
//
|
||||
// NOTE: This is solely to be used for testing purposes.
|
||||
|
||||
+80
-67
@@ -3,16 +3,17 @@ package app
|
||||
import (
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
|
||||
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
|
||||
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
|
||||
authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
|
||||
bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
|
||||
capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
|
||||
circuitmodulev1 "cosmossdk.io/api/cosmos/circuit/module/v1"
|
||||
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
|
||||
crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
|
||||
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
|
||||
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
|
||||
feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
|
||||
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
|
||||
govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
|
||||
@@ -24,46 +25,54 @@ import (
|
||||
txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
|
||||
upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
|
||||
vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
|
||||
"cosmossdk.io/depinject"
|
||||
|
||||
_ "cosmossdk.io/x/circuit" // import for side-effects
|
||||
_ "cosmossdk.io/x/upgrade" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/auth/vesting" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/authz/module" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/bank" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/consensus" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/crisis" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/distribution" // import for side-effects
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/group/module" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/mint" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/params" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/slashing" // import for side-effects
|
||||
_ "github.com/cosmos/cosmos-sdk/x/staking" // import for side-effects
|
||||
_ "github.com/skip-mev/pob/x/builder" // import for side-effects
|
||||
|
||||
"cosmossdk.io/core/appconfig"
|
||||
circuittypes "cosmossdk.io/x/circuit/types"
|
||||
"cosmossdk.io/x/feegrant"
|
||||
upgradetypes "cosmossdk.io/x/upgrade/types"
|
||||
"github.com/cosmos/cosmos-sdk/runtime"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
||||
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
|
||||
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/feegrant"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/group"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
|
||||
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||
buildermodulev1 "github.com/skip-mev/pob/api/pob/builder/module/v1"
|
||||
buildertypes "github.com/skip-mev/pob/x/builder/types"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// NOTE: The genutils module must occur after staking so that pools are
|
||||
// properly initialized with tokens from genesis accounts.
|
||||
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
|
||||
// NOTE: Capability module must occur first so that it can initialize any capabilities
|
||||
// so that other modules that want to create or claim capabilities afterwards in InitChain
|
||||
// can do so safely.
|
||||
genesisModuleOrder = []string{
|
||||
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
|
||||
distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
|
||||
minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
|
||||
feegrant.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
|
||||
vestingtypes.ModuleName, consensustypes.ModuleName, buildertypes.ModuleName,
|
||||
}
|
||||
|
||||
// module account permissions
|
||||
moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
|
||||
{Account: authtypes.FeeCollectorName},
|
||||
@@ -87,58 +96,35 @@ var (
|
||||
}
|
||||
|
||||
// application configuration (used by depinject)
|
||||
AppConfig = appconfig.Compose(&appv1alpha1.Config{
|
||||
AppConfig = depinject.Configs(appconfig.Compose(&appv1alpha1.Config{
|
||||
Modules: []*appv1alpha1.ModuleConfig{
|
||||
{
|
||||
Name: "runtime",
|
||||
Name: runtime.ModuleName,
|
||||
Config: appconfig.WrapAny(&runtimev1alpha1.Module{
|
||||
AppName: "TestApp",
|
||||
// During begin block slashing happens after distr.BeginBlocker so that
|
||||
// there is nothing left over in the validator fee pool, so as to keep the
|
||||
// CanWithdrawInvariant invariant.
|
||||
// NOTE: staking module is required if HistoricalEntries param > 0
|
||||
// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)
|
||||
BeginBlockers: []string{
|
||||
upgradetypes.ModuleName,
|
||||
capabilitytypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
distrtypes.ModuleName,
|
||||
slashingtypes.ModuleName,
|
||||
evidencetypes.ModuleName,
|
||||
stakingtypes.ModuleName,
|
||||
authtypes.ModuleName,
|
||||
banktypes.ModuleName,
|
||||
govtypes.ModuleName,
|
||||
crisistypes.ModuleName,
|
||||
genutiltypes.ModuleName,
|
||||
authz.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
group.ModuleName,
|
||||
paramstypes.ModuleName,
|
||||
vestingtypes.ModuleName,
|
||||
buildertypes.ModuleName,
|
||||
consensustypes.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
},
|
||||
EndBlockers: []string{
|
||||
crisistypes.ModuleName,
|
||||
govtypes.ModuleName,
|
||||
stakingtypes.ModuleName,
|
||||
capabilitytypes.ModuleName,
|
||||
authtypes.ModuleName,
|
||||
banktypes.ModuleName,
|
||||
distrtypes.ModuleName,
|
||||
slashingtypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
genutiltypes.ModuleName,
|
||||
evidencetypes.ModuleName,
|
||||
authz.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
group.ModuleName,
|
||||
paramstypes.ModuleName,
|
||||
consensustypes.ModuleName,
|
||||
upgradetypes.ModuleName,
|
||||
vestingtypes.ModuleName,
|
||||
buildertypes.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
},
|
||||
OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
|
||||
{
|
||||
@@ -146,12 +132,34 @@ var (
|
||||
KvStoreKey: "acc",
|
||||
},
|
||||
},
|
||||
InitGenesis: genesisModuleOrder,
|
||||
// NOTE: The genutils module must occur after staking so that pools are
|
||||
// properly initialized with tokens from genesis accounts.
|
||||
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
|
||||
InitGenesis: []string{
|
||||
authtypes.ModuleName,
|
||||
banktypes.ModuleName,
|
||||
distrtypes.ModuleName,
|
||||
stakingtypes.ModuleName,
|
||||
slashingtypes.ModuleName,
|
||||
govtypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
crisistypes.ModuleName,
|
||||
genutiltypes.ModuleName,
|
||||
authz.ModuleName,
|
||||
group.ModuleName,
|
||||
paramstypes.ModuleName,
|
||||
upgradetypes.ModuleName,
|
||||
vestingtypes.ModuleName,
|
||||
consensustypes.ModuleName,
|
||||
circuittypes.ModuleName,
|
||||
buildertypes.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
},
|
||||
// When ExportGenesis is not specified, the export genesis module order
|
||||
// is equal to the init genesis order
|
||||
// ExportGenesis: genesisModuleOrder,
|
||||
// ExportGenesis: []string{},
|
||||
// Uncomment if you want to set a custom migration order here.
|
||||
// OrderMigrations: nil,
|
||||
// OrderMigrations: []string{},
|
||||
}),
|
||||
},
|
||||
{
|
||||
@@ -168,6 +176,10 @@ var (
|
||||
Name: vestingtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&vestingmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: feegrant.ModuleName,
|
||||
Config: appconfig.WrapAny(&feegrantmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: banktypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&bankmodulev1.Module{
|
||||
@@ -206,16 +218,6 @@ var (
|
||||
Name: distrtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&distrmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: capabilitytypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&capabilitymodulev1.Module{
|
||||
SealKeeper: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: evidencetypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&evidencemodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: minttypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&mintmodulev1.Module{}),
|
||||
@@ -227,10 +229,6 @@ var (
|
||||
MaxMetadataLen: 255,
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: feegrant.ModuleName,
|
||||
Config: appconfig.WrapAny(&feegrantmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: govtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&govmodulev1.Module{}),
|
||||
@@ -243,10 +241,25 @@ var (
|
||||
Name: consensustypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&consensusmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: circuittypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&circuitmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: buildertypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&buildermodulev1.Module{}),
|
||||
},
|
||||
},
|
||||
})
|
||||
}),
|
||||
depinject.Supply(
|
||||
// supply custom module basics
|
||||
map[string]module.AppModuleBasic{
|
||||
genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
|
||||
govtypes.ModuleName: gov.NewAppModuleBasic(
|
||||
[]govclient.ProposalHandler{
|
||||
paramsclient.ProposalHandler,
|
||||
},
|
||||
),
|
||||
},
|
||||
))
|
||||
)
|
||||
|
||||
+44
-17
@@ -5,7 +5,9 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
|
||||
storetypes "cosmossdk.io/store/types"
|
||||
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@@ -16,19 +18,23 @@ import (
|
||||
|
||||
// ExportAppStateAndValidators exports the state of the application for a genesis
|
||||
// file.
|
||||
func (app *TestApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs []string, modulesToExport []string) (servertypes.ExportedApp, error) {
|
||||
func (app *TestApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs, modulesToExport []string) (servertypes.ExportedApp, error) {
|
||||
// as if they could withdraw from the start of the next block
|
||||
ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
|
||||
ctx := app.NewContextLegacy(true, cmtproto.Header{Height: app.LastBlockHeight()})
|
||||
|
||||
// We export at last height + 1, because that's the height at which
|
||||
// Tendermint will start InitChain.
|
||||
// CometBFT will start InitChain.
|
||||
height := app.LastBlockHeight() + 1
|
||||
if forZeroHeight {
|
||||
height = 0
|
||||
app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs)
|
||||
}
|
||||
|
||||
genState := app.ModuleManager.ExportGenesisForModules(ctx, app.appCodec, modulesToExport)
|
||||
genState, err := app.ModuleManager.ExportGenesisForModules(ctx, app.appCodec, modulesToExport)
|
||||
if err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
|
||||
appState, err := json.MarshalIndent(genState, "", " ")
|
||||
if err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
@@ -46,7 +52,7 @@ func (app *TestApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedA
|
||||
// prepare for fresh start at zero height
|
||||
// NOTE zero height genesis is a temporary feature which will be deprecated
|
||||
//
|
||||
// in favour of export at a block height
|
||||
// in favor of export at a block height
|
||||
func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
|
||||
applyAllowedAddrs := false
|
||||
|
||||
@@ -71,13 +77,20 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
/* Handle fee distribution state. */
|
||||
|
||||
// withdraw all validator commission
|
||||
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
err := app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// withdraw all delegator rewards
|
||||
dels := app.StakingKeeper.GetAllDelegations(ctx)
|
||||
dels, err := app.StakingKeeper.GetAllDelegations(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for _, delegation := range dels {
|
||||
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
|
||||
if err != nil {
|
||||
@@ -102,10 +115,18 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
// reinitialize all validators
|
||||
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
|
||||
scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
|
||||
feePool := app.DistrKeeper.GetFeePool(ctx)
|
||||
scraps, err := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
feePool, err := app.DistrKeeper.FeePool.Get(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
|
||||
app.DistrKeeper.SetFeePool(ctx, feePool)
|
||||
if err := app.DistrKeeper.FeePool.Set(ctx, feePool); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()); err != nil {
|
||||
panic(err)
|
||||
@@ -142,7 +163,10 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
for i := range red.Entries {
|
||||
red.Entries[i].CreationHeight = 0
|
||||
}
|
||||
app.StakingKeeper.SetRedelegation(ctx, red)
|
||||
err = app.StakingKeeper.SetRedelegation(ctx, red)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
@@ -151,20 +175,23 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
for i := range ubd.Entries {
|
||||
ubd.Entries[i].CreationHeight = 0
|
||||
}
|
||||
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
err = app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// Iterate through validators by power descending, reset bond heights, and
|
||||
// update bond intra-tx counters.
|
||||
store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey))
|
||||
iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
|
||||
iter := storetypes.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
|
||||
counter := int16(0)
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
||||
validator, found := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if !found {
|
||||
validator, err := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if err != nil {
|
||||
panic("expected validator, not found")
|
||||
}
|
||||
|
||||
@@ -182,7 +209,7 @@ func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs [
|
||||
return
|
||||
}
|
||||
|
||||
_, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
_, err = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"cosmossdk.io/log"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
|
||||
pruningtypes "cosmossdk.io/store/pruning/types"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
"github.com/cosmos/cosmos-sdk/types/module/testutil"
|
||||
)
|
||||
|
||||
// NewTestNetworkFixture returns a new simapp AppConstructor for network simulation tests
|
||||
func NewTestNetworkFixture() network.TestFixture {
|
||||
dir, err := os.MkdirTemp("", "simapp")
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("failed creating temporary directory: %v", err))
|
||||
}
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
app := New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(dir))
|
||||
|
||||
appCtr := func(val network.ValidatorI) servertypes.Application {
|
||||
return New(
|
||||
val.GetCtx().Logger, dbm.NewMemDB(), nil, true,
|
||||
simtestutil.NewAppOptionsWithFlagHome(val.GetCtx().Config.RootDir),
|
||||
bam.SetPruning(pruningtypes.NewPruningOptionsFromString(val.GetAppConfig().Pruning)),
|
||||
bam.SetMinGasPrices(val.GetAppConfig().MinGasPrices),
|
||||
bam.SetChainID(val.GetCtx().Viper.GetString(flags.FlagChainID)),
|
||||
)
|
||||
}
|
||||
|
||||
return network.TestFixture{
|
||||
AppConstructor: appCtr,
|
||||
GenesisState: app.DefaultGenesis(),
|
||||
EncodingConfig: testutil.TestEncodingConfig{
|
||||
InterfaceRegistry: app.InterfaceRegistry(),
|
||||
Codec: app.AppCodec(),
|
||||
TxConfig: app.TxConfig(),
|
||||
Amino: app.LegacyAmino(),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,17 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
dbm "github.com/cometbft/cometbft-db"
|
||||
tmcfg "github.com/cometbft/cometbft/config"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
cmtcfg "github.com/cometbft/cometbft/config"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"cosmossdk.io/client/v2/autocli"
|
||||
"cosmossdk.io/depinject"
|
||||
"cosmossdk.io/log"
|
||||
confixcmd "cosmossdk.io/tools/confix/cmd"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/client/debug"
|
||||
@@ -15,49 +23,64 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/client/pruning"
|
||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
"github.com/cosmos/cosmos-sdk/client/snapshot"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/tx"
|
||||
txmodule "github.com/cosmos/cosmos-sdk/x/auth/tx/config"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
"github.com/skip-mev/pob/tests/app/params"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// NewRootCmd creates a new root command for simd. It is called once in the main function.
|
||||
func NewRootCmd() *cobra.Command {
|
||||
// we "pre"-instantiate the application for getting the injected/configured encoding configuration
|
||||
testApp := app.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(app.DefaultNodeHome))
|
||||
encodingConfig := params.EncodingConfig{
|
||||
InterfaceRegistry: testApp.InterfaceRegistry(),
|
||||
Codec: testApp.AppCodec(),
|
||||
TxConfig: testApp.TxConfig(),
|
||||
Amino: testApp.LegacyAmino(),
|
||||
var (
|
||||
interfaceRegistry codectypes.InterfaceRegistry
|
||||
appCodec codec.Codec
|
||||
txConfig client.TxConfig
|
||||
legacyAmino *codec.LegacyAmino
|
||||
autoCliOpts autocli.AppOptions
|
||||
moduleBasicManager module.BasicManager
|
||||
)
|
||||
|
||||
if err := depinject.Inject(depinject.Configs(app.AppConfig, depinject.Supply(log.NewNopLogger())),
|
||||
&interfaceRegistry,
|
||||
&appCodec,
|
||||
&txConfig,
|
||||
&legacyAmino,
|
||||
&autoCliOpts,
|
||||
&moduleBasicManager,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
initClientCtx := client.Context{}.
|
||||
WithCodec(encodingConfig.Codec).
|
||||
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
|
||||
WithTxConfig(encodingConfig.TxConfig).
|
||||
WithLegacyAmino(encodingConfig.Amino).
|
||||
WithCodec(appCodec).
|
||||
WithInterfaceRegistry(interfaceRegistry).
|
||||
WithLegacyAmino(legacyAmino).
|
||||
WithInput(os.Stdin).
|
||||
WithAccountRetriever(types.AccountRetriever{}).
|
||||
WithHomeDir(app.DefaultNodeHome).
|
||||
WithViper("")
|
||||
WithViper("") // In simapp, we don't use any prefix for env variables.
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "testappd",
|
||||
Short: "POB testing application",
|
||||
Short: "POB's simulation app",
|
||||
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||
// set the default command outputs
|
||||
cmd.SetOut(cmd.OutOrStdout())
|
||||
cmd.SetErr(cmd.ErrOrStderr())
|
||||
|
||||
initClientCtx = initClientCtx.WithCmdContext(cmd.Context())
|
||||
initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -68,26 +91,45 @@ func NewRootCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
// This needs to go after ReadFromClientConfig, as that function
|
||||
// sets the RPC client needed for SIGN_MODE_TEXTUAL.
|
||||
enabledSignModes := append([]signing.SignMode{signing.SignMode_SIGN_MODE_DIRECT}, tx.DefaultSignModes...)
|
||||
txConfigOpts := tx.ConfigOptions{
|
||||
EnabledSignModes: enabledSignModes,
|
||||
TextualCoinMetadataQueryFn: txmodule.NewGRPCCoinMetadataQueryFn(initClientCtx),
|
||||
}
|
||||
txConfigWithTextual, err := tx.NewTxConfigWithOptions(
|
||||
codec.NewProtoCodec(interfaceRegistry),
|
||||
txConfigOpts,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
initClientCtx = initClientCtx.WithTxConfig(txConfigWithTextual)
|
||||
if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
customAppTemplate, customAppConfig := initAppConfig()
|
||||
customTMConfig := initTendermintConfig()
|
||||
customCMTConfig := initCometBFTConfig()
|
||||
|
||||
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig)
|
||||
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customCMTConfig)
|
||||
},
|
||||
}
|
||||
|
||||
initRootCmd(rootCmd, encodingConfig)
|
||||
initRootCmd(rootCmd, txConfig, interfaceRegistry, appCodec, moduleBasicManager)
|
||||
|
||||
if err := autoCliOpts.EnhanceRootCommand(rootCmd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
// initTendermintConfig helps to override default Tendermint Config values.
|
||||
// return tmcfg.DefaultConfig if no custom configuration is required for the application.
|
||||
func initTendermintConfig() *tmcfg.Config {
|
||||
cfg := tmcfg.DefaultConfig()
|
||||
// initCometBFTConfig helps to override default CometBFT Config values.
|
||||
// return cmtcfg.DefaultConfig if no custom configuration is required for the application.
|
||||
func initCometBFTConfig() *cmtcfg.Config {
|
||||
cfg := cmtcfg.DefaultConfig()
|
||||
|
||||
// these values put a higher strain on node memory
|
||||
// cfg.P2P.MaxNumInboundPeers = 100
|
||||
@@ -130,7 +172,7 @@ func initAppConfig() (string, interface{}) {
|
||||
// - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
|
||||
// own app.toml to override, or use this default value.
|
||||
//
|
||||
// In testapp, we set the min gas prices to 0.
|
||||
// In simapp, we set the min gas prices to 0.
|
||||
srvCfg.MinGasPrices = "0stake"
|
||||
// srvCfg.BaseConfig.IAVLDisableFastNode = true // disable fastnode by default
|
||||
|
||||
@@ -153,15 +195,23 @@ lru_size = 0`
|
||||
return customAppTemplate, customAppConfig
|
||||
}
|
||||
|
||||
func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
|
||||
func initRootCmd(
|
||||
rootCmd *cobra.Command,
|
||||
txConfig client.TxConfig,
|
||||
_ codectypes.InterfaceRegistry,
|
||||
_ codec.Codec,
|
||||
basicManager module.BasicManager,
|
||||
) {
|
||||
cfg := sdk.GetConfig()
|
||||
cfg.Seal()
|
||||
|
||||
rootCmd.AddCommand(
|
||||
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
|
||||
genutilcli.InitCmd(basicManager, app.DefaultNodeHome),
|
||||
NewTestnetCmd(basicManager, banktypes.GenesisBalancesIterator{}),
|
||||
debug.Cmd(),
|
||||
config.Cmd(),
|
||||
pruning.PruningCmd(newApp),
|
||||
confixcmd.ConfigCommand(),
|
||||
pruning.Cmd(newApp, app.DefaultNodeHome),
|
||||
snapshot.Cmd(newApp),
|
||||
)
|
||||
|
||||
server.AddCommands(rootCmd, app.DefaultNodeHome, newApp, appExport, addModuleInitFlags)
|
||||
@@ -169,7 +219,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
|
||||
// add keybase, auxiliary RPC, query, genesis, and tx child commands
|
||||
rootCmd.AddCommand(
|
||||
rpc.StatusCommand(),
|
||||
genesisCommand(encodingConfig),
|
||||
genesisCommand(txConfig, basicManager),
|
||||
queryCommand(),
|
||||
txCommand(),
|
||||
keys.Commands(app.DefaultNodeHome),
|
||||
@@ -180,13 +230,13 @@ func addModuleInitFlags(startCmd *cobra.Command) {
|
||||
crisis.AddModuleInitFlags(startCmd)
|
||||
}
|
||||
|
||||
func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command {
|
||||
cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, app.ModuleBasics, app.DefaultNodeHome)
|
||||
// genesisCommand builds genesis-related `simd genesis` command. Users may provide application specific commands as a parameter
|
||||
func genesisCommand(txConfig client.TxConfig, basicManager module.BasicManager, cmds ...*cobra.Command) *cobra.Command {
|
||||
cmd := genutilcli.Commands(txConfig, basicManager, app.DefaultNodeHome)
|
||||
|
||||
for _, subCmd := range cmds {
|
||||
cmd.AddCommand(subCmd)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -201,15 +251,13 @@ func queryCommand() *cobra.Command {
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
authcmd.GetAccountCmd(),
|
||||
rpc.ValidatorCommand(),
|
||||
rpc.BlockCommand(),
|
||||
server.QueryBlockCmd(),
|
||||
authcmd.QueryTxsByEventsCmd(),
|
||||
server.QueryBlocksCmd(),
|
||||
authcmd.QueryTxCmd(),
|
||||
)
|
||||
|
||||
app.ModuleBasics.AddQueryCommands(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
@@ -234,29 +282,26 @@ func txCommand() *cobra.Command {
|
||||
authcmd.GetAuxToFeeCommand(),
|
||||
)
|
||||
|
||||
app.ModuleBasics.AddTxCommands(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// newApp creates the application
|
||||
func newApp(
|
||||
logger log.Logger,
|
||||
db dbm.DB,
|
||||
traceStore io.Writer,
|
||||
appOpts servertypes.AppOptions,
|
||||
) servertypes.Application {
|
||||
baseAppOpts := server.DefaultBaseappOptions(appOpts)
|
||||
baseappOptions := server.DefaultBaseappOptions(appOpts)
|
||||
|
||||
return app.New(
|
||||
logger,
|
||||
db,
|
||||
traceStore,
|
||||
true,
|
||||
logger, db, traceStore, true,
|
||||
appOpts,
|
||||
baseAppOpts...,
|
||||
baseappOptions...,
|
||||
)
|
||||
}
|
||||
|
||||
// appExport creates a new simapp (optionally at a given height) and exports state.
|
||||
func appExport(
|
||||
logger log.Logger,
|
||||
db dbm.DB,
|
||||
@@ -267,8 +312,6 @@ func appExport(
|
||||
appOpts servertypes.AppOptions,
|
||||
modulesToExport []string,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
var testApp *app.TestApp
|
||||
|
||||
// this check is necessary as we use the flag in x/upgrade.
|
||||
// we can exit more gracefully by checking the flag here.
|
||||
homePath, ok := appOpts.Get(flags.FlagHome).(string)
|
||||
@@ -285,15 +328,16 @@ func appExport(
|
||||
viperAppOpts.Set(server.FlagInvCheckPeriod, 1)
|
||||
appOpts = viperAppOpts
|
||||
|
||||
var simApp *app.TestApp
|
||||
if height != -1 {
|
||||
testApp = app.New(logger, db, traceStore, false, appOpts)
|
||||
simApp = app.New(logger, db, traceStore, false, appOpts)
|
||||
|
||||
if err := testApp.LoadHeight(height); err != nil {
|
||||
if err := simApp.LoadHeight(height); err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
} else {
|
||||
testApp = app.New(logger, db, traceStore, true, appOpts)
|
||||
simApp = app.New(logger, db, traceStore, true, appOpts)
|
||||
}
|
||||
|
||||
return testApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
|
||||
return simApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,522 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
cmtconfig "github.com/cometbft/cometbft/config"
|
||||
cmttime "github.com/cometbft/cometbft/types/time"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
"cosmossdk.io/math/unsafe"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/tx"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/hd"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
srvconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||
"github.com/cosmos/cosmos-sdk/testutil"
|
||||
"github.com/cosmos/cosmos-sdk/testutil/network"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
var (
|
||||
flagNodeDirPrefix = "node-dir-prefix"
|
||||
flagNumValidators = "v"
|
||||
flagOutputDir = "output-dir"
|
||||
flagNodeDaemonHome = "node-daemon-home"
|
||||
flagStartingIPAddress = "starting-ip-address"
|
||||
flagEnableLogging = "enable-logging"
|
||||
flagGRPCAddress = "grpc.address"
|
||||
flagRPCAddress = "rpc.address"
|
||||
flagAPIAddress = "api.address"
|
||||
flagPrintMnemonic = "print-mnemonic"
|
||||
)
|
||||
|
||||
type initArgs struct {
|
||||
algo string
|
||||
chainID string
|
||||
keyringBackend string
|
||||
minGasPrices string
|
||||
nodeDaemonHome string
|
||||
nodeDirPrefix string
|
||||
numValidators int
|
||||
outputDir string
|
||||
startingIPAddress string
|
||||
}
|
||||
|
||||
type startArgs struct {
|
||||
algo string
|
||||
apiAddress string
|
||||
chainID string
|
||||
enableLogging bool
|
||||
grpcAddress string
|
||||
minGasPrices string
|
||||
numValidators int
|
||||
outputDir string
|
||||
printMnemonic bool
|
||||
rpcAddress string
|
||||
}
|
||||
|
||||
func addTestnetFlagsToCmd(cmd *cobra.Command) {
|
||||
cmd.Flags().Int(flagNumValidators, 4, "Number of validators to initialize the testnet with")
|
||||
cmd.Flags().StringP(flagOutputDir, "o", "./.testnets", "Directory to store initialization data for the testnet")
|
||||
cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
|
||||
cmd.Flags().String(server.FlagMinGasPrices, fmt.Sprintf("0.000006%s", sdk.DefaultBondDenom), "Minimum gas prices to accept for transactions; All fees in a tx must meet this minimum (e.g. 0.01photino,0.001stake)")
|
||||
cmd.Flags().String(flags.FlagKeyType, string(hd.Secp256k1Type), "Key signing algorithm to generate keys for")
|
||||
|
||||
// support old flags name for backwards compatibility
|
||||
cmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||
if name == "algo" {
|
||||
name = flags.FlagKeyType
|
||||
}
|
||||
|
||||
return pflag.NormalizedName(name)
|
||||
})
|
||||
}
|
||||
|
||||
// NewTestnetCmd creates a root testnet command with subcommands to run an in-process testnet or initialize
|
||||
// validator configuration files for running a multi-validator testnet in a separate process
|
||||
func NewTestnetCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command {
|
||||
testnetCmd := &cobra.Command{
|
||||
Use: "testnet",
|
||||
Short: "subcommands for starting or configuring local testnets",
|
||||
DisableFlagParsing: true,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
testnetCmd.AddCommand(testnetStartCmd())
|
||||
testnetCmd.AddCommand(testnetInitFilesCmd(mbm, genBalIterator))
|
||||
|
||||
return testnetCmd
|
||||
}
|
||||
|
||||
// testnetInitFilesCmd returns a cmd to initialize all files for CometBFT testnet and application
|
||||
func testnetInitFilesCmd(mbm module.BasicManager, genBalIterator banktypes.GenesisBalancesIterator) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "init-files",
|
||||
Short: "Initialize config directories & files for a multi-validator testnet running locally via separate processes (e.g. Docker Compose or similar)",
|
||||
Long: `init-files will setup "v" number of directories and populate each with
|
||||
necessary files (private validator, genesis, config, etc.) for running "v" validator nodes.
|
||||
|
||||
Booting up a network with these validator folders is intended to be used with Docker Compose,
|
||||
or a similar setup where each node has a manually configurable IP address.
|
||||
|
||||
Note, strict routability for addresses is turned off in the config file.
|
||||
|
||||
Example:
|
||||
simd testnet init-files --v 4 --output-dir ./.testnets --starting-ip-address 192.168.10.2
|
||||
`,
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
clientCtx, err := client.GetClientQueryContext(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
serverCtx := server.GetServerContextFromCmd(cmd)
|
||||
config := serverCtx.Config
|
||||
|
||||
args := initArgs{}
|
||||
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
|
||||
args.keyringBackend, _ = cmd.Flags().GetString(flags.FlagKeyringBackend)
|
||||
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
|
||||
args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices)
|
||||
args.nodeDirPrefix, _ = cmd.Flags().GetString(flagNodeDirPrefix)
|
||||
args.nodeDaemonHome, _ = cmd.Flags().GetString(flagNodeDaemonHome)
|
||||
args.startingIPAddress, _ = cmd.Flags().GetString(flagStartingIPAddress)
|
||||
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
|
||||
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType)
|
||||
|
||||
return initTestnetFiles(clientCtx, cmd, config, mbm, genBalIterator, args)
|
||||
},
|
||||
}
|
||||
|
||||
addTestnetFlagsToCmd(cmd)
|
||||
cmd.Flags().String(flagNodeDirPrefix, "node", "Prefix the directory name for each node with (node results in node0, node1, ...)")
|
||||
cmd.Flags().String(flagNodeDaemonHome, "simd", "Home directory of the node's daemon configuration")
|
||||
cmd.Flags().String(flagStartingIPAddress, "192.168.0.1", "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)")
|
||||
cmd.Flags().String(flags.FlagKeyringBackend, flags.DefaultKeyringBackend, "Select keyring's backend (os|file|test)")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// testnetStartCmd returns a cmd to start multi validator in-process testnet
|
||||
func testnetStartCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "Launch an in-process multi-validator testnet",
|
||||
Long: `testnet will launch an in-process multi-validator testnet,
|
||||
and generate "v" directories, populated with necessary validator configuration files
|
||||
(private validator, genesis, config, etc.).
|
||||
|
||||
Example:
|
||||
simd testnet --v 4 --output-dir ./.testnets
|
||||
`,
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
args := startArgs{}
|
||||
args.outputDir, _ = cmd.Flags().GetString(flagOutputDir)
|
||||
args.chainID, _ = cmd.Flags().GetString(flags.FlagChainID)
|
||||
args.minGasPrices, _ = cmd.Flags().GetString(server.FlagMinGasPrices)
|
||||
args.numValidators, _ = cmd.Flags().GetInt(flagNumValidators)
|
||||
args.algo, _ = cmd.Flags().GetString(flags.FlagKeyType)
|
||||
args.enableLogging, _ = cmd.Flags().GetBool(flagEnableLogging)
|
||||
args.rpcAddress, _ = cmd.Flags().GetString(flagRPCAddress)
|
||||
args.apiAddress, _ = cmd.Flags().GetString(flagAPIAddress)
|
||||
args.grpcAddress, _ = cmd.Flags().GetString(flagGRPCAddress)
|
||||
args.printMnemonic, _ = cmd.Flags().GetBool(flagPrintMnemonic)
|
||||
|
||||
return startTestnet(cmd, args)
|
||||
},
|
||||
}
|
||||
|
||||
addTestnetFlagsToCmd(cmd)
|
||||
cmd.Flags().Bool(flagEnableLogging, false, "Enable INFO logging of CometBFT validator nodes")
|
||||
cmd.Flags().String(flagRPCAddress, "tcp://0.0.0.0:26657", "the RPC address to listen on")
|
||||
cmd.Flags().String(flagAPIAddress, "tcp://0.0.0.0:1317", "the address to listen on for REST API")
|
||||
cmd.Flags().String(flagGRPCAddress, "0.0.0.0:9090", "the gRPC server address to listen on")
|
||||
cmd.Flags().Bool(flagPrintMnemonic, true, "print mnemonic of first validator to stdout for manual testing")
|
||||
return cmd
|
||||
}
|
||||
|
||||
const nodeDirPerm = 0o755
|
||||
|
||||
// initTestnetFiles initializes testnet files for a testnet to be run in a separate process
|
||||
func initTestnetFiles(
|
||||
clientCtx client.Context,
|
||||
cmd *cobra.Command,
|
||||
nodeConfig *cmtconfig.Config,
|
||||
mbm module.BasicManager,
|
||||
genBalIterator banktypes.GenesisBalancesIterator,
|
||||
args initArgs,
|
||||
) error {
|
||||
if args.chainID == "" {
|
||||
args.chainID = "chain-" + unsafe.Str(6)
|
||||
}
|
||||
nodeIDs := make([]string, args.numValidators)
|
||||
valPubKeys := make([]cryptotypes.PubKey, args.numValidators)
|
||||
|
||||
simappConfig := srvconfig.DefaultConfig()
|
||||
simappConfig.MinGasPrices = args.minGasPrices
|
||||
simappConfig.API.Enable = true
|
||||
simappConfig.Telemetry.Enabled = true
|
||||
simappConfig.Telemetry.PrometheusRetentionTime = 60
|
||||
simappConfig.Telemetry.EnableHostnameLabel = false
|
||||
simappConfig.Telemetry.GlobalLabels = [][]string{{"chain_id", args.chainID}}
|
||||
|
||||
var (
|
||||
genAccounts []authtypes.GenesisAccount
|
||||
genBalances []banktypes.Balance
|
||||
genFiles []string
|
||||
)
|
||||
|
||||
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||
// generate private keys, node IDs, and initial transactions
|
||||
for i := 0; i < args.numValidators; i++ {
|
||||
nodeDirName := fmt.Sprintf("%s%d", args.nodeDirPrefix, i)
|
||||
nodeDir := filepath.Join(args.outputDir, nodeDirName, args.nodeDaemonHome)
|
||||
gentxsDir := filepath.Join(args.outputDir, "gentxs")
|
||||
|
||||
nodeConfig.SetRoot(nodeDir)
|
||||
nodeConfig.Moniker = nodeDirName
|
||||
nodeConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm); err != nil {
|
||||
_ = os.RemoveAll(args.outputDir)
|
||||
return err
|
||||
}
|
||||
|
||||
ip, err := getIP(i, args.startingIPAddress)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(args.outputDir)
|
||||
return err
|
||||
}
|
||||
|
||||
nodeIDs[i], valPubKeys[i], err = genutil.InitializeNodeValidatorFiles(nodeConfig)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(args.outputDir)
|
||||
return err
|
||||
}
|
||||
|
||||
memo := fmt.Sprintf("%s@%s:26656", nodeIDs[i], ip)
|
||||
genFiles = append(genFiles, nodeConfig.GenesisFile())
|
||||
|
||||
kb, err := keyring.New(sdk.KeyringServiceName(), args.keyringBackend, nodeDir, inBuf, clientCtx.Codec)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keyringAlgos, _ := kb.SupportedAlgorithms()
|
||||
algo, err := keyring.NewSigningAlgoFromString(args.algo, keyringAlgos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
addr, secret, err := testutil.GenerateSaveCoinKey(kb, nodeDirName, "", true, algo)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(args.outputDir)
|
||||
return err
|
||||
}
|
||||
|
||||
info := map[string]string{"secret": secret}
|
||||
|
||||
cliPrint, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// save private key seed words
|
||||
if err := writeFile(fmt.Sprintf("%v.json", "key_seed"), nodeDir, cliPrint); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
accTokens := sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction)
|
||||
accStakingTokens := sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction)
|
||||
coins := sdk.Coins{
|
||||
sdk.NewCoin("testtoken", accTokens),
|
||||
sdk.NewCoin(sdk.DefaultBondDenom, accStakingTokens),
|
||||
}
|
||||
|
||||
genBalances = append(genBalances, banktypes.Balance{Address: addr.String(), Coins: coins.Sort()})
|
||||
genAccounts = append(genAccounts, authtypes.NewBaseAccount(addr, nil, 0, 0))
|
||||
|
||||
valTokens := sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction)
|
||||
createValMsg, err := stakingtypes.NewMsgCreateValidator(
|
||||
sdk.ValAddress(addr),
|
||||
valPubKeys[i],
|
||||
sdk.NewCoin(sdk.DefaultBondDenom, valTokens),
|
||||
stakingtypes.NewDescription(nodeDirName, "", "", "", ""),
|
||||
stakingtypes.NewCommissionRates(math.LegacyOneDec(), math.LegacyOneDec(), math.LegacyOneDec()),
|
||||
math.OneInt(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txBuilder := clientCtx.TxConfig.NewTxBuilder()
|
||||
if err := txBuilder.SetMsgs(createValMsg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txBuilder.SetMemo(memo)
|
||||
|
||||
txFactory := tx.Factory{}
|
||||
txFactory = txFactory.
|
||||
WithChainID(args.chainID).
|
||||
WithMemo(memo).
|
||||
WithKeybase(kb).
|
||||
WithTxConfig(clientCtx.TxConfig)
|
||||
|
||||
if err := tx.Sign(cmd.Context(), txFactory, nodeDirName, txBuilder, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
txBz, err := clientCtx.TxConfig.TxJSONEncoder()(txBuilder.GetTx())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := writeFile(fmt.Sprintf("%v.json", nodeDirName), gentxsDir, txBz); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
srvconfig.WriteConfigFile(filepath.Join(nodeDir, "config", "app.toml"), simappConfig)
|
||||
}
|
||||
|
||||
if err := initGenFiles(clientCtx, mbm, args.chainID, genAccounts, genBalances, genFiles, args.numValidators); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := collectGenFiles(
|
||||
clientCtx, nodeConfig, args.chainID, nodeIDs, valPubKeys, args.numValidators,
|
||||
args.outputDir, args.nodeDirPrefix, args.nodeDaemonHome, genBalIterator,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd.PrintErrf("Successfully initialized %d node directories\n", args.numValidators)
|
||||
return nil
|
||||
}
|
||||
|
||||
func initGenFiles(
|
||||
clientCtx client.Context, mbm module.BasicManager, chainID string,
|
||||
genAccounts []authtypes.GenesisAccount, genBalances []banktypes.Balance,
|
||||
genFiles []string, numValidators int,
|
||||
) error {
|
||||
appGenState := mbm.DefaultGenesis(clientCtx.Codec)
|
||||
|
||||
// set the accounts in the genesis state
|
||||
var authGenState authtypes.GenesisState
|
||||
clientCtx.Codec.MustUnmarshalJSON(appGenState[authtypes.ModuleName], &authGenState)
|
||||
|
||||
accounts, err := authtypes.PackAccounts(genAccounts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
authGenState.Accounts = accounts
|
||||
appGenState[authtypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&authGenState)
|
||||
|
||||
// set the balances in the genesis state
|
||||
var bankGenState banktypes.GenesisState
|
||||
clientCtx.Codec.MustUnmarshalJSON(appGenState[banktypes.ModuleName], &bankGenState)
|
||||
|
||||
bankGenState.Balances = banktypes.SanitizeGenesisBalances(genBalances)
|
||||
for _, bal := range bankGenState.Balances {
|
||||
bankGenState.Supply = bankGenState.Supply.Add(bal.Coins...)
|
||||
}
|
||||
appGenState[banktypes.ModuleName] = clientCtx.Codec.MustMarshalJSON(&bankGenState)
|
||||
|
||||
appGenStateJSON, err := json.MarshalIndent(appGenState, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
appGenesis := genutiltypes.NewAppGenesisWithVersion(chainID, appGenStateJSON)
|
||||
// generate empty genesis files for each validator and save
|
||||
for i := 0; i < numValidators; i++ {
|
||||
if err := appGenesis.SaveAs(genFiles[i]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func collectGenFiles(
|
||||
clientCtx client.Context, nodeConfig *cmtconfig.Config, chainID string,
|
||||
nodeIDs []string, valPubKeys []cryptotypes.PubKey, numValidators int,
|
||||
outputDir, nodeDirPrefix, nodeDaemonHome string, genBalIterator banktypes.GenesisBalancesIterator,
|
||||
) error {
|
||||
var appState json.RawMessage
|
||||
genTime := cmttime.Now()
|
||||
|
||||
for i := 0; i < numValidators; i++ {
|
||||
nodeDirName := fmt.Sprintf("%s%d", nodeDirPrefix, i)
|
||||
nodeDir := filepath.Join(outputDir, nodeDirName, nodeDaemonHome)
|
||||
gentxsDir := filepath.Join(outputDir, "gentxs")
|
||||
nodeConfig.Moniker = nodeDirName
|
||||
|
||||
nodeConfig.SetRoot(nodeDir)
|
||||
|
||||
nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
|
||||
initCfg := genutiltypes.NewInitConfig(chainID, gentxsDir, nodeID, valPubKey)
|
||||
|
||||
appGenesis, err := genutiltypes.AppGenesisFromFile(nodeConfig.GenesisFile())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nodeAppState, err := genutil.GenAppStateFromConfig(clientCtx.Codec, clientCtx.TxConfig, nodeConfig, initCfg, appGenesis, genBalIterator, genutiltypes.DefaultMessageValidator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if appState == nil {
|
||||
// set the canonical application state (they should not differ)
|
||||
appState = nodeAppState
|
||||
}
|
||||
|
||||
genFile := nodeConfig.GenesisFile()
|
||||
|
||||
// overwrite each validator's genesis file to have a canonical genesis time
|
||||
if err := genutil.ExportGenesisFileWithTime(genFile, chainID, nil, appState, genTime); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getIP(i int, startingIPAddr string) (ip string, err error) {
|
||||
if len(startingIPAddr) == 0 {
|
||||
ip, err = server.ExternalIP()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ip, nil
|
||||
}
|
||||
return calculateIP(startingIPAddr, i)
|
||||
}
|
||||
|
||||
func calculateIP(ip string, i int) (string, error) {
|
||||
ipv4 := net.ParseIP(ip).To4()
|
||||
if ipv4 == nil {
|
||||
return "", fmt.Errorf("%v: non ipv4 address", ip)
|
||||
}
|
||||
|
||||
for j := 0; j < i; j++ {
|
||||
ipv4[3]++
|
||||
}
|
||||
|
||||
return ipv4.String(), nil
|
||||
}
|
||||
|
||||
func writeFile(name, dir string, contents []byte) error {
|
||||
file := filepath.Join(dir, name)
|
||||
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
return fmt.Errorf("could not create directory %q: %w", dir, err)
|
||||
}
|
||||
|
||||
return os.WriteFile(file, contents, 0o600)
|
||||
}
|
||||
|
||||
// startTestnet starts an in-process testnet
|
||||
func startTestnet(cmd *cobra.Command, args startArgs) error {
|
||||
networkConfig := network.DefaultConfig(app.NewTestNetworkFixture)
|
||||
|
||||
// Default networkConfig.ChainID is random, and we should only override it if chainID provided
|
||||
// is non-empty
|
||||
if args.chainID != "" {
|
||||
networkConfig.ChainID = args.chainID
|
||||
}
|
||||
networkConfig.SigningAlgo = args.algo
|
||||
networkConfig.MinGasPrices = args.minGasPrices
|
||||
networkConfig.NumValidators = args.numValidators
|
||||
networkConfig.EnableLogging = args.enableLogging
|
||||
networkConfig.RPCAddress = args.rpcAddress
|
||||
networkConfig.APIAddress = args.apiAddress
|
||||
networkConfig.GRPCAddress = args.grpcAddress
|
||||
networkConfig.PrintMnemonic = args.printMnemonic
|
||||
networkLogger := network.NewCLILogger(cmd)
|
||||
|
||||
baseDir := fmt.Sprintf("%s/%s", args.outputDir, networkConfig.ChainID)
|
||||
if _, err := os.Stat(baseDir); !os.IsNotExist(err) {
|
||||
return fmt.Errorf(
|
||||
"testnests directory already exists for chain-id '%s': %s, please remove or select a new --chain-id",
|
||||
networkConfig.ChainID, baseDir)
|
||||
}
|
||||
|
||||
testnet, err := network.New(networkLogger, baseDir, networkConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := testnet.WaitForHeight(1); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Println("press the Enter Key to terminate")
|
||||
if _, err := fmt.Scanln(); err != nil { // wait for Enter Key
|
||||
return err
|
||||
}
|
||||
testnet.Cleanup()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -3,21 +3,16 @@ package main
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
"cosmossdk.io/log"
|
||||
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
"github.com/skip-mev/pob/tests/app/testappd/cmd"
|
||||
cmd "github.com/skip-mev/pob/tests/app/testappd/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rootCmd := cmd.NewRootCmd()
|
||||
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
||||
switch e := err.(type) {
|
||||
case server.ErrorCode:
|
||||
os.Exit(e.Code)
|
||||
|
||||
default:
|
||||
os.Exit(1)
|
||||
}
|
||||
log.NewLogger(rootCmd.OutOrStderr()).Error("failure when running app", "err", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -4,8 +4,8 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
dbm "github.com/cometbft/cometbft-db"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
"cosmossdk.io/log"
|
||||
dbm "github.com/cosmos/cosmos-db"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
@@ -40,7 +40,11 @@ type chain struct {
|
||||
}
|
||||
|
||||
func newChain() (*chain, error) {
|
||||
tmpDir, err := os.MkdirTemp("", "pob-e2e-testnet-")
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
tmpDir, err := os.MkdirTemp(pwd, ".pob-e2e-testnet-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+11
-10
@@ -11,6 +11,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
cometcfg "github.com/cometbft/cometbft/config"
|
||||
cometjson "github.com/cometbft/cometbft/libs/json"
|
||||
rpchttp "github.com/cometbft/cometbft/rpc/client/http"
|
||||
@@ -31,9 +32,9 @@ import (
|
||||
|
||||
var (
|
||||
numValidators = 4
|
||||
minGasPrice = sdk.NewDecCoinFromDec(app.BondDenom, sdk.MustNewDecFromStr("0.02")).String()
|
||||
minGasPrice = sdk.NewDecCoinFromDec(app.BondDenom, math.LegacyMustNewDecFromStr("0.02")).String()
|
||||
initBalanceStr = sdk.NewInt64Coin(app.BondDenom, 1000000000000000000).String()
|
||||
stakeAmount, _ = sdk.NewIntFromString("100000000000")
|
||||
stakeAmount = math.NewInt(100000000000)
|
||||
stakeAmountCoin = sdk.NewCoin(app.BondDenom, stakeAmount)
|
||||
)
|
||||
|
||||
@@ -116,15 +117,12 @@ func (s *IntegrationTestSuite) initNodes() {
|
||||
val0ConfigDir := s.chain.validators[0].configDir()
|
||||
|
||||
// Define the builder module parameters
|
||||
escrowAddress, err := sdk.AccAddressFromBech32("cosmos14j5j2lsx7629590jvpk3vj0xe9w8203jf4yknk")
|
||||
s.Require().Nil(err, "Unexpected error decoding escrow address")
|
||||
|
||||
params := types.Params{
|
||||
MaxBundleSize: 5,
|
||||
EscrowAccountAddress: escrowAddress,
|
||||
ReserveFee: sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000)),
|
||||
MinBidIncrement: sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000)),
|
||||
ProposerFee: sdk.NewDecWithPrec(1, 2),
|
||||
EscrowAccountAddress: sdk.MustAccAddressFromBech32("cosmos14j5j2lsx7629590jvpk3vj0xe9w8203jf4yknk").Bytes(),
|
||||
ReserveFee: sdk.NewCoin(app.BondDenom, math.NewInt(1000000)),
|
||||
MinBidIncrement: sdk.NewCoin(app.BondDenom, math.NewInt(1000000)),
|
||||
ProposerFee: math.LegacyMustNewDecFromStr("0.1"),
|
||||
FrontRunningProtection: true,
|
||||
}
|
||||
|
||||
@@ -162,7 +160,7 @@ func (s *IntegrationTestSuite) initGenesis() {
|
||||
|
||||
votingPeriod := 5 * time.Second
|
||||
govGenState.Params.VotingPeriod = &votingPeriod
|
||||
govGenState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(100)))
|
||||
govGenState.Params.MinDeposit = sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(100)))
|
||||
|
||||
bz, err := cdc.MarshalJSON(&govGenState)
|
||||
s.Require().NoError(err)
|
||||
@@ -223,6 +221,9 @@ func (s *IntegrationTestSuite) initValidatorConfigs() {
|
||||
valConfig.RPC.ListenAddress = "tcp://0.0.0.0:26657"
|
||||
valConfig.StateSync.Enable = false
|
||||
valConfig.LogLevel = "info"
|
||||
valConfig.BaseConfig.Genesis = filepath.Join("config", "genesis.json")
|
||||
valConfig.RootDir = filepath.Join("root", ".simapp")
|
||||
valConfig.Consensus.TimeoutCommit = 2 * time.Second
|
||||
|
||||
var peers []string
|
||||
|
||||
|
||||
+182
-181
@@ -3,6 +3,7 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"cosmossdk.io/math"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
)
|
||||
@@ -28,7 +29,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
accounts := s.createTestAccounts(numAccounts, initBalance)
|
||||
|
||||
// basic send amount
|
||||
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
|
||||
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
|
||||
|
||||
// auction parameters
|
||||
params := s.queryBuilderParams()
|
||||
@@ -39,7 +40,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
|
||||
// standard tx params
|
||||
gasLimit := uint64(5000000)
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -56,15 +57,17 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure that the block was correctly created and executed in the order expected
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
@@ -72,7 +75,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
bundleHashes[0]: true,
|
||||
bundleHashes[1]: true,
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
|
||||
@@ -91,15 +94,17 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
bundle[i] = s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, uint64(i), 1000, gasLimit, fees)
|
||||
}
|
||||
|
||||
// Wait for a block to ensure all transactions are included in the same block
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.displayExpectedBundle("gud auction bid", bidTx, bundle)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// broadcast the bid so that it can be included in a vote extension of a coming block
|
||||
s.waitForABlock()
|
||||
|
||||
// Execute a few other messages to be included in the block after the bid and bundle
|
||||
normalTxs := make([][]byte, 3)
|
||||
@@ -128,7 +133,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
expectedExecution[hash] = true
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
|
||||
@@ -147,32 +152,33 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
bundle[i] = s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, uint64(i), 1000, gasLimit, fees)
|
||||
}
|
||||
|
||||
// Wait for a block to ensure all transactions are included in the same block
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.displayExpectedBundle("gud auction bid 1", bidTx, bundle)
|
||||
|
||||
// Create another bid transaction that includes the bundle and is valid from the same account
|
||||
// to verify that user can bid with the same account multiple times in the same block
|
||||
bid2 := bid.Add(minBidIncrement)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[1], bid2, bundle, 0, height+1, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[1], bid2, bundle, 0, height+3, gasLimit, fees)
|
||||
s.displayExpectedBundle("gud auction bid 2", bidTx2, bundle)
|
||||
|
||||
// Create a third bid
|
||||
bid3 := bid2.Add(minBidIncrement)
|
||||
bidTx3 := s.createAuctionBidTx(accounts[1], bid3, bundle, 0, height+1, gasLimit, fees)
|
||||
s.broadcastTx(bidTx3, 0)
|
||||
bidTx3 := s.createAuctionBidTx(accounts[1], bid3, bundle, 0, height+3, gasLimit, fees)
|
||||
s.displayExpectedBundle("gud auction bid 3", bidTx3, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
// Wait for a block to ensure all transactions are included in the same block
|
||||
s.waitForABlock()
|
||||
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
s.broadcastTx(bidTx3, 0)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure that the block was correctly created and executed in the order expected
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
|
||||
@@ -180,14 +186,13 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
expectedExecution := map[string]bool{
|
||||
bundleHashes[0]: false,
|
||||
bundleHashes2[0]: false,
|
||||
bundleHashes3[0]: true,
|
||||
}
|
||||
|
||||
for _, hash := range bundleHashes3[1:] {
|
||||
for _, hash := range bundleHashes3 {
|
||||
expectedExecution[hash] = true
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes3, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+3, bundleHashes3, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid3)
|
||||
@@ -212,17 +217,21 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.displayExpectedBundle("gud auction bid", bidTx, bundle)
|
||||
|
||||
// Broadcast the bid transaction
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Wait for a block to broadcast other transactions so that the normal txs can be included in the
|
||||
// mempool before they are included in a proposal with the vote extensions
|
||||
s.waitForABlock()
|
||||
|
||||
// Broadcast all of the transactions in the bundle to the mempool
|
||||
for _, tx := range bundle {
|
||||
s.broadcastTx(tx, 0)
|
||||
}
|
||||
|
||||
// Broadcast the bid transaction
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Broadcast some other transactions to the mempool
|
||||
normalTxs := make([][]byte, 10)
|
||||
for i := 0; i < 10; i++ {
|
||||
@@ -247,7 +256,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
expectedExecution[hash] = true
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
|
||||
@@ -272,9 +281,13 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Wait for a block to broadcast other transactions so that the normal txs can be included in the
|
||||
// mempool before they are included in a proposal with the vote extensions
|
||||
s.waitForABlock()
|
||||
|
||||
// Execute a few other messages to be included in the block after the bid and bundle
|
||||
normalTxs := make([][]byte, 3)
|
||||
normalTxs[0] = s.createMsgSendTx(accounts[1], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees)
|
||||
@@ -306,7 +319,7 @@ func (s *IntegrationTestSuite) TestValidBids() {
|
||||
expectedExecution[hash] = true
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
|
||||
@@ -338,7 +351,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
accounts := s.createTestAccounts(numAccounts, initBalance)
|
||||
|
||||
// basic send amount
|
||||
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
|
||||
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
|
||||
|
||||
// auction parameters
|
||||
params := s.queryBuilderParams()
|
||||
@@ -349,7 +362,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
|
||||
// standard tx params
|
||||
gasLimit := uint64(5000000)
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -378,7 +391,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
|
||||
|
||||
// Createa a second bid transaction that includes the bundle and is valid
|
||||
bid2 := reserveFee.Add(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
|
||||
bid2 := reserveFee.Add(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
|
||||
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, bundle2, 0, height+5, gasLimit, fees)
|
||||
|
||||
// Wait for a block to ensure all transactions are included in the same block
|
||||
@@ -413,7 +426,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
}
|
||||
|
||||
// Pass in nil since we don't know the order of transactions that ill be executed
|
||||
s.verifyTopOfBlockAuction(height+2, nil, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+3, nil, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance (both bids should have been extracted by this point)
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid).Add(s.calculateProposerEscrowSplit(bid2))
|
||||
@@ -443,18 +456,18 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+2, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("gud auction bid 1", bidTx, bundle)
|
||||
|
||||
// Create another bid transaction that includes the bundle and is valid from a different account
|
||||
bid2 := bid.Add(minBidIncrement)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, bundle2, 0, height+1, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, bundle2, 0, height+5, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 1)
|
||||
s.displayExpectedBundle("gud auction bid 2", bidTx2, bundle2)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(3)
|
||||
|
||||
// Ensure that the block was correctly created and executed in the order expected
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
@@ -467,10 +480,10 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
expectedExecution[hash] = true
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(3)
|
||||
|
||||
// Ensure that the block was correctly created and executed in the order expected
|
||||
expectedExecution = map[string]bool{
|
||||
@@ -481,7 +494,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
expectedExecution[hash] = true
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+4, bundleHashes, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance (both bids should have been extracted by this point)
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid).Add(s.calculateProposerEscrowSplit(bid2))
|
||||
@@ -499,21 +512,23 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bid 1", bidTx, bundle)
|
||||
|
||||
// Create a second bid transaction that includes the bundle and is valid (but smaller than the min bid increment)
|
||||
badBid := reserveFee.Add(sdk.NewInt64Coin(app.BondDenom, 10))
|
||||
bidTx2 := s.createAuctionBidTx(accounts[0], badBid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[0], badBid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
s.displayExpectedBundle("bid 2", bidTx2, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure only the first bid was executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
@@ -523,7 +538,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
bundleHashes[1]: true,
|
||||
bundleHashes2[0]: false,
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
|
||||
@@ -531,7 +546,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
|
||||
// Wait another block to make sure the second bid is not executed
|
||||
s.waitForABlock()
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+4, bundleHashes2, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -545,21 +560,23 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
s.createMsgSendTx(accounts[2], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bid 1", bidTx, bundle)
|
||||
|
||||
// Create a second bid transaction that includes the bundle and is valid (but smaller than the min bid increment)
|
||||
badBid := reserveFee.Add(sdk.NewInt64Coin(app.BondDenom, 10))
|
||||
bidTx2 := s.createAuctionBidTx(accounts[1], badBid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[1], badBid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
s.displayExpectedBundle("bid 2", bidTx2, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure only the first bid was executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
@@ -569,7 +586,7 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
bundleHashes[1]: true,
|
||||
bundleHashes2[0]: false,
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid)
|
||||
@@ -577,99 +594,55 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
|
||||
// Wait another block to make sure the second bid is not executed
|
||||
s.waitForABlock()
|
||||
s.verifyTopOfBlockAuction(height+4, bundleHashes2, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Multiple transactions with increasing bids but first bid has same bundle so it should fail in later block (different accounts)",
|
||||
test: func() {
|
||||
// Get escrow account balance
|
||||
escrowBalance := s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom)
|
||||
|
||||
// Create a bundle with a single transaction
|
||||
bundle := [][]byte{
|
||||
s.createMsgSendTx(accounts[2], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bid 1", bidTx, bundle)
|
||||
|
||||
// Create a second bid transaction that includes the bundle and is valid
|
||||
bid2 := reserveFee.Add(minBidIncrement)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[0], bid2, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 1)
|
||||
s.displayExpectedBundle("bid 2", bidTx2, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure only the second bid was executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
|
||||
expectedExecution := map[string]bool{
|
||||
bundleHashes[0]: false,
|
||||
bundleHashes2[0]: true,
|
||||
bundleHashes2[1]: true,
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Multiple transactions with increasing bids but first bid has same bundle so it should fail in later block (same account)",
|
||||
test: func() {
|
||||
// Get escrow account balance
|
||||
escrowBalance := s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom)
|
||||
|
||||
// Create a bundle with a single transaction
|
||||
bundle := [][]byte{
|
||||
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+2, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bid 1", bidTx, bundle)
|
||||
|
||||
// Create a second bid transaction that includes the bundle and is valid
|
||||
bid2 := reserveFee.Add(minBidIncrement)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[0], bid2, bundle, 0, height+1, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
s.displayExpectedBundle("bid 2", bidTx2, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
|
||||
// Ensure only the second bid was executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
|
||||
expectedExecution := map[string]bool{
|
||||
bundleHashes[0]: false,
|
||||
bundleHashes2[0]: true,
|
||||
bundleHashes2[1]: true,
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid2)
|
||||
s.Require().Equal(expectedEscrowFee.Add(escrowBalance), s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom))
|
||||
|
||||
// Wait for a block to be created and ensure that the first bid was not executed
|
||||
s.waitForABlock()
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Multiple transactions with increasing bids but first bid has same bundle so it should fail in later block (different account)",
|
||||
test: func() {
|
||||
// Get escrow account balance
|
||||
escrowBalance := s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom)
|
||||
|
||||
// Create a bundle with a single transaction
|
||||
bundle := [][]byte{
|
||||
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+2, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bid 1", bidTx, bundle)
|
||||
|
||||
// Create a second bid transaction that includes the bundle and is valid
|
||||
bid2 := reserveFee.Add(minBidIncrement)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[1], bid2, bundle, 0, height+1, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
s.displayExpectedBundle("bid 2", bidTx2, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
|
||||
// Ensure only the second bid was executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
bundleHashes2 := s.bundleToTxHashes(bidTx2, bundle)
|
||||
expectedExecution := map[string]bool{
|
||||
bundleHashes[0]: false,
|
||||
bundleHashes2[0]: true,
|
||||
bundleHashes2[1]: true,
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid2)
|
||||
s.Require().Equal(expectedEscrowFee.Add(escrowBalance), s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom))
|
||||
|
||||
// Wait for a block to be created and ensure that the first bid was not executed
|
||||
s.waitForABlock()
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
s.waitForNBlocks(2)
|
||||
s.verifyTopOfBlockAuction(height+4, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -688,21 +661,23 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
s.createMsgSendTx(accounts[1], accounts[0].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle and is valid
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, firstBundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, firstBundle, 0, height+2, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bid 1", bidTx, firstBundle)
|
||||
|
||||
// Create a second bid transaction that includes the bundle and is valid
|
||||
bid2 := reserveFee.Add(minBidIncrement)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, secondBundle, 0, height+1, gasLimit, fees)
|
||||
bidTx2 := s.createAuctionBidTx(accounts[3], bid2, secondBundle, 0, height+2, gasLimit, fees)
|
||||
s.broadcastTx(bidTx2, 0)
|
||||
s.displayExpectedBundle("bid 2", bidTx2, secondBundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure only the second bid was executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, firstBundle)
|
||||
@@ -713,15 +688,15 @@ func (s *IntegrationTestSuite) TestMultipleBids() {
|
||||
bundleHashes2[0]: true,
|
||||
bundleHashes2[1]: true,
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes2, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes2, expectedExecution)
|
||||
|
||||
// Ensure that the escrow account has the correct balance
|
||||
expectedEscrowFee := s.calculateProposerEscrowSplit(bid2)
|
||||
s.Require().Equal(expectedEscrowFee.Add(escrowBalance), s.queryBalanceOf(sdk.AccAddress(escrowAddress).String(), app.BondDenom))
|
||||
|
||||
// Wait for a block to be created and ensure that the second bid is executed
|
||||
// Wait for a block to be created and ensure that the second bid is not executed
|
||||
s.waitForABlock()
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+4, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -742,7 +717,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
accounts := s.createTestAccounts(numAccounts, initBalance)
|
||||
|
||||
// basic send amount
|
||||
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(10)))
|
||||
defaultSendAmount := sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(10)))
|
||||
|
||||
// auction parameters
|
||||
params := s.queryBuilderParams()
|
||||
@@ -752,7 +727,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
// standard tx params
|
||||
gasLimit := uint64(5000000)
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -772,10 +747,12 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
// Create a bid transaction that includes the bundle
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bad auction bid", bidTx, bundle)
|
||||
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure that the block was built correctly and that the bid was not executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
expectedExecution := map[string]bool{
|
||||
@@ -783,7 +760,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
bundleHashes[1]: false,
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -794,15 +771,18 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
// Wait for a block to ensure all transactions are included in the same block
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle that is attempting to bid more than their balance
|
||||
bid := sdk.NewCoin(app.BondDenom, sdk.NewInt(999999999999999999))
|
||||
bid := sdk.NewCoin(app.BondDenom, math.NewInt(999999999999999999))
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("bad auction bid", bidTx, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
expectedExecution := map[string]bool{
|
||||
@@ -811,7 +791,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
}
|
||||
|
||||
// Ensure that the block was built correctly and that the bid was not executed
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -824,15 +804,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
s.createMsgSendTx(accounts[2], accounts[1].Address.String(), defaultSendAmount, 0, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("front-running auction bid", bidTx, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
expectedExecution := map[string]bool{
|
||||
@@ -843,7 +825,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
}
|
||||
|
||||
// Ensure that the block was built correctly and that the bid was not executed
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -854,15 +836,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1000, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
expectedExecution := map[string]bool{
|
||||
@@ -871,7 +855,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
}
|
||||
|
||||
// Ensure that the block was built correctly and that the bid was not executed
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -882,15 +866,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, 1, 1000, gasLimit, fees),
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes a bid that is smaller than the reserve fee
|
||||
bid := reserveFee.Sub(sdk.NewInt64Coin(app.BondDenom, 1))
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+3, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure that no transactions were executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
@@ -899,7 +885,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
bundleHashes[1]: false,
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -911,15 +897,17 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
bundle = append(bundle, s.createMsgSendTx(accounts[0], accounts[1].Address.String(), defaultSendAmount, uint64(i+1), 1000, gasLimit, fees))
|
||||
}
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Create a bid transaction that includes the bundle
|
||||
bid := reserveFee
|
||||
height := s.queryCurrentHeight()
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+1, gasLimit, fees)
|
||||
bidTx := s.createAuctionBidTx(accounts[0], bid, bundle, 0, height+2, gasLimit, fees)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure that no transactions were executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
@@ -928,7 +916,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
for _, hash := range bundleHashes {
|
||||
expectedExecution[hash] = false
|
||||
}
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -947,7 +935,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
s.displayExpectedBundle("invalid auction bid", bidTx, bundle)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
s.waitForNBlocks(2)
|
||||
|
||||
// Ensure that no transactions were executed
|
||||
bundleHashes := s.bundleToTxHashes(bidTx, bundle)
|
||||
@@ -956,7 +944,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
bundleHashes[1]: false,
|
||||
}
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+2, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -977,14 +965,16 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
// Wait for a block to ensure all transactions are included in the same block
|
||||
s.waitForABlock()
|
||||
|
||||
// Broadcast the bid transaction
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
s.waitForABlock()
|
||||
|
||||
// Broadcast all of the transactions in the bundle
|
||||
for _, tx := range bundle {
|
||||
s.broadcastTx(tx, 0)
|
||||
}
|
||||
|
||||
// Broadcast the bid transaction
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
|
||||
@@ -998,7 +988,7 @@ func (s *IntegrationTestSuite) TestInvalidBids() {
|
||||
|
||||
expectedExecution[bundleHashes[0]] = false
|
||||
|
||||
s.verifyTopOfBlockAuction(height+1, bundleHashes, expectedExecution)
|
||||
s.verifyTopOfBlockAuction(height+3, bundleHashes, expectedExecution)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1025,13 +1015,13 @@ func (s *IntegrationTestSuite) TestFreeLane() {
|
||||
numAccounts := 4
|
||||
accounts := s.createTestAccounts(numAccounts, initBalance)
|
||||
|
||||
defaultSendAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
|
||||
defaultStakeAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
|
||||
defaultSendAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
|
||||
defaultStakeAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
|
||||
defaultSendAmountCoins := sdk.NewCoins(defaultSendAmount)
|
||||
|
||||
// standard tx params
|
||||
gasLimit := uint64(5000000)
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -1146,8 +1136,8 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
numAccounts := 4
|
||||
accounts := s.createTestAccounts(numAccounts, initBalance)
|
||||
|
||||
defaultSendAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
|
||||
defaultStakeAmount := sdk.NewCoin(app.BondDenom, sdk.NewInt(10))
|
||||
defaultSendAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
|
||||
defaultStakeAmount := sdk.NewCoin(app.BondDenom, math.NewInt(10))
|
||||
defaultSendAmountCoins := sdk.NewCoins(defaultSendAmount)
|
||||
|
||||
// auction parameters
|
||||
@@ -1156,7 +1146,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
|
||||
// standard tx params
|
||||
gasLimit := uint64(5000000)
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000)))
|
||||
fees := sdk.NewCoins(sdk.NewCoin("stake", math.NewInt(150000)))
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
@@ -1182,11 +1172,13 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
|
||||
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
|
||||
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Broadcast the transactions
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(freeTx, 0)
|
||||
s.broadcastTx(normalTx, 0)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
@@ -1234,11 +1226,14 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
|
||||
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
|
||||
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Broadcast the transactions
|
||||
s.waitForABlock()
|
||||
|
||||
s.broadcastTx(freeTx, 0)
|
||||
s.broadcastTx(normalTx, 0)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
@@ -1282,11 +1277,13 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
bidTx := s.createAuctionBidTx(accounts[2], bid, bundle, 0, height+5, gasLimit, fees)
|
||||
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
|
||||
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Broadcast the transactions
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(freeTx, 0)
|
||||
s.broadcastTx(normalTx, 0)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
@@ -1316,7 +1313,7 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
// basic free transaction
|
||||
validators := s.queryValidators()
|
||||
validator := validators[0]
|
||||
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(0)))) // Free transaction with no fees
|
||||
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(0)))) // Free transaction with no fees
|
||||
|
||||
// Create a bid transaction that includes the bundle and is invalid (out of sequence number)
|
||||
bundle := [][]byte{
|
||||
@@ -1328,10 +1325,12 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
bidTx := s.createAuctionBidTx(accounts[1], bid, bundle, 0, height+5, gasLimit, fees)
|
||||
s.displayExpectedBundle("Valid auction bid", bidTx, bundle)
|
||||
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Broadcast the transactions
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(freeTx, 0)
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Wait for a block to be created
|
||||
s.waitForABlock()
|
||||
@@ -1359,10 +1358,10 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
// basic free transaction
|
||||
validators := s.queryValidators()
|
||||
validator := validators[0]
|
||||
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(0)))) // Free transaction with no fees
|
||||
freeTx := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 0, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(0)))) // Free transaction with no fees
|
||||
|
||||
// Another free transaction that should be included in the block
|
||||
freeTx2 := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 1, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, sdk.NewInt(0)))) // Free transaction with no fees
|
||||
freeTx2 := s.createMsgDelegateTx(accounts[0], validator.OperatorAddress, defaultStakeAmount, 1, 1000, gasLimit, sdk.NewCoins(sdk.NewCoin(app.BondDenom, math.NewInt(0)))) // Free transaction with no fees
|
||||
|
||||
// Create a bid transaction that includes the bundle and is invalid (out of sequence number)
|
||||
bundle := [][]byte{
|
||||
@@ -1376,9 +1375,11 @@ func (s *IntegrationTestSuite) TestLanes() {
|
||||
|
||||
normalTx := s.createMsgSendTx(accounts[3], accounts[2].Address.String(), defaultSendAmountCoins, 0, 1000, gasLimit, fees)
|
||||
|
||||
// Broadcast the transactions (including the ones in the bundle)
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(bidTx, 0)
|
||||
|
||||
// Broadcast the transactions (including the ones in the bundle)
|
||||
s.waitForABlock()
|
||||
s.broadcastTx(freeTx, 0)
|
||||
s.broadcastTx(bundle[1], 0)
|
||||
s.broadcastTx(freeTx2, 0)
|
||||
|
||||
+35
-23
@@ -7,8 +7,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
clienttx "github.com/cosmos/cosmos-sdk/client/tx"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
@@ -49,7 +49,7 @@ func (s *IntegrationTestSuite) execMsgSendTx(valIdx int, to sdk.AccAddress, amou
|
||||
amount.String(), // amount
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, s.chain.validators[valIdx].keyInfo.Name),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagChainID, s.chain.id),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoin(app.BondDenom, sdk.NewInt(1000000000)).String()),
|
||||
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoin(app.BondDenom, math.NewInt(1000000000)).String()),
|
||||
"--keyring-backend=test",
|
||||
"--broadcast-mode=sync",
|
||||
"-y",
|
||||
@@ -127,41 +127,53 @@ func (s *IntegrationTestSuite) createTx(account TestAccount, msgs []sdk.Msg, seq
|
||||
baseAccount := s.queryAccount(account.Address)
|
||||
sequenceNumber := baseAccount.Sequence + sequenceOffset
|
||||
|
||||
// Set the messages, fees, and timeout.
|
||||
txBuilder.SetMsgs(msgs...)
|
||||
txBuilder.SetGasLimit(5000000)
|
||||
txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(150000))))
|
||||
s.Require().NoError(txBuilder.SetMsgs(msgs...))
|
||||
txBuilder.SetFeeAmount(fees)
|
||||
txBuilder.SetGasLimit(gasLimit)
|
||||
txBuilder.SetTimeoutHeight(height)
|
||||
|
||||
sigV2 := signing.SignatureV2{
|
||||
signerData := authsigning.SignerData{
|
||||
ChainID: app.ChainID,
|
||||
AccountNumber: baseAccount.AccountNumber,
|
||||
Sequence: sequenceNumber,
|
||||
PubKey: account.PrivateKey.PubKey(),
|
||||
}
|
||||
|
||||
sig := signing.SignatureV2{
|
||||
PubKey: account.PrivateKey.PubKey(),
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: txConfig.SignModeHandler().DefaultMode(),
|
||||
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
|
||||
Signature: nil,
|
||||
},
|
||||
Sequence: sequenceNumber,
|
||||
}
|
||||
|
||||
s.Require().NoError(txBuilder.SetSignatures(sigV2))
|
||||
s.Require().NoError(txBuilder.SetSignatures(sig))
|
||||
|
||||
signerData := authsigning.SignerData{
|
||||
ChainID: s.chain.id,
|
||||
AccountNumber: baseAccount.AccountNumber,
|
||||
Sequence: sequenceNumber,
|
||||
}
|
||||
|
||||
sigV2, err := clienttx.SignWithPrivKey(
|
||||
txConfig.SignModeHandler().DefaultMode(),
|
||||
bytesToSign, err := authsigning.GetSignBytesAdapter(
|
||||
context.Background(),
|
||||
encodingConfig.TxConfig.SignModeHandler(),
|
||||
signing.SignMode_SIGN_MODE_DIRECT,
|
||||
signerData,
|
||||
txBuilder,
|
||||
account.PrivateKey,
|
||||
txConfig,
|
||||
sequenceNumber,
|
||||
txBuilder.GetTx(),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NoError(txBuilder.SetSignatures(sigV2))
|
||||
|
||||
bz, err := txConfig.TxEncoder()(txBuilder.GetTx())
|
||||
sigBytes, err := account.PrivateKey.Sign(bytesToSign)
|
||||
s.Require().NoError(err)
|
||||
|
||||
sig = signing.SignatureV2{
|
||||
PubKey: account.PrivateKey.PubKey(),
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
|
||||
Signature: sigBytes,
|
||||
},
|
||||
Sequence: sequenceNumber,
|
||||
}
|
||||
s.Require().NoError(txBuilder.SetSignatures(sig))
|
||||
|
||||
signedTx := txBuilder.GetTx()
|
||||
bz, err := encodingConfig.TxConfig.TxEncoder()(signedTx)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return bz
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
tmclient "github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
||||
cmtclient "github.com/cosmos/cosmos-sdk/client/grpc/cmtservice"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
txtypes "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
@@ -116,6 +116,18 @@ func (s *IntegrationTestSuite) waitForABlock() {
|
||||
)
|
||||
}
|
||||
|
||||
// waitForNBlocks will wait until the current block height has increased by n blocks.
|
||||
func (s *IntegrationTestSuite) waitForNBlocks(n int) {
|
||||
height := s.queryCurrentHeight()
|
||||
s.Require().Eventually(
|
||||
func() bool {
|
||||
return s.queryCurrentHeight() >= height+uint64(n)
|
||||
},
|
||||
10*time.Second,
|
||||
50*time.Millisecond,
|
||||
)
|
||||
}
|
||||
|
||||
// bundleToTxHashes converts a bundle to a slice of transaction hashes.
|
||||
func (s *IntegrationTestSuite) bundleToTxHashes(bidTx []byte, bundle [][]byte) []string {
|
||||
hashes := make([]string, len(bundle)+1)
|
||||
@@ -163,7 +175,7 @@ func (s *IntegrationTestSuite) verifyTopOfBlockAuction(height uint64, bundle []s
|
||||
|
||||
// Check that the block contains the expected transactions in the expected order
|
||||
// iff the bid transaction was expected to execute.
|
||||
if len(bundle) > 0 && expectedExecution[bundle[0]] {
|
||||
if len(bundle) > 0 && len(expectedExecution) > 0 && expectedExecution[bundle[0]] && len(txs) > 0 {
|
||||
if expectedExecution[bundle[0]] {
|
||||
hashBz := sha256.Sum256(txs[0])
|
||||
hash := hex.EncodeToString(hashBz[:])
|
||||
@@ -259,12 +271,12 @@ func (s *IntegrationTestSuite) broadcastTx(tx []byte, valIdx int) {
|
||||
gRPCURI,
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
)
|
||||
s.Require().NoError(err)
|
||||
|
||||
client := txtypes.NewServiceClient(grpcConn)
|
||||
|
||||
req := &txtypes.BroadcastTxRequest{TxBytes: tx, Mode: txtypes.BroadcastMode_BROADCAST_MODE_SYNC}
|
||||
_, err = client.BroadcastTx(context.Background(), req)
|
||||
s.Require().NoError(err)
|
||||
client.BroadcastTx(context.Background(), req)
|
||||
}
|
||||
|
||||
// queryTx queries a transaction by its hash and returns whether there was an
|
||||
@@ -335,9 +347,9 @@ func (s *IntegrationTestSuite) queryAccount(address sdk.AccAddress) *authtypes.B
|
||||
|
||||
// queryCurrentHeight returns the current block height.
|
||||
func (s *IntegrationTestSuite) queryCurrentHeight() uint64 {
|
||||
queryClient := tmclient.NewServiceClient(s.createClientContext())
|
||||
queryClient := cmtclient.NewServiceClient(s.createClientContext())
|
||||
|
||||
req := &tmclient.GetLatestBlockRequest{}
|
||||
req := &cmtclient.GetLatestBlockRequest{}
|
||||
resp, err := queryClient.GetLatestBlock(context.Background(), req)
|
||||
s.Require().NoError(err)
|
||||
|
||||
@@ -346,13 +358,35 @@ func (s *IntegrationTestSuite) queryCurrentHeight() uint64 {
|
||||
|
||||
// queryBlockTxs returns the txs of the block at the given height.
|
||||
func (s *IntegrationTestSuite) queryBlockTxs(height uint64) [][]byte {
|
||||
queryClient := tmclient.NewServiceClient(s.createClientContext())
|
||||
queryClient := cmtclient.NewServiceClient(s.createClientContext())
|
||||
|
||||
req := &tmclient.GetBlockByHeightRequest{Height: int64(height)}
|
||||
req := &cmtclient.GetBlockByHeightRequest{Height: int64(height)}
|
||||
resp, err := queryClient.GetBlockByHeight(context.Background(), req)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return resp.GetSdkBlock().Data.Txs
|
||||
txs := resp.GetSdkBlock().Data.Txs
|
||||
|
||||
// The first transaction is the vote extension.
|
||||
s.Require().Greater(len(txs), 0)
|
||||
|
||||
return txs[1:]
|
||||
}
|
||||
|
||||
// queryTx returns information about a transaction.
|
||||
func (s *IntegrationTestSuite) queryTx(txHash string) *txtypes.GetTxResponse {
|
||||
queryClient := txtypes.NewServiceClient(s.createClientContext())
|
||||
|
||||
req := &txtypes.GetTxRequest{Hash: txHash}
|
||||
resp, err := queryClient.GetTx(context.Background(), req)
|
||||
s.Require().NoError(err)
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
// queryTxExecutionHeight returns the block height at which a transaction was executed.
|
||||
func (s *IntegrationTestSuite) queryTxExecutionHeight(txHash string) uint64 {
|
||||
txResp := s.queryTx(txHash)
|
||||
return uint64(txResp.TxResponse.Height)
|
||||
}
|
||||
|
||||
// queryValidators returns the validators of the network.
|
||||
|
||||
+36
-16
@@ -1,12 +1,14 @@
|
||||
package e2e
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"cosmossdk.io/math"
|
||||
cometcfg "github.com/cometbft/cometbft/config"
|
||||
"github.com/cometbft/cometbft/p2p"
|
||||
"github.com/cometbft/cometbft/privval"
|
||||
@@ -18,9 +20,10 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
sdktx "github.com/cosmos/cosmos-sdk/types/tx"
|
||||
txsigning "github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||
genutilstypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
)
|
||||
@@ -74,7 +77,16 @@ func (v *validator) init() error {
|
||||
genDoc.Validators = nil
|
||||
genDoc.AppState = appState
|
||||
|
||||
if err = genutil.ExportGenesisFile(genDoc, config.GenesisFile()); err != nil {
|
||||
if err := genDoc.SaveAs(config.GenesisFile()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
genAppState, err := genutilstypes.AppGenesisFromFile(config.GenesisFile())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal genesis state: %w", err)
|
||||
}
|
||||
|
||||
if err = genutil.ExportGenesisFile(genAppState, config.GenesisFile()); err != nil {
|
||||
return fmt.Errorf("failed to export app genesis state: %w", err)
|
||||
}
|
||||
|
||||
@@ -167,15 +179,15 @@ func (v *validator) createKey(name string) error {
|
||||
func (v *validator) buildCreateValidatorMsg(amount sdk.Coin) (sdk.Msg, error) {
|
||||
description := stakingtypes.NewDescription(v.moniker, "", "", "", "")
|
||||
commissionRates := stakingtypes.CommissionRates{
|
||||
Rate: sdk.MustNewDecFromStr("0.1"),
|
||||
MaxRate: sdk.MustNewDecFromStr("0.2"),
|
||||
MaxChangeRate: sdk.MustNewDecFromStr("0.01"),
|
||||
Rate: math.LegacyMustNewDecFromStr("0.1"),
|
||||
MaxRate: math.LegacyMustNewDecFromStr("0.2"),
|
||||
MaxChangeRate: math.LegacyMustNewDecFromStr("0.01"),
|
||||
}
|
||||
|
||||
// get the initial validator min self delegation
|
||||
minSelfDelegation, _ := sdk.NewIntFromString("1")
|
||||
minSelfDelegation := math.NewInt(1)
|
||||
|
||||
valPubKey, err := cryptocodec.FromTmPubKeyInterface(v.consensusKey.PubKey)
|
||||
valPubKey, err := cryptocodec.FromCmtPubKeyInterface(v.consensusKey.PubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -205,10 +217,16 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
|
||||
txBuilder.SetFeeAmount(sdk.NewCoins())
|
||||
txBuilder.SetGasLimit(200_000)
|
||||
|
||||
pubKey, err := v.keyInfo.GetPubKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
signerData := authsigning.SignerData{
|
||||
ChainID: v.chain.id,
|
||||
AccountNumber: 0,
|
||||
Sequence: 0,
|
||||
PubKey: pubKey,
|
||||
}
|
||||
|
||||
// For SIGN_MODE_DIRECT, calling SetSignatures calls setSignerInfos on
|
||||
@@ -219,14 +237,14 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
|
||||
// Note: This line is not needed for SIGN_MODE_LEGACY_AMINO, but putting it
|
||||
// also doesn't affect its generated sign bytes, so for code's simplicity
|
||||
// sake, we put it here.
|
||||
pubKey, err := v.keyInfo.GetPubKey()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sig := txsigning.SignatureV2{
|
||||
|
||||
sig := signing.SignatureV2{
|
||||
PubKey: pubKey,
|
||||
Data: &txsigning.SingleSignatureData{
|
||||
SignMode: txsigning.SignMode_SIGN_MODE_DIRECT,
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
|
||||
Signature: nil,
|
||||
},
|
||||
Sequence: 0,
|
||||
@@ -236,8 +254,10 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bytesToSign, err := encodingConfig.TxConfig.SignModeHandler().GetSignBytes(
|
||||
txsigning.SignMode_SIGN_MODE_DIRECT,
|
||||
bytesToSign, err := authsigning.GetSignBytesAdapter(
|
||||
context.Background(),
|
||||
encodingConfig.TxConfig.SignModeHandler(),
|
||||
signing.SignMode_SIGN_MODE_DIRECT,
|
||||
signerData,
|
||||
txBuilder.GetTx(),
|
||||
)
|
||||
@@ -250,10 +270,10 @@ func (v *validator) signMsg(msgs ...sdk.Msg) (*sdktx.Tx, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sig = txsigning.SignatureV2{
|
||||
sig = signing.SignatureV2{
|
||||
PubKey: pubKey,
|
||||
Data: &txsigning.SingleSignatureData{
|
||||
SignMode: txsigning.SignMode_SIGN_MODE_DIRECT,
|
||||
Data: &signing.SingleSignatureData{
|
||||
SignMode: signing.SignMode_SIGN_MODE_DIRECT,
|
||||
Signature: sigBytes,
|
||||
},
|
||||
Sequence: 0,
|
||||
|
||||
Reference in New Issue
Block a user