diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a388363..b011a83 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -119,3 +119,18 @@ jobs: check-latest: true - run: make install - run: make test-solidity + + test-wasmd: + runs-on: ubuntu-latest + needs: test-build + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.23.6" + check-latest: true + - run: go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest + - run: sudo apt-get update && sudo apt-get install -y xxd + - run: make install + - run: make test-wasmd + timeout-minutes: 3 diff --git a/.gitignore b/.gitignore index ac5030c..52c0eb5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,8 @@ coverage.txt .testnet .test-localnet-params .test-localnet-evm +.test-wasmd .mainnet + +# babylon +.babylond diff --git a/Dockerfile b/Dockerfile index fac020d..4abbed9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,12 +11,22 @@ RUN set -eux; apk add --no-cache ca-certificates build-base libusb-dev linux-hea WORKDIR /code COPY . /code/ -RUN LEDGER_ENABLED=true make build +# See https://github.com/CosmWasm/wasmvm/releases +ADD https://github.com/CosmWasm/wasmvm/releases/download/v2.2.3/libwasmvm_muslc.aarch64.a /lib/libwasmvm_muslc.aarch64.a +ADD https://github.com/CosmWasm/wasmvm/releases/download/v2.2.3/libwasmvm_muslc.x86_64.a /lib/libwasmvm_muslc.x86_64.a +RUN sha256sum /lib/libwasmvm_muslc.aarch64.a | grep 6641730781bb1adc4bdf04a1e0f822b9ad4fb8ed57dcbbf575527e63b791ae41 +RUN sha256sum /lib/libwasmvm_muslc.x86_64.a | grep 32503fe35a7be202c5f7c3051497d6e4b3cd83079a61f5a0bf72a2a455b6d820 +# force it to use static lib (from above) not standard libgo_cosmwasm.so file +RUN LEDGER_ENABLED=true BUILD_TAGS=muslc LINK_STATICALLY=true make build +RUN echo "Ensuring binary is statically linked ..." \ + && (file /code/build/tacchaind | grep "statically linked") # -------------------------------------------------------- FROM alpine:3.18 +RUN apk update && apk add bash jq + COPY --from=go-builder /code/build/tacchaind /usr/bin/tacchaind WORKDIR /opt diff --git a/Makefile b/Makefile index e30a6d9..d718aaa 100644 --- a/Makefile +++ b/Makefile @@ -56,6 +56,9 @@ ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=tacchain \ ifeq ($(WITH_CLEVELDB),yes) ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb endif +ifeq ($(LINK_STATICALLY),true) + ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static" +endif ldflags += $(LDFLAGS) ldflags := $(strip $(ldflags)) @@ -92,7 +95,7 @@ clean: ### Tests ### ############################################################################### -test: test-unit test-race test-e2e test-localnet-params test-localnet-evm test-ledger test-solidity +test: test-unit test-race test-e2e test-localnet-params test-localnet-evm test-ledger test-solidity test-wasmd test-unit: @VERSION=$(VERSION) go test -mod=readonly -tags='ledger test_ledger_mock' -v $(shell go list ./... | grep -v "tests") @@ -121,6 +124,9 @@ test-ledger: test-solidity: ./tests/solidity/run-solidity-tests.sh +test-wasmd: + ./tests/wasmd/test-wasmd.sh + ############################################################################### ### Networks ### ############################################################################### diff --git a/NETWORKS.md b/NETWORKS.md index 93c7012..121b7aa 100644 --- a/NETWORKS.md +++ b/NETWORKS.md @@ -153,7 +153,7 @@ tacchaind start --chain-id tacchain_239-1 --home .mainnet ``` shell export TAC_HOME="~/.tacchain" -export VERSION="v1.0.0" +export VERSION="v1.0.1" git clone https://github.com/TacBuild/tacchain.git && cd tacchain git checkout ${VERSION} diff --git a/README.md b/README.md index 0180f96..c98ce2f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Tac Chain -`tacchaind` is a TAC EVM Node based on CosmosSDK with EVM support. +`tacchaind` is a TAC EVM Node based on CosmosSDK with EVM and WASM support. ### Quickstart @@ -40,4 +40,5 @@ Check our [tool](./contrib/tac-address-converter/) for converting between EVM <> - [Cosmos SDK docs](https://docs.cosmos.network) - [CosmosEVM docs](https://evm.cosmos.network/) +- [CosmWasm docs](https://docs.cosmwasm.com/) diff --git a/app/ante.go b/app/ante.go index 19494c3..82873fd 100644 --- a/app/ante.go +++ b/app/ante.go @@ -19,10 +19,13 @@ import ( evmante "github.com/cosmos/evm/ante/evm" evmanteinterfaces "github.com/cosmos/evm/ante/interfaces" evmtypes "github.com/cosmos/evm/x/vm/types" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) // HandlerOptions extend the SDK's AnteHandler options by requiring the IBC -// channel keeper and Ethermint keeper. +// channel keeper, CosmWasm keeper and cosmosevm keeper. type HandlerOptions struct { authante.HandlerOptions @@ -37,6 +40,10 @@ type HandlerOptions struct { FeeMarketKeeper evmanteinterfaces.FeeMarketKeeper EvmKeeper evmanteinterfaces.EVMKeeper MaxTxGasWanted uint64 + + // CosmWasm + WasmConfig *wasmtypes.NodeConfig + WasmKeeper *wasmkeeper.Keeper } // NewAnteHandler returns an ante handler responsible for attempting to route an @@ -62,6 +69,15 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { if options.EvmKeeper == nil { return nil, errors.New("evm keeper is required for ante builder") } + if options.TXCounterStoreService == nil { + return nil, errors.New("wasm store service is required for ante builder") + } + if options.WasmConfig == nil { + return nil, errors.New("wasm config is required for ante builder") + } + if options.WasmKeeper == nil { + return nil, errors.New("wasm keeper is required for ante builder") + } return func( ctx sdk.Context, tx sdk.Tx, sim bool, @@ -122,6 +138,10 @@ func newCosmosAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { sdk.MsgTypeURL(&sdkvesting.MsgCreateVestingAccount{}), ), authante.NewSetUpContextDecorator(), + wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit), // after setup context to enforce limits early + wasmkeeper.NewCountTXDecorator(options.TXCounterStoreService), + wasmkeeper.NewGasRegisterDecorator(options.WasmKeeper.GetGasRegister()), + wasmkeeper.NewTxContractsDecorator(), circuitante.NewCircuitBreakerDecorator(options.CircuitKeeper), authante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), authante.NewValidateBasicDecorator(), diff --git a/app/app.go b/app/app.go index 8ffd82d..09f8e0d 100644 --- a/app/app.go +++ b/app/app.go @@ -6,6 +6,7 @@ import ( "io" "maps" "os" + "path/filepath" "sort" // Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes @@ -13,8 +14,10 @@ import ( _ "github.com/ethereum/go-ethereum/eth/tracers/native" abci "github.com/cometbft/cometbft/abci/types" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/gogoproto/proto" + "github.com/cosmos/ibc-go/modules/capability" capabilitykeeper "github.com/cosmos/ibc-go/modules/capability/keeper" capabilitytypes "github.com/cosmos/ibc-go/modules/capability/types" @@ -152,6 +155,14 @@ import ( evmibctransferkeeper "github.com/cosmos/evm/x/ibc/transfer/keeper" evmvmkeeper "github.com/cosmos/evm/x/vm/keeper" evmvmtypes "github.com/cosmos/evm/x/vm/types" + + "github.com/CosmWasm/wasmd/x/wasm" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + babylonappwasm "github.com/babylonlabs-io/babylon-sdk/demo/app/wasm" + babylon "github.com/babylonlabs-io/babylon-sdk/x/babylon" + babylonkeeper "github.com/babylonlabs-io/babylon-sdk/x/babylon/keeper" + babylontypes "github.com/babylonlabs-io/babylon-sdk/x/babylon/types" ) // module account permissions @@ -167,6 +178,8 @@ var maccPerms = map[string][]string{ ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner}, ibcfeetypes.ModuleName: nil, icatypes.ModuleName: nil, + wasmtypes.ModuleName: {authtypes.Burner}, + babylontypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // Cosmos EVM modules evmvmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, evmfeemarkettypes.ModuleName: nil, @@ -216,12 +229,15 @@ type TacChainApp struct { ICAControllerKeeper icacontrollerkeeper.Keeper ICAHostKeeper icahostkeeper.Keeper TransferKeeper evmibctransferkeeper.Keeper + WasmKeeper wasmkeeper.Keeper + BabylonKeeper *babylonkeeper.Keeper ScopedIBCKeeper capabilitykeeper.ScopedKeeper ScopedICAHostKeeper capabilitykeeper.ScopedKeeper ScopedICAControllerKeeper capabilitykeeper.ScopedKeeper ScopedTransferKeeper capabilitykeeper.ScopedKeeper ScopedIBCFeeKeeper capabilitykeeper.ScopedKeeper + ScopedWasmKeeper capabilitykeeper.ScopedKeeper // the module manager ModuleManager *module.Manager @@ -248,6 +264,7 @@ func NewTacChainApp( invCheckPeriod uint, appOpts servertypes.AppOptions, evmAppOptions evmd.EVMOptionsFn, + wasmOpts []wasmkeeper.Option, baseAppOptions ...func(*baseapp.BaseApp), ) *TacChainApp { encodingConfig := evmencoding.MakeConfig() @@ -300,11 +317,13 @@ func NewTacChainApp( // non sdk store keys capabilitytypes.StoreKey, ibcexported.StoreKey, ibctransfertypes.StoreKey, ibcfeetypes.StoreKey, icahosttypes.StoreKey, icacontrollertypes.StoreKey, + wasmtypes.StoreKey, + babylontypes.StoreKey, // Cosmos EVM store keys evmvmtypes.StoreKey, evmfeemarkettypes.StoreKey, evmerc20types.StoreKey, ) - tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey, evmvmtypes.TransientKey, evmfeemarkettypes.TransientKey) + tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey, evmvmtypes.TransientKey, evmfeemarkettypes.TransientKey, babylontypes.MemStoreKey) memKeys := storetypes.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) // register streaming services @@ -353,6 +372,7 @@ func NewTacChainApp( app.ScopedICAHostKeeper = app.CapabilityKeeper.ScopeToModule(icahosttypes.SubModuleName) app.ScopedICAControllerKeeper = app.CapabilityKeeper.ScopeToModule(icacontrollertypes.SubModuleName) app.ScopedTransferKeeper = app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName) + app.ScopedWasmKeeper = app.CapabilityKeeper.ScopeToModule(wasmtypes.ModuleName) // Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating // their scoped modules in `NewApp` with `ScopeToModule` @@ -422,6 +442,16 @@ func NewTacChainApp( authAddr, ) + app.BabylonKeeper = babylonkeeper.NewKeeper( + app.appCodec, + keys[babylontypes.StoreKey], + memKeys[babylontypes.MemStoreKey], + app.BankKeeper, + app.StakingKeeper, + &app.WasmKeeper, // ensure this is a pointer as we instantiate the keeper a bit later + authAddr, + ) + app.SlashingKeeper = slashingkeeper.NewKeeper( encodingConfig.Codec, encodingConfig.Amino, @@ -630,6 +660,56 @@ func NewTacChainApp( authAddr, ) + // Override max wasm size to 1MB + // TODO: Remove this after down-sizing / splitting contracts + wasmtypes.MaxWasmSize = 1 * 1024 * 1024 + + wasmDir := filepath.Join(homePath, "wasm") + wasmConfig, err := wasm.ReadNodeConfig(appOpts) + if err != nil { + panic(fmt.Sprintf("error while reading wasm config: %s", err)) + } + + messageHandler := wasmkeeper.WithMessageHandlerDecorator(func(nested wasmkeeper.Messenger) wasmkeeper.Messenger { + return wasmkeeper.NewMessageHandlerChain( + // security layer for system integrity, should always be first in chain + babylonkeeper.NewIntegrityHandler(app.BabylonKeeper), + nested, + // append our custom message handler + babylonkeeper.NewDefaultCustomMsgHandler(app.BabylonKeeper), + ) + }) + wasmOpts = append(wasmOpts, messageHandler, + // add support for the custom queries + wasmkeeper.WithQueryHandlerDecorator(babylonkeeper.NewQueryDecorator(app.BabylonKeeper)), + ) + // Add grpc query support for the whitelisted grpc queries + wasmOpts = append(wasmOpts, babylonappwasm.RegisterGrpcQueries(bApp, encodingConfig.Codec)...) + + // The last arguments can contain custom message handlers, and custom query handlers, + // if we want to allow any custom callbacks + app.WasmKeeper = wasmkeeper.NewKeeper( + encodingConfig.Codec, + runtime.NewKVStoreService(keys[wasmtypes.StoreKey]), + app.AccountKeeper, + app.BankKeeper, + app.StakingKeeper, + distrkeeper.NewQuerier(app.DistrKeeper), + app.IBCFeeKeeper, // ISC4 Wrapper: fee IBC middleware + app.IBCKeeper.ChannelKeeper, + app.IBCKeeper.PortKeeper, + app.ScopedWasmKeeper, + app.TransferKeeper, + app.MsgServiceRouter(), + app.GRPCQueryRouter(), + wasmDir, + wasmConfig, + wasmtypes.VMConfig{}, + wasmkeeper.BuiltInCapabilities(), + authtypes.NewModuleAddress(govtypes.ModuleName).String(), + wasmOpts..., + ) + // Create Interchain Accounts Stack // SendPacket, since it is originating from the application to core IBC: // icaAuthModuleKeeper.SendTx -> icaController.SendPacket -> fee.SendPacket -> channel.SendPacket @@ -655,11 +735,18 @@ func NewTacChainApp( transferStack = evmibctransfer.NewIBCModule(app.TransferKeeper) transferStack = evmerc20.NewIBCMiddleware(app.Erc20Keeper, transferStack) + // Create fee enabled wasm ibc Stack + var wasmStack porttypes.IBCModule + wasmStack = wasm.NewIBCHandler(app.WasmKeeper, app.IBCKeeper.ChannelKeeper, app.IBCFeeKeeper) + wasmStack = ibcfee.NewIBCMiddleware(wasmStack, app.IBCFeeKeeper) + // Create static IBC router, add app routes, then set and seal it ibcRouter := porttypes.NewRouter(). AddRoute(ibctransfertypes.ModuleName, transferStack). AddRoute(icacontrollertypes.SubModuleName, icaControllerStack). - AddRoute(icahosttypes.SubModuleName, icaHostStack) + AddRoute(icahosttypes.SubModuleName, icaHostStack). + AddRoute(wasmtypes.ModuleName, wasmStack) + app.IBCKeeper.SetRouter(ibcRouter) // NOTE: we are adding all available Cosmos EVM EVM extensions. @@ -714,11 +801,15 @@ func NewTacChainApp( circuit.NewAppModule(encodingConfig.Codec, app.CircuitKeeper), // non sdk modules capability.NewAppModule(encodingConfig.Codec, *app.CapabilityKeeper, false), + wasm.NewAppModule(encodingConfig.Codec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)), + ibc.NewAppModule(app.IBCKeeper), evmibctransfer.NewAppModule(app.TransferKeeper), ibcfee.NewAppModule(app.IBCFeeKeeper), ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper), ibctm.AppModule{}, + babylon.NewAppModule(encodingConfig.Codec, app.BabylonKeeper), + // sdk crisis.NewAppModule(app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), // always be last to make sure that it checks for all invariants and not only part of them // Cosmos EVM modules @@ -785,6 +876,8 @@ func NewTacChainApp( vestingtypes.ModuleName, consensusparamtypes.ModuleName, crisistypes.ModuleName, + wasmtypes.ModuleName, + babylontypes.ModuleName, ) app.ModuleManager.SetOrderEndBlockers( @@ -817,6 +910,8 @@ func NewTacChainApp( upgradetypes.ModuleName, vestingtypes.ModuleName, consensusparamtypes.ModuleName, + wasmtypes.ModuleName, + babylontypes.ModuleName, // last to capture all chain events ) // NOTE: The genutils module must occur after staking so that pools are @@ -825,6 +920,8 @@ func NewTacChainApp( // 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. + // NOTE: wasm module should be at the end as it can call other module functionality direct or via message dispatching during + // genesis phase. For example bank transfer, auth account check, staking, ... genesisModuleOrder := []string{ capabilitytypes.ModuleName, // simd modules @@ -863,6 +960,9 @@ func NewTacChainApp( consensusparamtypes.ModuleName, // NOTE: crisis module must go at the end to check for invariants on each module crisistypes.ModuleName, + // wasm after ibc transfer + wasmtypes.ModuleName, + babylontypes.ModuleName, } app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...) app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...) @@ -916,8 +1016,21 @@ func NewTacChainApp( app.setAnteHandler( txConfig, cast.ToUint64(appOpts.Get(evmsrvflags.EVMMaxTxGasWanted)), + wasmConfig, + keys[wasmtypes.StoreKey], ) + // must be before Loading version + // requires the snapshot store to be created and registered as a BaseAppOption + // see cmd/wasmd/root.go: 206 - 214 approx + if manager := app.SnapshotManager(); manager != nil { + err := manager.RegisterExtensions( + wasmkeeper.NewWasmSnapshotter(app.CommitMultiStore(), &app.WasmKeeper), + ) + if err != nil { + panic(fmt.Errorf("failed to register snapshot extension: %s", err)) + } + } // In v0.46, the SDK introduces _postHandlers_. PostHandlers are like // antehandlers, but are run _after_ the `runMsgs` execution. They are also // defined as a chain, and have the same signature as antehandlers. @@ -950,12 +1063,18 @@ func NewTacChainApp( if err := app.LoadLatestVersion(); err != nil { panic(fmt.Errorf("error loading last version: %w", err)) } + + // Initialize pinned codes in wasmvm as they are not persisted there + ctx := app.BaseApp.NewUncachedContext(true, cmtproto.Header{}) + if err := app.WasmKeeper.InitializePinnedCodes(ctx); err != nil { + panic(fmt.Sprintf("failed initialize pinned codes %s", err)) + } } return app } -func (app *TacChainApp) setAnteHandler(txConfig client.TxConfig, maxGasWanted uint64) { +func (app *TacChainApp) setAnteHandler(txConfig client.TxConfig, maxGasWanted uint64, wasmConfig wasmtypes.NodeConfig, txCounterStoreKey *storetypes.KVStoreKey) { anteHandler, err := NewAnteHandler(HandlerOptions{ HandlerOptions: authante.HandlerOptions{ BankKeeper: app.BankKeeper, @@ -965,12 +1084,15 @@ func (app *TacChainApp) setAnteHandler(txConfig client.TxConfig, maxGasWanted ui ExtensionOptionChecker: evmcosmostypes.HasDynamicFeeExtensionOption, TxFeeChecker: evmcosmosante.NewDynamicFeeChecker(app.FeeMarketKeeper), }, - AccountKeeper: app.AccountKeeper, - IBCKeeper: app.IBCKeeper, - CircuitKeeper: &app.CircuitKeeper, - EvmKeeper: app.EVMKeeper, - FeeMarketKeeper: app.FeeMarketKeeper, - MaxTxGasWanted: maxGasWanted, + AccountKeeper: app.AccountKeeper, + IBCKeeper: app.IBCKeeper, + CircuitKeeper: &app.CircuitKeeper, + EvmKeeper: app.EVMKeeper, + FeeMarketKeeper: app.FeeMarketKeeper, + MaxTxGasWanted: maxGasWanted, + WasmConfig: &wasmConfig, + WasmKeeper: &app.WasmKeeper, + TXCounterStoreService: runtime.NewKVStoreService(txCounterStoreKey), }, ) if err != nil { diff --git a/app/app_test.go b/app/app_test.go index 81dec08..db9999c 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" abci "github.com/cometbft/cometbft/abci/types" dbm "github.com/cosmos/cosmos-db" "github.com/cosmos/gogoproto/proto" @@ -62,6 +63,7 @@ func TestExportAndBlockedAddrs(t *testing.T) { 0, simtestutil.NewAppOptionsWithFlagHome(t.TempDir()), evmdcmd.NoOpEvmAppOptions, + []wasmkeeper.Option{}, ) _, err = app2.ExportAppStateAndValidators(false, []string{}, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") diff --git a/app/config.go b/app/config.go index 74c64dd..844acab 100644 --- a/app/config.go +++ b/app/config.go @@ -12,6 +12,8 @@ import ( "github.com/cosmos/evm/evmd/eips" evmvmtypes "github.com/cosmos/evm/x/vm/types" evmvmcore "github.com/ethereum/go-ethereum/core/vm" + + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) const ( @@ -108,4 +110,5 @@ func setAddressPrefixes() { config.SetBech32PrefixForAccount(Bech32PrefixAccAddr, Bech32PrefixAccPub) config.SetBech32PrefixForValidator(Bech32PrefixValAddr, Bech32PrefixValPub) config.SetBech32PrefixForConsensusNode(Bech32PrefixConsAddr, Bech32PrefixConsPub) + config.SetAddressVerifier(wasmtypes.VerifyAddressLen()) } diff --git a/app/test_helpers.go b/app/test_helpers.go index 0818994..3043412 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -3,6 +3,7 @@ package app import ( "testing" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" abci "github.com/cometbft/cometbft/abci/types" cmtjson "github.com/cometbft/cometbft/libs/json" cmttypes "github.com/cometbft/cometbft/types" @@ -24,9 +25,10 @@ import ( // SetupOptions defines arguments that are passed into `TacChainApp` constructor. type SetupOptions struct { - Logger log.Logger - DB *dbm.MemDB - AppOpts servertypes.AppOptions + Logger log.Logger + DB *dbm.MemDB + AppOpts servertypes.AppOptions + WasmOpts []wasmkeeper.Option } // NewTacChainAppWithCustomOptions initializes a new TacChainApp with custom options. @@ -56,6 +58,7 @@ func NewTacChainAppWithCustomOptions(t *testing.T, isCheckTx bool, invCheckPerio invCheckPeriod, options.AppOpts, SetupEvmConfig, + options.WasmOpts, bam.SetChainID(DefaultChainID), ) genesisState := app.DefaultGenesis() diff --git a/cmd/tacchaind/commands.go b/cmd/tacchaind/commands.go index 47d33af..80f1eb4 100644 --- a/cmd/tacchaind/commands.go +++ b/cmd/tacchaind/commands.go @@ -7,6 +7,7 @@ import ( cmtcli "github.com/cometbft/cometbft/libs/cli" dbm "github.com/cosmos/cosmos-db" + "github.com/prometheus/client_golang/prometheus" "github.com/spf13/cast" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -33,6 +34,10 @@ import ( evmclient "github.com/cosmos/evm/client" evmserver "github.com/cosmos/evm/server" evmsrvflags "github.com/cosmos/evm/server/flags" + + "github.com/CosmWasm/wasmd/x/wasm" + wasmcli "github.com/CosmWasm/wasmd/x/wasm/client/cli" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" ) func initRootCmd(appInstance *app.TacChainApp, rootCmd *cobra.Command) { @@ -57,6 +62,8 @@ func initRootCmd(appInstance *app.TacChainApp, rootCmd *cobra.Command) { addModuleInitFlags, ) + wasmcli.ExtendUnsafeResetAllCmd(rootCmd) + // add Cosmos EVM key commands rootCmd.AddCommand( evmclient.KeyCommands(app.DefaultNodeHome, true), @@ -79,6 +86,7 @@ func initRootCmd(appInstance *app.TacChainApp, rootCmd *cobra.Command) { func addModuleInitFlags(cmd *cobra.Command) { crisis.AddModuleInitFlags(cmd) + wasm.AddModuleInitFlags(cmd) } func queryCommand() *cobra.Command { @@ -138,6 +146,11 @@ func newApp( ) servertypes.Application { baseappOptions := server.DefaultBaseappOptions(appOpts) + var wasmOpts []wasmkeeper.Option + if cast.ToBool(appOpts.Get("telemetry.enabled")) { + wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer)) + } + return app.NewTacChainApp( logger, db, @@ -146,6 +159,7 @@ func newApp( cast.ToUint(appOpts.Get(server.FlagInvCheckPeriod)), appOpts, app.SetupEvmConfig, + wasmOpts, baseappOptions..., ) } @@ -186,6 +200,7 @@ func appExport( uint(1), appOpts, app.SetupEvmConfig, + []wasmkeeper.Option{}, baseapp.SetChainID(cast.ToString(appOpts.Get(flags.FlagChainID))), ) diff --git a/cmd/tacchaind/root.go b/cmd/tacchaind/root.go index 39a2d05..830ba3b 100644 --- a/cmd/tacchaind/root.go +++ b/cmd/tacchaind/root.go @@ -24,10 +24,12 @@ import ( "github.com/Asphere-xyz/tacchain/app" + evmdcmd "github.com/cosmos/evm/cmd/evmd/cmd" evmkeyring "github.com/cosmos/evm/crypto/keyring" evmserverconfig "github.com/cosmos/evm/server/config" - evmdcmd "github.com/cosmos/evm/cmd/evmd/cmd" + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" ) // NewRootCmd creates a new root command for tacchaind. It is called once in the @@ -45,6 +47,7 @@ func NewRootCmd() *cobra.Command { 0, simtestutil.NewAppOptionsWithFlagHome(temp), evmdcmd.NoOpEvmAppOptions, + []wasmkeeper.Option{}, ) encodingConfig := params.EncodingConfig{ @@ -168,6 +171,8 @@ func initAppConfig() (string, interface{}) { EVM evmserverconfig.EVMConfig JSONRPC evmserverconfig.JSONRPCConfig TLS evmserverconfig.TLSConfig + + Wasm wasmtypes.NodeConfig `mapstructure:"wasm"` } // Optionally allow the chain developer to overwrite the SDK's default @@ -191,12 +196,14 @@ func initAppConfig() (string, interface{}) { customAppConfig := CustomAppConfig{ Config: *srvCfg, + Wasm: wasmtypes.DefaultNodeConfig(), EVM: *evmserverconfig.DefaultEVMConfig(), JSONRPC: *evmserverconfig.DefaultJSONRPCConfig(), TLS: *evmserverconfig.DefaultTLSConfig(), } customAppTemplate := serverconfig.DefaultConfigTemplate + + wasmtypes.DefaultConfigTemplate() + evmserverconfig.DefaultEVMConfigTemplate return customAppTemplate, customAppConfig diff --git a/contrib/babylon/README.md b/contrib/babylon/README.md new file mode 100644 index 0000000..ec8ace3 --- /dev/null +++ b/contrib/babylon/README.md @@ -0,0 +1,9 @@ +# Tacchain Babylon Integration + +This is an example showcasing tacchain integration as a babylon consumer bsn chain and verifies bitcoin staking. + +## Quickstart + +``` shell +docker-compose up +``` \ No newline at end of file diff --git a/contrib/babylon/bitcoindsim/Dockerfile b/contrib/babylon/bitcoindsim/Dockerfile new file mode 100644 index 0000000..c83b956 --- /dev/null +++ b/contrib/babylon/bitcoindsim/Dockerfile @@ -0,0 +1,29 @@ +# Reference taken from https://www.willianantunes.com/blog/2022/04/bitcoin-node-with-regtest-mode-using-docker/ + +FROM debian:bullseye-slim + +RUN useradd --system --user-group bitcoin \ + && apt-get update -y \ + && apt-get install -y curl gnupg gosu \ + && apt-get clean \ + && apt-get install vim -y \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +ARG BITCOIN_CORE_VERSION="26.0" +ENV BITCOIN_CORE_VERSION=$BITCOIN_CORE_VERSION +ENV PATH=/opt/bitcoin-${BITCOIN_CORE_VERSION}/bin:$PATH + +RUN set -ex \ + && curl -SLO https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_CORE_VERSION}/bitcoin-${BITCOIN_CORE_VERSION}-x86_64-linux-gnu.tar.gz \ + && tar -xzf *.tar.gz -C /opt + +WORKDIR /bitcoindsim + +ENV BITCOIN_DATA=/bitcoindsim/bitcoin +ENV BITCOIN_CONF=/bitcoindsim/bitcoin/bitcoin.conf + +COPY wrapper.sh /bitcoindsim/wrapper.sh + +ENTRYPOINT ["/bitcoindsim/wrapper.sh"] +CMD [] +STOPSIGNAL SIGTERM diff --git a/contrib/babylon/bitcoindsim/wrapper.sh b/contrib/babylon/bitcoindsim/wrapper.sh new file mode 100755 index 0000000..a51ca24 --- /dev/null +++ b/contrib/babylon/bitcoindsim/wrapper.sh @@ -0,0 +1,112 @@ +#!/usr/bin/env bash +set -e + +echo "BITCOIN_NETWORK: $BITCOIN_NETWORK" +echo "BITCOIN_RPC_PORT: $BITCOIN_RPC_PORT" + +if [[ -z "$BITCOIN_NETWORK" ]]; then + BITCOIN_NETWORK="regtest" +fi + +if [[ -z "$BITCOIN_RPC_PORT" ]]; then + BITCOIN_RPC_PORT="18443" +fi + +if [[ "$BITCOIN_NETWORK" != "regtest" && "$BITCOIN_NETWORK" != "signet" ]]; then + echo "Unsupported network: $BITCOIN_NETWORK" + exit 1 +fi + +# Create bitcoin data directory and initialize bitcoin configuration file. +mkdir -p "$BITCOIN_DATA" +cat < "$BITCOIN_CONF" +# Enable ${BITCOIN_NETWORK} mode. +${BITCOIN_NETWORK}=1 + +# Accept command line and JSON-RPC commands +server=1 + +# RPC user and password. +rpcuser=$RPC_USER +rpcpassword=$RPC_PASS + +# ZMQ notification options. +# Enable publish hash block and tx sequence +zmqpubsequence=tcp://*:$ZMQ_SEQUENCE_PORT +# Enable publishing of raw block hex. +zmqpubrawblock=tcp://*:$ZMQ_RAWBLOCK_PORT +# Enable publishing of raw transaction. +zmqpubrawtx=tcp://*:$ZMQ_RAWTR_PORT + +txindex=1 +deprecatedrpc=create_bdb + +# Fallback fee +fallbackfee=0.00001 + +# Allow all IPs to access the RPC server. +[${BITCOIN_NETWORK}] +rpcbind=0.0.0.0 +rpcallowip=0.0.0.0/0 +EOF + +echo "Starting bitcoind..." +bitcoind -${BITCOIN_NETWORK} -datadir="$BITCOIN_DATA" -conf="$BITCOIN_CONF" -daemon +# Allow some time for bitcoind to start +sleep 3 + +if [[ "$BITCOIN_NETWORK" == "regtest" ]]; then + echo "Creating a wallet..." + bitcoin-cli -${BITCOIN_NETWORK} -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" createwallet "$WALLET_NAME" false false "$WALLET_PASS" false false + + echo "Creating a wallet for btcstaker..." + bitcoin-cli -${BITCOIN_NETWORK} -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" createwallet "$BTCSTAKER_WALLET_NAME" false false "$WALLET_PASS" false false + + echo "Generating 110 blocks for the first coinbases to mature..." + bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$WALLET_NAME" -generate 110 + + echo "Creating $BTCSTAKER_WALLET_ADDR_COUNT addresses for btcstaker..." + BTCSTAKER_ADDRS=() + for i in `seq 0 1 $((BTCSTAKER_WALLET_ADDR_COUNT - 1))` + do + BTCSTAKER_ADDRS+=($(bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$BTCSTAKER_WALLET_NAME" getnewaddress)) + done + + # Generate a UTXO for each btc-staker address + bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$WALLET_NAME" walletpassphrase "$WALLET_PASS" 1 + for addr in "${BTCSTAKER_ADDRS[@]}" + do + bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$WALLET_NAME" sendtoaddress "$addr" 10 + done + + # Allow some time for the wallet to catch up. + sleep 5 + + echo "Checking balance..." + bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$WALLET_NAME" getbalance + + echo "Generating a block every ${GENERATE_INTERVAL_SECS} seconds." + echo "Press [CTRL+C] to stop..." + while true + do + bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$WALLET_NAME" -generate 1 + if [[ "$GENERATE_STAKER_WALLET" == "true" ]]; then + echo "Periodically send funds to btcstaker addresses..." + bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$WALLET_NAME" walletpassphrase "$WALLET_PASS" 10 + for addr in "${BTCSTAKER_ADDRS[@]}" + do + bitcoin-cli -regtest -rpcuser="$RPC_USER" -rpcpassword="$RPC_PASS" -rpcwallet="$WALLET_NAME" sendtoaddress "$addr" 10 + done + fi + sleep "${GENERATE_INTERVAL_SECS}" + done +elif [[ "$BITCOIN_NETWORK" == "signet" ]]; then + # Check if the wallet database already exists. + if [[ -d "$BITCOIN_DATA"/signet/wallets/"$BTCSTAKER_WALLET_NAME" ]]; then + echo "Wallet already exists and removing it..." + rm -rf "$BITCOIN_DATA"/signet/wallets/"$BTCSTAKER_WALLET_NAME" + fi + # Keep the container running + echo "Bitcoind is running. Press CTRL+C to stop..." + tail -f /dev/null +fi \ No newline at end of file diff --git a/contrib/babylon/consumer-eotsd.conf b/contrib/babylon/consumer-eotsd.conf new file mode 100644 index 0000000..0d7df97 --- /dev/null +++ b/contrib/babylon/consumer-eotsd.conf @@ -0,0 +1,38 @@ +[Application Options] +; Logging level for all subsystems +LogLevel = debug + +; Type of keyring to use +KeyringBackend = test + +; the listener for RPC connections, e.g., localhost:1234 +RPCListener = 0.0.0.0:15813 + +[metrics] +; IP of the Prometheus server +Host = 127.0.0.1 + +; Port of the Prometheus server +Port = 2112 + +; The interval of Prometheus metrics updated +UpdateInterval = 1m0s + +[dbconfig] +; The directory path in which the database file should be stored. +DBPath = /home/finality-provider/.eotsd/data + +; The name of the database file. +DBFileName = eots.db + +; Prevents the database from syncing its freelist to disk, resulting in improved performance at the expense of increased startup time. +NoFreelistSync = true + +; Specifies if a Bolt based database backend should be automatically compacted on startup (if the minimum age of the database file is reached). This will require additional disk space for the compacted copy of the database but will result in an overall lower database size after the compaction. +AutoCompact = false + +; Specifies the minimum time that must have passed since a bolt database file was last compacted for the compaction to be considered again. +AutoCompactMinAge = 168h0m0s + +; Specifies the timeout value to use when opening the wallet database. +DBTimeout = 1m0s diff --git a/contrib/babylon/consumer-fpd.conf b/contrib/babylon/consumer-fpd.conf new file mode 100644 index 0000000..c38d0a0 --- /dev/null +++ b/contrib/babylon/consumer-fpd.conf @@ -0,0 +1,171 @@ +[Application Options] +; Logging level for all subsystems {trace, debug, info, warn, error, fatal} +LogLevel = debug + +; the type of the consumer chain +ChainType = wasm + +; The number of Schnorr public randomness for each commitment +NumPubRand = 1000 + +; The upper bound of the number of Schnorr public randomness for each commitment +NumPubRandMax = 1000 + +; The delay, measured in blocks, between a randomness commit submission and the randomness is BTC-timestamped +TimestampingDelayBlocks = 4 + +; The size of a batch in one submission +BatchSubmissionSize = 1000 + +; The interval between each attempt to commit public randomness +RandomnessCommitInterval = 5s + +; The interval between each attempt to submit finality signature or public randomness after a failure +SubmissionRetryInterval = 1s + +; The interval between each finality signature(s) submission +SignatureSubmissionInterval = 1s + +; The maximum number of retries to submit finality signature or public randomness +MaxSubmissionRetries = 20 + +; The address of the remote EOTS manager; Empty if the EOTS manager is running locally +EOTSManagerAddress = consumer-eotsmanager:15813 + +; the listener for RPC connections, e.g., localhost:1234 +RPCListener = 127.0.0.1:12581 + +[chainpollerconfig] +; The maximum number of Babylon blocks that can be stored in the buffer +BufferSize = 1000 + +; The interval between each polling of Babylon blocks +PollInterval = 5s + +; The size of a batch in one polling of Babylon blocks +PollSize = 100 + +; The static height from which we start polling the chain +StaticChainScanningStartHeight = 1 + +; Automatically discover the height from which to start polling the chain +AutoChainScanningMode = true + +[metrics] +; IP of the Prometheus server +Host = 127.0.0.1 + +; Port of the Prometheus server +Port = 2112 + +; The interval of Prometheus metrics updated +UpdateInterval = 1m + +[dbconfig] +; The directory path in which the database file should be stored. +DBPath = /home/finality-provider/.fpd/data + +; The name of the database file. +DBFileName = finality-provider.db + +; Prevents the database from syncing its freelist to disk, resulting in improved performance at the expense of increased startup time. +NoFreelistSync = true + +; Specifies if a Bolt based database backend should be automatically compacted on startup (if the minimum age of the database file is reached). This will require additional disk space for the compacted copy of the database but will result in an overall lower database size after the compaction. +AutoCompact = false + +; Specifies the minimum time that must have passed since a bolt database file was last compacted for the compaction to be considered again. +AutoCompactMinAge = 168h0m0s + +; Specifies the timeout value to use when opening the wallet database. +DBTimeout = 1m0s + +[babylon] +; name of the key to sign transactions with +Key = finality-provider + +; chain id of the chain to connect to +ChainID = chain-test + +; address of the rpc server to connect to +RPCAddr = http://babylondnode0:26657 + +; address of the grpc server to connect to +GRPCAddr = https://babylondnode0:9090 + +; account prefix to use for addresses +AccountPrefix = bbn + +; type of keyring to use +KeyringBackend = test + +; adjustment factor when using gas estimation +GasAdjustment = 3 + +; comma separated minimum gas prices to accept for transactions +GasPrices = 0.01ubbn + +; directory to store keys in +KeyDirectory = /home/finality-provider/.fpd + +; flag to print debug output +Debug = true + +; client timeout when doing queries +Timeout = 20s + +; block timeout when waiting for block events +BlockTimeout = 1m0s + +; default output when printint responses +OutputFormat = json + +; sign mode to use +SignModeStr = direct + +[wasm] +; name of the key to sign transactions with +Key = consumer-fp + +; chain id of the chain to connect to +ChainID = bcd-test + +; address of the rpc server to connect to +RPCAddr = http://ibcsim-bcd:26657 + +; address of the grpc server to connect to +GRPCAddr = https://ibcsim-bcd:9090 + +; account prefix to use for addresses +AccountPrefix = bbnc + +; type of keyring to use +KeyringBackend = test + +; adjustment factor when using gas estimation +GasAdjustment = 3 + +; comma separated minimum gas prices to accept for transactions +GasPrices = 0.01ustake + +; directory to store keys in +KeyDirectory = /home/finality-provider/.fpd + +; flag to print debug output +Debug = true + +; client timeout when doing queries +Timeout = 20s + +; block timeout when waiting for block events +BlockTimeout = 1m0s + +; default output when printint responses +OutputFormat = json + +; sign mode to use +SignModeStr = direct + +; TODO(euphrates): fetching this from bcd node? +BtcStakingContractAddress = "bbnc17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9jfksztgw5uh69wac2pgssg3nft" +BtcFinalityContractAddress = "bbnc1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqv7u2f2" \ No newline at end of file diff --git a/contrib/babylon/contracts/babylon_contract_v0.14.0.wasm b/contrib/babylon/contracts/babylon_contract_v0.14.0.wasm new file mode 100644 index 0000000..9213d8a Binary files /dev/null and b/contrib/babylon/contracts/babylon_contract_v0.14.0.wasm differ diff --git a/contrib/babylon/contracts/btc_finality_v0.14.0.wasm b/contrib/babylon/contracts/btc_finality_v0.14.0.wasm new file mode 100644 index 0000000..574ddb0 Binary files /dev/null and b/contrib/babylon/contracts/btc_finality_v0.14.0.wasm differ diff --git a/contrib/babylon/contracts/btc_light_client_v0.14.0.wasm b/contrib/babylon/contracts/btc_light_client_v0.14.0.wasm new file mode 100755 index 0000000..6f43336 Binary files /dev/null and b/contrib/babylon/contracts/btc_light_client_v0.14.0.wasm differ diff --git a/contrib/babylon/contracts/btc_staking_v0.14.0.wasm b/contrib/babylon/contracts/btc_staking_v0.14.0.wasm new file mode 100644 index 0000000..767ff29 Binary files /dev/null and b/contrib/babylon/contracts/btc_staking_v0.14.0.wasm differ diff --git a/contrib/babylon/docker-compose.yml b/contrib/babylon/docker-compose.yml new file mode 100644 index 0000000..d6ce5eb --- /dev/null +++ b/contrib/babylon/docker-compose.yml @@ -0,0 +1,389 @@ +services: + +# 1. Spin up local bitcoin network + bitcoindsim: + build: + context: ./bitcoindsim/ + dockerfile: ./Dockerfile + platform: linux/amd64 + networks: + localnet: + ipv4_address: 192.168.10.2 + environment: + - ZMQ_SEQUENCE_PORT=29000 + - ZMQ_RAWBLOCK_PORT=29001 + - ZMQ_RAWTR_PORT=29002 + - RPC_PORT=18443 + - RPC_USER=rpcuser + - RPC_PASS=rpcpass + - WALLET_PASS=walletpass + - WALLET_NAME=default + - BTCSTAKER_WALLET_NAME=btcstaker + - BTCSTAKER_WALLET_ADDR_COUNT=3 + - GENERATE_INTERVAL_SECS=10 + ports: + - "18443:18443" + - "29000-29002:29000-29002" + volumes: + - ./.babylond/bitcoin:/bitcoindsim/bitcoin:Z + +# 2. Spin up bitcoin indexer + electrs: + image: mempool/electrs:v3.1.0 + container_name: electrs + platform: linux/amd64 + networks: + localnet: + ipv4_address: 192.168.10.31 + depends_on: + - bitcoindsim + environment: + - ELECTRS_NETWORK=regtest + - ELECTRS_COOKIE=rpcuser:rpcpass + - ELECTRS_DAEMON_RPC_ADDR=bitcoindsim:18443 + - ELECTRS_DB_DIR=/electrs/.electrs/db + ports: + - "8080:8080" + - "3003:3003" + volumes: + - ../.babylond/electrs:/data:Z + - ../.babylond/bitcoin:/bitcoin/.bitcoin:Z + command: + [ "--cookie", "rpcuser:rpcpass", + "--network", "regtest", + "--electrum-rpc-addr", "0.0.0.0:8080", + "--http-addr", "0.0.0.0:3003", + "--db-dir", "/electrs/.electrs/db/", + "--daemon-rpc-addr", "bitcoindsim:18443", + "--daemon-dir", "/bitcoin/.bitcoin", + "-v", + "--address-search", + "--cors", "*", + "--timestamp" + ] + +# 3. Spin up local babylon network + babylond: + build: + context: https://github.com/babylonlabs-io/babylon.git#ec3dc80bff2c15e4c44525b3e91d963f53bb617d + dockerfile: contrib/images/babylond/Dockerfile + volumes: + - "./.babylond:/data" + - "./init-babylond.sh:/init-babylond.sh" + command: > + bash -c "/init-babylond.sh && babylond start --home /data/node0/babylond" + cap_add: + - SYS_PTRACE + security_opt: + - seccomp:unconfined + environment: + - BABYLON_BLS_PASSWORD=password + - HOMEDIR=/data/node0/babylond + ports: + - "26656-26657:26656-26657" + - "1317:1317" + - "9090:9090" + - "2345:2345" + networks: + localnet: + ipv4_address: 192.168.10.3 + +# 4. Fund all service accounts on babylon network (ibc relayer, finality provider, etc.) + babylond-fund-accounts: + build: + context: https://github.com/babylonlabs-io/babylon.git#ec3dc80bff2c15e4c44525b3e91d963f53bb617d + dockerfile: contrib/images/babylond/Dockerfile + volumes: + - "./.babylond/node0/babylond:/data" + - "./fund-accounts.sh:/fund-accounts.sh" + environment: + - BINARY=babylond + - HOMEDIR=/data + - SENDER_KEY=test-spending-key + - CHAIN_ID=babylon-localnet + - RPC_URL=http://babylond:26657 + - AMOUNT=100000000000 + - GAS_PRICES=1 + - DENOM=ubbn + - RELAYER_ADDRESS=bbn1mjyd6ksf0ay5j5ta3x7hqeptxs6j3cr9lawv3d + - FPD_ADDRESS=bbn1jswmc6x22vlgs507n2wuqmparcqun67v0mg93p + - EOTSMANAGER_ADDRESS=bbn1fezaz37eqxxgg5rzm3xg5u53qahp0q6ae55ktt + command: > + bash -c "/fund-accounts.sh" + networks: + localnet: + ipv4_address: 192.168.10.4 + depends_on: + - babylond + +# 5. Spin up vigilante services on babylon network + vigilante-reporter: + build: + context: https://github.com/babylonlabs-io/vigilante.git#v0.23.7 + command: > + vigilante reporter --config /home/vigilante/vigilante.yml 2>&1 | tee /home/vigilante/config/reporter.log + networks: + localnet: + ipv4_address: 192.168.10.5 + volumes: + - ./.babylond/vigilante:/home/vigilante/config + - ./vigilante.yml:/home/vigilante/vigilante.yml + depends_on: + - bitcoindsim + - babylond + restart: unless-stopped + + vigilante-submitter: + build: + context: https://github.com/babylonlabs-io/vigilante.git#v0.23.7 + command: > + vigilante submitter --config /home/vigilante/vigilante.yml 2>&1 | tee /home/vigilante/config/submitter.log + networks: + localnet: + ipv4_address: 192.168.10.6 + volumes: + - ./.babylond/vigilante:/home/vigilante/config + - ./vigilante.yml:/home/vigilante/vigilante.yml + depends_on: + - bitcoindsim + - babylond + restart: unless-stopped + +# TODO: fix 'error: unknown field "timeout_timestamp" in tx.TxBody: tx parse error' in vigilante-monitor, also appears in babylon-edge-deployment example + vigilante-monitor: + build: + context: https://github.com/babylonlabs-io/vigilante.git#v0.23.7 + command: > + vigilante monitor --config /home/vigilante/vigilante.yml --genesis /home/vigilante/genesis.json 2>&1 | tee /home/vigilante/config/monitor.log + networks: + localnet: + ipv4_address: 192.168.10.7 + volumes: + - ./.babylond/vigilante:/home/vigilante/config + - ./vigilante.yml:/home/vigilante/vigilante.yml + - ./.babylond/node0/babylond/config/genesis.json:/home/vigilante/genesis.json + depends_on: + - bitcoindsim + - babylond + restart: unless-stopped + + vigilante-bstracker: + build: + context: https://github.com/babylonlabs-io/vigilante.git#v0.23.7 + command: > + vigilante bstracker --config /home/vigilante/vigilante.yml 2>&1 | tee /home/vigilante/config/submitter.log + networks: + localnet: + ipv4_address: 192.168.10.8 + volumes: + - ./.babylond/vigilante:/home/vigilante/config + - ./vigilante.yml:/home/vigilante/vigilante.yml + depends_on: + - bitcoindsim + - babylond + restart: unless-stopped + +# TODO: 5. Spin up covenant services on babylon network + +# 6. Spin up finality provider services on babylon network + eotsmanager: + build: + context: https://github.com/babylonlabs-io/finality-provider.git#951d696f9bf7ad2a55631907983a92eb42cbb1c6 + command: bash -c "/home/finality-provider/init-eotsmanager.sh && eotsd start" + networks: + localnet: + ipv4_address: 192.168.10.9 + ports: + - "15825:15813" + volumes: + - ./.babylond/eotsmanager:/home/finality-provider/.eotsd + - ./eotsd.conf:/home/finality-provider/.eotsd/eotsd.conf + - ./init-eotsmanager.sh:/home/finality-provider/init-eotsmanager.sh + depends_on: + - babylond + restart: unless-stopped + + finality-provider: + build: + context: https://github.com/babylonlabs-io/finality-provider.git#951d696f9bf7ad2a55631907983a92eb42cbb1c6 + command: fpd start + networks: + localnet: + ipv4_address: 192.168.10.10 + ports: + - "15822:15812" + volumes: + - ./.babylond/finality-provider:/home/finality-provider/.fpd + - ./fpd.conf:/home/finality-provider/.fpd/fpd.conf + depends_on: + - babylond + restart: unless-stopped + +# 6. Spin up a local tacchain network as a BSN consumer network + tacchaind: + build: + context: ../.. + dockerfile: ./Dockerfile + ports: + - "27656-27657:27656-27657" + - "1417:1417" + - "9190:9190" + volumes: + - ./.babylond/tacchaind:/home/tacchaind/.tacchaind + - ./init-tacchaind.sh:/home/init-tacchaind.sh + environment: + HOMEDIR: /home/tacchaind/.tacchaind + command: > + bash -c "/home/init-tacchaind.sh && tacchaind start --home /home/tacchaind/.tacchaind --chain-id tacchain_2391-1" + cap_add: + - SYS_PTRACE + security_opt: + - seccomp:unconfined + networks: + localnet: + ipv4_address: 192.168.10.11 + restart: unless-stopped + +# 7. Initialize babylon contracts on tacchain network + tacchaind-init-babylon-contracts: + build: + context: ../.. + dockerfile: ./Dockerfile + volumes: + - ./.babylond/tacchaind:/home/tacchaind/.tacchaind + - ./contracts:/home/tacchaind/contracts + - ./init-contracts.sh:/home/tacchaind/init-contracts.sh + environment: + HOMEDIR: /home/tacchaind/.tacchaind + command: > + bash -c "/home/tacchaind/init-contracts.sh" + networks: + localnet: + ipv4_address: 192.168.10.12 + depends_on: + - tacchaind + +# 8. Fund all service accounts on tacchain network (ibc relayer, finality provider, etc.) + tacchaind-fund-accounts: + build: + context: https://github.com/babylonlabs-io/babylon.git#ec3dc80bff2c15e4c44525b3e91d963f53bb617d + dockerfile: contrib/images/babylond/Dockerfile + volumes: + - ./.babylond/tacchaind:/home/tacchaind/.tacchaind + - "./fund-accounts.sh:/fund-accounts.sh" + command: > + bash -c "/fund-accounts.sh" + networks: + localnet: + ipv4_address: 192.168.10.13 + depends_on: + - tacchaind-init-babylon-contracts + +# TODO: 9. Spin up finality provider services on tacchain network + +# 10. Spin up ibc relayer + hermes-ibc-relayer: + image: informalsystems/hermes:1.13.1 + restart: unless-stopped + volumes: + - ./.babylond/hermes:/home/hermes + - ./hermes-ibc-relayer/mnemonic.txt:/home/hermes-ibc-relayer/mnemonic.txt + - ./hermes-ibc-relayer/start.sh:/home/hermes-ibc-relayer/start.sh + - ./hermes-ibc-relayer/config.toml:/home/hermes/.hermes/config.toml + entrypoint: /home/hermes-ibc-relayer/start.sh + networks: + localnet: + ipv4_address: 192.168.10.14 + ports: + - "3000:3000" + - "3001:3001" + depends_on: + - tacchaind-fund-accounts + - babylond-fund-accounts + +# TODO: 11. Register tacchain as a consumer chain on babylon network + +# TODO: 12. Spin up btcstaker +# TODO: 13. + + # btc-staker: + # container_name: btc-staker + # image: babylonlabs-io/btc-staker + # networks: + # localnet: + # ipv4_address: 192.168.10.11 + # environment: + # - BTCSTAKER_USERNAME=rpcuser + # - BTCSTAKER_PASSWORD=rpcpass + # volumes: + # - ../.babylond/btc-staker:/home/btcstaker/.stakerd + # ports: + # - "15912:15812" + # depends_on: + # - bitcoindsim + # - babylondnode0 + # restart: unless-stopped + + + # consumer-fp: + # container_name: consumer-fp + # image: babylonlabs-io/finality-provider + # command: fpd start + # networks: + # localnet: + # ipv4_address: 192.168.10.13 + # volumes: + # - ../.babylond/consumer-fp:/home/finality-provider/.fpd + # depends_on: + # - babylondnode0 + # - consumer-eotsmanager + # - ibcsim-bcd + # restart: unless-stopped + + # consumer-eotsmanager: + # container_name: consumer-eotsmanager + # image: babylonlabs-io/finality-provider + # command: eotsd start + # networks: + # localnet: + # ipv4_address: 192.168.10.15 + # volumes: + # - ../.babylond/consumer-eotsmanager:/home/finality-provider/.eotsd + # depends_on: + # - babylondnode0 + # restart: unless-stopped + + # covenant-signer: + # container_name: covenant-signer + # image: babylonlabs-io/covenant-signer + # command: covenant-signer start + # networks: + # localnet: + # ipv4_address: 192.168.10.16 + # volumes: + # - ../.babylond/covenant-signer:/home/covenant-signer/.signer + # depends_on: + # - babylondnode0 + # restart: unless-stopped + + # covenant-emulator: + # container_name: covenant-emulator + # image: babylonlabs-io/covenant-emulator + # command: covd start + # networks: + # localnet: + # ipv4_address: 192.168.10.17 + # volumes: + # - ../.babylond/covenant-emulator:/home/covenant-emulator/.covd + # depends_on: + # - babylondnode0 + # - covenant-signer + # restart: unless-stopped + +networks: + localnet: + driver: bridge + ipam: + driver: default + config: + - subnet: 192.168.10.0/25 diff --git a/contrib/babylon/eotsd.conf b/contrib/babylon/eotsd.conf new file mode 100644 index 0000000..0d7df97 --- /dev/null +++ b/contrib/babylon/eotsd.conf @@ -0,0 +1,38 @@ +[Application Options] +; Logging level for all subsystems +LogLevel = debug + +; Type of keyring to use +KeyringBackend = test + +; the listener for RPC connections, e.g., localhost:1234 +RPCListener = 0.0.0.0:15813 + +[metrics] +; IP of the Prometheus server +Host = 127.0.0.1 + +; Port of the Prometheus server +Port = 2112 + +; The interval of Prometheus metrics updated +UpdateInterval = 1m0s + +[dbconfig] +; The directory path in which the database file should be stored. +DBPath = /home/finality-provider/.eotsd/data + +; The name of the database file. +DBFileName = eots.db + +; Prevents the database from syncing its freelist to disk, resulting in improved performance at the expense of increased startup time. +NoFreelistSync = true + +; Specifies if a Bolt based database backend should be automatically compacted on startup (if the minimum age of the database file is reached). This will require additional disk space for the compacted copy of the database but will result in an overall lower database size after the compaction. +AutoCompact = false + +; Specifies the minimum time that must have passed since a bolt database file was last compacted for the compaction to be considered again. +AutoCompactMinAge = 168h0m0s + +; Specifies the timeout value to use when opening the wallet database. +DBTimeout = 1m0s diff --git a/contrib/babylon/fpd.conf b/contrib/babylon/fpd.conf new file mode 100644 index 0000000..aa687c4 --- /dev/null +++ b/contrib/babylon/fpd.conf @@ -0,0 +1,123 @@ +[Application Options] +; Logging level for all subsystems {trace, debug, info, warn, error, fatal} +LogLevel = debug + +; the type of the consumer chain +ChainType = babylon + +; The number of Schnorr public randomness for each commitment +NumPubRand = 1000 + +; The upper bound of the number of Schnorr public randomness for each commitment +NumPubRandMax = 1000 + +; The delay, measured in blocks, between a randomness commit submission and the randomness is BTC-timestamped +TimestampingDelayBlocks = 4 + +; The size of a batch in one submission +BatchSubmissionSize = 1000 + +; The interval between each attempt to commit public randomnessBatchSubmissionSize +RandomnessCommitInterval = 5s + +; The interval between each attempt to submit finality signature or public randomness after a failure +SubmissionRetryInterval = 1s + +; The interval between each finality signature(s) submission +SignatureSubmissionInterval = 1s + +; The maximum number of retries to submit finality signature or public randomness +MaxSubmissionRetries = 20 + +; The address of the remote EOTS manager; Empty if the EOTS manager is running locally +EOTSManagerAddress = eotsmanager:15813 + +; the listener for RPC connections, e.g., localhost:1234 +RPCListener = 127.0.0.1:12581 + +[chainpollerconfig] +; The maximum number of Babylon blocks that can be stored in the buffer +BufferSize = 1000 + +; The interval between each polling of Babylon blocks +PollInterval = 5s + +; The size of a batch in one polling of Babylon blocks +PollSize = 100 + +; The static height from which we start polling the chain +StaticChainScanningStartHeight = 1 + +; Automatically discover the height from which to start polling the chain +AutoChainScanningMode = true + +[metrics] +; IP of the Prometheus server +Host = 127.0.0.1 + +; Port of the Prometheus server +Port = 2112 + +; The interval of Prometheus metrics updated +UpdateInterval = 1m + +[dbconfig] +; The directory path in which the database file should be stored. +DBPath = /home/finality-provider/.fpd/data + +; The name of the database file. +DBFileName = finality-provider.db + +; Prevents the database from syncing its freelist to disk, resulting in improved performance at the expense of increased startup time. +NoFreelistSync = true + +; Specifies if a Bolt based database backend should be automatically compacted on startup (if the minimum age of the database file is reached). This will require additional disk space for the compacted copy of the database but will result in an overall lower database size after the compaction. +AutoCompact = false + +; Specifies the minimum time that must have passed since a bolt database file was last compacted for the compaction to be considered again. +AutoCompactMinAge = 168h0m0s + +; Specifies the timeout value to use when opening the wallet database. +DBTimeout = 1m0s + +[babylon] +; name of the key to sign transactions with +Key = finality-provider + +; chain id of the chain to connect to +ChainID = chain-test +; address of the rpc server to connect to +RPCAddr = http://babylond:26657 + +; address of the grpc server to connect to +GRPCAddr = https://babylond:9090 + +; account prefix to use for addresses +AccountPrefix = bbn + +; type of keyring to use +KeyringBackend = test + +; adjustment factor when using gas estimation +GasAdjustment = 3 + +; comma separated minimum gas prices to accept for transactions +GasPrices = 0.01ubbn + +; directory to store keys in +KeyDirectory = /home/finality-provider/.fpd + +; flag to print debug output +Debug = true + +; client timeout when doing queries +Timeout = 20s + +; block timeout when waiting for block events +BlockTimeout = 1m0s + +; default output when printint responses +OutputFormat = json + +; sign mode to use +SignModeStr = direct diff --git a/contrib/babylon/fund-accounts.sh b/contrib/babylon/fund-accounts.sh new file mode 100755 index 0000000..724f045 --- /dev/null +++ b/contrib/babylon/fund-accounts.sh @@ -0,0 +1,66 @@ +#!/bin/bash -e + +BINARY=${BINARY:-$(which tacchaind)} +HOMEDIR=${HOMEDIR:-/home/tacchaind/.tacchaind} +SENDER_KEY=${SENDER_KEY:-validator} +CHAIN_ID=${CHAIN_ID:-tacchain_2391-1} +RPC_URL=${RPC_URL:-http://tacchaind:27657} +AMOUNT=${AMOUNT:-200000000000000000000000} +GAS_PRICES=${GAS_PRICES:-400000000000} +DENOM=${DENOM:-utac} +RELAYER_ADDRESS=${RELAYER_ADDRESS:-tac1rt62vnvm008pay0g4rj58m5umq2jzzyyhvgvgz} +FPD_ADDRESS=${FPD_ADDRESS:-tac1ng3kqnv7rjcf7cv2sesqyz6fln8gne4x95c5ju} +EOTSMANAGER_ADDRESS=${EOTSMANAGER_ADDRESS:-tac1vwkhvx42xjwktp6khs72ehrnawjyyz6v53ml5u} + +# establish connection with the network +echo "Establishing connection with the network..." +timeout=120 +elapsed=0 +interval=2 +while ! $BINARY query block --type=height 3 --node $RPC_URL > /dev/null 2>&1; do + sleep $interval + elapsed=$((elapsed + interval)) + if [ $elapsed -ge $timeout ]; then + echo "Failed to establish connection with the network. Timeout waiting for block height 3" + exit 1 + fi +done +echo "Connection established successfully." + +$BINARY keys list --keyring-backend test --home $HOMEDIR + +# fund IBC Relayer +echo "Funding IBC Relayer address $RELAYER_ADDRESS with $AMOUNT $DENOM" +$BINARY tx bank send $SENDER_KEY $RELAYER_ADDRESS ${AMOUNT}${DENOM} --keyring-backend test --home $HOMEDIR --node $RPC_URL --chain-id $CHAIN_ID --gas-prices ${GAS_PRICES}${DENOM} --yes +sleep 5 + +BALANCE=$($BINARY q bank balances "$RELAYER_ADDRESS" -o json --node $RPC_URL | jq -r ".balances[] | select(.denom==\"$DENOM\") | .amount") +echo "IBC Relayer Balance: $BALANCE $DENOM" +if [[ -z "$BALANCE" || "$BALANCE" -lt $AMOUNT ]]; then + echo "Error: IBC Relayer Balance is less than ${AMOUNT}${DENOM}" + exit 1 +fi + +# fund Finality Provider +echo "Funding Finality Provider address $FPD_ADDRESS with $AMOUNT $DENOM" +$BINARY tx bank send $SENDER_KEY $FPD_ADDRESS ${AMOUNT}${DENOM} --keyring-backend test --home $HOMEDIR --node $RPC_URL --chain-id $CHAIN_ID --gas-prices ${GAS_PRICES}${DENOM} --yes +sleep 5 + +BALANCE=$($BINARY q bank balances "$FPD_ADDRESS" -o json --node $RPC_URL | jq -r ".balances[] | select(.denom==\"$DENOM\") | .amount") +echo "Finality Provider Balance: $BALANCE $DENOM" +if [[ -z "$BALANCE" || "$BALANCE" -lt $AMOUNT ]]; then + echo "Error: Finality Provider Balance is less than ${AMOUNT}${DENOM}" + exit 1 +fi + +# fund Eotsmanager +echo "Funding Eotsmanager address $EOTSMANAGER_ADDRESS with $AMOUNT $DENOM" +$BINARY tx bank send $SENDER_KEY $EOTSMANAGER_ADDRESS ${AMOUNT}${DENOM} --keyring-backend test --home $HOMEDIR --node $RPC_URL --chain-id $CHAIN_ID --gas-prices ${GAS_PRICES}${DENOM} --yes +sleep 5 + +BALANCE=$($BINARY q bank balances "$EOTSMANAGER_ADDRESS" -o json --node $RPC_URL | jq -r ".balances[] | select(.denom==\"$DENOM\") | .amount") +echo "Eotsmanager Balance: $BALANCE $DENOM" +if [[ -z "$BALANCE" || "$BALANCE" -lt $AMOUNT ]]; then + echo "Error: Eotsmanager Balance is less than ${AMOUNT}${DENOM}" + exit 1 +fi \ No newline at end of file diff --git a/contrib/babylon/hermes-ibc-relayer/config.toml b/contrib/babylon/hermes-ibc-relayer/config.toml new file mode 100644 index 0000000..d5a1383 --- /dev/null +++ b/contrib/babylon/hermes-ibc-relayer/config.toml @@ -0,0 +1,164 @@ +[global] +log_level = "info" + +[mode.clients] +enabled = true +refresh = true +misbehaviour = true + +[mode.connections] +enabled = false + +[mode.channels] +enabled = false + +[mode.packets] +enabled = true +clear_interval = 100 +clear_on_start = true +tx_confirmation = false +auto_register_counterparty_payee = false +clear_limit = 50 + +[mode.packets.ics20_max_memo_size] +enabled = true +size = 32768 + +[mode.packets.ics20_max_receiver_size] +enabled = true +size = 2048 + +[rest] +enabled = false +host = "0.0.0.0" +port = 3000 + +[telemetry] +enabled = false +host = "0.0.0.0" +port = 3001 + +[telemetry.buckets.latency_submitted] +start = 500 +end = 20000 +buckets = 10 + +[telemetry.buckets.latency_confirmed] +start = 1000 +end = 30000 +buckets = 10 + +[[chains]] +type = "CosmosSdk" +id = "babylon-localnet" +rpc_addr = "http://babylond:26657" +grpc_addr = "http://babylond:9090" +rpc_timeout = "10s" +trusted_node = false +account_prefix = "bbn" +key_name = "testkey" +key_store_type = "Test" +store_prefix = "ibc" +default_gas = 100000 +max_gas = 400000 +gas_multiplier = 1.1 +max_msg_num = 30 +max_tx_size = 180000 +max_grpc_decoding_size = 33554432 +query_packets_chunk_size = 50 +clock_drift = "5s" +max_block_time = "30s" +client_refresh_rate = "1/3" +ccv_consumer_chain = false +memo_prefix = "" +sequential_batch_tx = false +allow_ccq = true + +[chains.event_source] +mode = "pull" +interval = "500ms" +max_retries = 4 + +[chains.trust_threshold] +numerator = 2 +denominator = 3 + +[chains.gas_price] +price = 2 +denom = "ubbn" + +[chains.packet_filter] +policy = "allow" +list = [["transfer", "channel-0"]] + +[chains.packet_filter.min_fees] + +[chains.dynamic_gas_price] +enabled = false +multiplier = 1.1 +max = 0.6 + +[chains.address_type] +derivation = "cosmos" + +[chains.excluded_sequences] + +[[chains]] +type = "CosmosSdk" +id = "tacchain_2391-1" +rpc_addr = "http://tacchaind:27657" +grpc_addr = "http://tacchaind:9190" +rpc_timeout = "10s" +trusted_node = false +account_prefix = "tac" +key_name = "testkey" +key_store_type = "Test" +store_prefix = "ibc" +default_gas = 100000 +max_gas = 400000 +gas_multiplier = 1.1 +max_msg_num = 30 +max_tx_size = 180000 +max_grpc_decoding_size = 33554432 +query_packets_chunk_size = 50 +clock_drift = "5s" +max_block_time = "30s" +client_refresh_rate = "1/3" +ccv_consumer_chain = false +memo_prefix = "" +sequential_batch_tx = false +allow_ccq = true + +[chains.event_source] +mode = "pull" +interval = "500ms" +max_retries = 4 + +[chains.trust_threshold] +numerator = 2 +denominator = 3 + +[chains.gas_price] +price = 25000000000 +denom = "utac" + +[chains.packet_filter] +policy = "allow" +list = [["transfer", "channel-0"]] + +[chains.packet_filter.min_fees] + +[chains.dynamic_gas_price] +enabled = false +multiplier = 1.1 +max = 0.6 + +[chains.address_type] +derivation = "ethermint" +proto_type = { pk_type = '/cosmos.evm.crypto.v1.ethsecp256k1.PubKey' } + +[chains.excluded_sequences] + +[tracing_server] +enabled = false +port = 5555 diff --git a/contrib/babylon/hermes-ibc-relayer/mnemonic.txt b/contrib/babylon/hermes-ibc-relayer/mnemonic.txt new file mode 100644 index 0000000..aff9ced --- /dev/null +++ b/contrib/babylon/hermes-ibc-relayer/mnemonic.txt @@ -0,0 +1 @@ +cinnamon legend sword giant master simple visit action level ancient day rubber pigeon filter garment hockey stay water crawl omit airport venture toilet oppose \ No newline at end of file diff --git a/contrib/babylon/hermes-ibc-relayer/start.sh b/contrib/babylon/hermes-ibc-relayer/start.sh new file mode 100755 index 0000000..a3fd99b --- /dev/null +++ b/contrib/babylon/hermes-ibc-relayer/start.sh @@ -0,0 +1,13 @@ +#!/bin/sh -e + +if ! hermes keys list --chain babylon-localnet | grep -q 'testkey'; then + hermes keys add --chain babylon-localnet --mnemonic-file "/home/hermes-ibc-relayer/mnemonic.txt" --hd-path "m/44'/60'/0'/0/0" +fi + +if ! hermes keys list --chain tacchain_2391-1 | grep -q 'testkey'; then + hermes keys add --chain tacchain_2391-1 --mnemonic-file "/home/hermes-ibc-relayer/mnemonic.txt" --hd-path "m/44'/60'/0'/0/0" +fi + +echo y | hermes create channel --a-chain babylon-localnet --b-chain tacchain_2391-1 --a-port transfer --b-port transfer --new-client-connection +hermes start + diff --git a/contrib/babylon/init-babylond.sh b/contrib/babylon/init-babylond.sh new file mode 100755 index 0000000..90d6349 --- /dev/null +++ b/contrib/babylon/init-babylond.sh @@ -0,0 +1,27 @@ +#!/bin/bash -e + +HOMEDIR=${HOMEDIR:-/data/node0/babylond} +IP_ADDRESS=${IP_ADDRESS:-192.168.10.2} +CHAIN_ID=${CHAIN_ID:-babylon-localnet} + +babylond testnet \ + --v 1 \ + -o /data \ + --starting-ip-address $IP_ADDRESS \ + --keyring-backend=test \ + --chain-id $CHAIN_ID \ + --epoch-interval 10 \ + --btc-finalization-timeout 2 \ + --btc-confirmation-depth 1 \ + --minimum-gas-prices 1ubbn \ + --btc-base-header 0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f2002000000 \ + --btc-network regtest \ + --additional-sender-account \ + --slashing-pk-script "76a914010101010101010101010101010101010101010188ac" \ + --slashing-rate 0.1 \ + --min-staking-time-blocks 10 \ + --min-commission-rate 0.05 \ + --covenant-quorum 1 \ + --activation-height 39 \ + --unbonding-time 5 \ + --covenant-pks 2d4ccbe538f846a750d82a77cd742895e51afcf23d86d05004a356b783902748 \ No newline at end of file diff --git a/contrib/babylon/init-contracts.sh b/contrib/babylon/init-contracts.sh new file mode 100755 index 0000000..47e32ef --- /dev/null +++ b/contrib/babylon/init-contracts.sh @@ -0,0 +1,124 @@ +#!/bin/bash -e + +# environment variables +TACCHAIND=${TACCHAIND:-$(which tacchaind)} +HOMEDIR=${HOMEDIR:-$HOME/.tacchaind} +OWNER_KEY=${OWNER_KEY:-validator} +KEYRING_BACKEND=${KEYRING_BACKEND:-test} +RPC_URL=${RPC_URL:-http://tacchaind:27657} +CHAIN_ID=${CHAIN_ID:-tacchain_2391-1} + +BABYLON_CONTRACT_FILE=${BABYLON_CONTRACT_FILE:-"$(dirname "$0")/contracts/babylon_contract_v0.14.0.wasm"} +BTC_LIGHT_CLIENT_CONTRACT_FILE=${BTC_LIGHT_CLIENT_CONTRACT_FILE:-"$(dirname "$0")/contracts/btc_light_client_v0.14.0.wasm"} +BTC_STAKING_CONTRACT_FILE=${BTC_STAKING_CONTRACT_FILE:-"$(dirname "$0")/contracts/btc_staking_v0.14.0.wasm"} +BTC_FINALITY_CONTRACT_FILE=${BTC_FINALITY_CONTRACT_FILE:-"$(dirname "$0")/contracts/btc_finality_v0.14.0.wasm"} + +# establish connection with the network +echo "Establishing connection with the network..." +timeout=120 +elapsed=0 +interval=2 +while ! $TACCHAIND query block --type=height 3 --node $RPC_URL > /dev/null 2>&1; do + sleep $interval + elapsed=$((elapsed + interval)) + if [ $elapsed -ge $timeout ]; then + echo "Failed to establish connection with the network. Timeout waiting for block height 3" + exit 1 + fi +done +echo "Connection established successfully." + +$TACCHAIND config set client chain-id $CHAIN_ID + +# check if already initialized +DEFAULT_PARAMS='{"babylon_contract_code_id":"0","btc_light_client_contract_code_id":"0","btc_staking_contract_code_id":"0","btc_finality_contract_code_id":"0","babylon_contract_address":"","btc_light_client_contract_address":"","btc_staking_contract_address":"","btc_finality_contract_address":"","max_gas_begin_blocker":500000}' +CURRENT_PARAMS=$($TACCHAIND q babylon params --node $RPC_URL --output json) +if [ "$CURRENT_PARAMS" != "$DEFAULT_PARAMS" ]; then + echo "Babylon Contracts already initialized. Skipping babylon contract init." + exit 0 +fi + +# upload babylon contract +echo "Uploading babylon contract code $BABYLON_CONTRACT_FILE..." +TX_HASH=$($TACCHAIND tx wasm store "$BABYLON_CONTRACT_FILE" --from $OWNER_KEY --keyring-backend $KEYRING_BACKEND --home $HOMEDIR --node $RPC_URL --gas-prices 25000000000utac --gas 6000000 -y --output json | jq -r '.txhash') +echo "Waiting for transaction $TX_HASH to be included in a block..." +sleep 5 +BABYLON_CONTRACT_CODE_ID=$($TACCHAIND query tx $TX_HASH --node $RPC_URL --output json | jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value' | tr -d '"') +BABYLON_CONTRACT_CODE_ID=$(printf "%d" "$BABYLON_CONTRACT_CODE_ID" 2>/dev/null || echo "$BABYLON_CONTRACT_CODE_ID") +if ! $TACCHAIND query wasm code $BABYLON_CONTRACT_CODE_ID temp.txt --node $RPC_URL; then + echo "Failed to upload babylon contract code." + exit 1 +fi + +# upload btc light client contract +echo "Uploading btc light client contract code $BTC_LIGHT_CLIENT_CONTRACT_FILE..." +TX_HASH=$($TACCHAIND tx wasm store "$BTC_LIGHT_CLIENT_CONTRACT_FILE" --from $OWNER_KEY --keyring-backend $KEYRING_BACKEND --home $HOMEDIR --node $RPC_URL --gas-prices 25000000000utac --gas 6000000 -y --output json | jq -r '.txhash') +echo "Waiting for transaction $TX_HASH to be included in a block..." +sleep 5 +BTC_LIGHT_CLIENT_CONTRACT_CODE_ID=$($TACCHAIND query tx $TX_HASH --node $RPC_URL --output json | jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value' | tr -d '"') +if ! $TACCHAIND query wasm code $BTC_LIGHT_CLIENT_CONTRACT_CODE_ID temp.txt --node $RPC_URL; then + echo "Failed to upload btc light client contract code." + exit 1 +fi + +# upload btc staking contract +echo "Uploading btc staking contract code $BTC_STAKING_CONTRACT_FILE..." +TX_HASH=$($TACCHAIND tx wasm store "$BTC_STAKING_CONTRACT_FILE" --from $OWNER_KEY --keyring-backend $KEYRING_BACKEND --home $HOMEDIR --node $RPC_URL --gas-prices 25000000000utac --gas 6000000 -y --output json | jq -r '.txhash') +echo "Waiting for transaction $TX_HASH to be included in a block..." +sleep 5 +BTC_STAKING_CONTRACT_CODE_ID=$($TACCHAIND query tx $TX_HASH --node $RPC_URL --output json | jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value' | tr -d '"') +if ! $TACCHAIND query wasm code $BTC_STAKING_CONTRACT_CODE_ID temp.txt --node $RPC_URL; then + echo "Failed to upload btc staking contract code." + exit 1 +fi + +# upload btc finality contract +echo "Uploading btc finality contract code $BTC_FINALITY_CONTRACT_FILE..." +TX_HASH=$($TACCHAIND tx wasm store "$BTC_FINALITY_CONTRACT_FILE" --from $OWNER_KEY --keyring-backend $KEYRING_BACKEND --home $HOMEDIR --node $RPC_URL --gas-prices 25000000000utac --gas 6000000 -y --output json | jq -r '.txhash') +echo "Waiting for transaction $TX_HASH to be included in a block..." +sleep 5 +BTC_FINALITY_CONTRACT_CODE_ID=$($TACCHAIND query tx $TX_HASH --node $RPC_URL --output json | jq -r '.events[] | select(.type == "store_code") | .attributes[] | select(.key == "code_id") | .value' | tr -d '"') +if ! $TACCHAIND query wasm code $BTC_FINALITY_CONTRACT_CODE_ID temp.txt --node $RPC_URL; then + echo "Failed to upload btc finality contract code." + exit 1 +fi + +# Instantiate contracts +echo "Instantiating contracts..." +ADMIN=$(tacchaind keys show $OWNER_KEY --keyring-backend $KEYRING_BACKEND -a --home $HOMEDIR) +STAKING_MSG='{ + "admin": "'"$ADMIN"'" +}' +FINALITY_MSG='{ + "params": { + "max_active_finality_providers": 100, + "min_pub_rand": 1, + "finality_inflation_rate": "0.035", + "epoch_length": 10, + "missed_blocks_window": 250, + "jail_duration": 86400 + }, + "admin": "'"$ADMIN"'" +}' + +echo BABYLON_CONTRACT_CODE_ID=$BABYLON_CONTRACT_CODE_ID +echo BTC_LIGHT_CLIENT_CONTRACT_CODE_ID=$BTC_LIGHT_CLIENT_CONTRACT_CODE_ID +echo BTC_STAKING_CONTRACT_CODE_ID=$BTC_STAKING_CONTRACT_CODE_ID +echo BTC_FINALITY_CONTRACT_CODE_ID=$BTC_FINALITY_CONTRACT_CODE_ID +echo STAKING_MSG="$STAKING_MSG" +echo FINALITY_MSG="$FINALITY_MSG" +echo ADMIN="$ADMIN" + +# TODO: currently after initialising the node logs throw warning on each block "cannot get tx contracts from context module=x/wasm", seems to be from x/babylon abci.go? +$TACCHAIND tx babylon instantiate-babylon-contracts "$BABYLON_CONTRACT_CODE_ID" "$BTC_LIGHT_CLIENT_CONTRACT_CODE_ID" "$BTC_STAKING_CONTRACT_CODE_ID" "$BTC_FINALITY_CONTRACT_CODE_ID" "regtest" "01020304" 1 2 false "$STAKING_MSG" "$FINALITY_MSG" "test-consumer" "test-consumer-description" \ + --admin=$ADMIN \ + --ibc-transfer-channel-id=channel-0 \ + --from $OWNER_KEY \ + --home $HOMEDIR \ + --node $RPC_URL \ + --keyring-backend=$KEYRING_BACKEND \ + --gas 6000000 \ + --gas-prices 25000000000utac \ + -y + +rm -rf temp.txt \ No newline at end of file diff --git a/contrib/babylon/init-eotsmanager.sh b/contrib/babylon/init-eotsmanager.sh new file mode 100755 index 0000000..7d0a7b4 --- /dev/null +++ b/contrib/babylon/init-eotsmanager.sh @@ -0,0 +1,9 @@ +#!/bin/bash -e + +HOMEDIR=${HOMEDIR:-/home/finality-provider/.eotsd} +CHAIN_ID=${CHAIN_ID:-babylon-localnet} +MNEMONIC=${MNEMONIC:-"glad slab inch unfold ticket lonely canyon gadget short eager chimney post baby round unknown upset village random club away voice obscure quote cheap"} # bbn1fezaz37eqxxgg5rzm3xg5u53qahp0q6ae55ktt / tac1vwkhvx42xjwktp6khs72ehrnawjyyz6v53ml5u + +if ! eotsd keys show finality-provider --home "$HOMEDIR" --keyring-backend=test > /dev/null 2>&1; then + echo "$MNEMONIC" | eotsd keys add finality-provider --keyring-backend=test --home "$HOMEDIR" --recover +fi \ No newline at end of file diff --git a/contrib/babylon/init-fpd.sh b/contrib/babylon/init-fpd.sh new file mode 100755 index 0000000..6807157 --- /dev/null +++ b/contrib/babylon/init-fpd.sh @@ -0,0 +1,19 @@ +#!/bin/bash -e + +HOMEDIR=${HOMEDIR:-/home/finality-provider/.fpd} +CHAIN_ID=${CHAIN_ID:-tacchain_2391-1} +MNEMONIC=${MNEMONIC:-"city brick always tower shallow enemy alien sauce galaxy lonely where clown bronze garment grain genius summer program lounge hip infant scene outdoor door"} # bbn1jswmc6x22vlgs507n2wuqmparcqun67v0mg93p / tac1ng3kqnv7rjcf7cv2sesqyz6fln8gne4x95c5ju +BTC_PUBLIC_KEY=${BTC_PUBLIC_KEY:-"b5c03bcf902456e16b9beee180d0c71f6e293549759a4f96f7c5638beecd185c"} + +echo $MNEMONIC | fpd keys add finality-provider --keyring-backend test --recover + +# TODO link with eotsmanager + +fpd cfp \ + --key-name finality-provider \ + --chain-id $CHAIN_ID \ + --eots-pk $BTC_PUBLIC_KEY \ + --commission-rate 0.05 \ + --commission-max-rate 0.20 \ + --commission-max-change-rate 0.01 \ + --moniker \"Babylon finality provider\" 2>&1" \ No newline at end of file diff --git a/contrib/babylon/init-tacchaind.sh b/contrib/babylon/init-tacchaind.sh new file mode 100755 index 0000000..e805d3a --- /dev/null +++ b/contrib/babylon/init-tacchaind.sh @@ -0,0 +1,247 @@ +#!/bin/bash -e + +# environment variables +TACCHAIND=${TACCHAIND:-$(which tacchaind)} +HOMEDIR=${HOMEDIR:-$HOME/.tacchaind} +NODE_MONIKER=${NODE_MONIKER:-$(hostname)} +CHAIN_ID=${CHAIN_ID:-tacchain_2391-1} +KEYRING_BACKEND=${KEYRING_BACKEND:-test} +VALIDATOR_IDENTITY=${VALIDATOR_IDENTITY:-4DD1A5E1D03FA12D} +VALIDATOR_WEBSITE=${VALIDATOR_WEBSITE:-https://tac.build/} +VALIDATOR_MNEMONIC=${VALIDATOR_MNEMONIC:-"island mail dice alien project surround orchard ball twist worth innocent arrange assume dragon rotate enough flee rapid rookie swim addict ice destroy run"} # tac15lvhklny0khnwy7hgrxsxut6t6ku2cgknw79fr +VALIDATOR_IP=${VALIDATOR_IP:-192.168.10.8} +INITIAL_BALANCE=${INITIAL_BALANCE:-20000000000000000000000000} +INITIAL_STAKE=${INITIAL_STAKE:-1000000000000000000000} +BLOCK_TIME_SECONDS=${BLOCK_TIME_SECONDS:-2} +MAX_GAS=${MAX_GAS:-90000000} +MIN_GAS_PRICE=${MIN_GAS_PRICE:-25000000000} +GOV_TIME_SECONDS=${GOV_TIME_SECONDS:-900} +GOV_MIN_DEPOSIT=${GOV_MIN_DEPOSIT:-10000000000000000} +GOV_MIN_EXPEDITED_DEPOSIT=${GOV_MIN_EXPEDITED_DEPOSIT:-50000000000000000} +GOV_MIN_INITIAL_DEPOSIT_RATIO=${GOV_MIN_INITIAL_DEPOSIT_RATIO:-1} +INFLATION_MAX=${INFLATION_MAX:-0.05} +INFLATION_MIN=${INFLATION_MIN:-0.01} +GOAL_BONDED=${GOAL_BONDED:-0.6} +SLASH_DOWNTIME_PENALTY=${SLASH_DOWNTIME_PENALTY:-0.001} +SLASH_SIGNED_BLOCKS_WINDOW=${SLASH_SIGNED_BLOCKS_WINDOW:-21600} +MAX_VALIDATORS=${MAX_VALIDATORS:-14} + +# ports +RPC_PORT=${RPC_PORT:-27657} +P2P_PORT=${P2P_PORT:-27656} +GRPC_PORT=${GRPC_PORT:-9190} +GRPC_WEB_PORT=${GRPC_WEB_PORT:-9191} +API_PORT=${API_PORT:-1417} +JSON_RPC_PORT=${JSON_RPC_PORT:-8645} +JSON_WS_PORT=${JSON_WS_PORT:-8646} +METRICS_PORT=${METRICS_PORT:-6165} +PROMETHEUS_PORT=${PROMETHEUS_PORT:-27660} +PPROF_PORT=${PPROF_PORT:-6160} +PROXY_PORT=${PROXY_PORT:-27658} + +# set cli options default values +$TACCHAIND config set client chain-id $CHAIN_ID +$TACCHAIND config set client keyring-backend $KEYRING_BACKEND +$TACCHAIND config set client output json + +# if HOMEDIR already exists, skip initialization +if [ -f "$HOMEDIR/config/genesis.json" ]; then + echo "HOMEDIR already exists, skipping initialization." + exit 0 +fi + +# init genesis file +$TACCHAIND init "$NODE_MONIKER" --chain-id $CHAIN_ID --default-denom utac --home $HOMEDIR + +# predeployed contracts (all precompiled contracts need to be defined before genesis accounts to avoid issues with auth account_numbers) +# safe singleton factory (https://github.com/safe-global/safe-singleton-factory) +jq ' + .app_state.auth.accounts += [{ + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tac1j9xhlmr24jxd2sh890983vcx2r29vs7hc7xaks", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }] + | .app_state.evm.accounts += [{ + "address": "0x914d7fec6aac8cd542e72bca78b30650d45643d7", + "code": "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", + "storage": [] + }] +' $HOMEDIR/config/genesis.json > $HOMEDIR/config/genesis_patched.json && mv $HOMEDIR/config/genesis_patched.json $HOMEDIR/config/genesis.json + +# arachnid (https://github.com/Arachnid/deterministic-deployment-proxy) +jq ' + .app_state.auth.accounts += [{ + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tac1fevmgjz8kdu40pvgjgx20ralymqtf9tv2r6x6q", + "pub_key": null, + "account_number": "1", + "sequence": "0" + }] + | .app_state.evm.accounts += [{ + "address": "0x4e59b44847b379578588920ca78fbf26c0b4956c", + "code": "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3", + "storage": [] + }] +' $HOMEDIR/config/genesis.json > $HOMEDIR/config/genesis_patched.json && mv $HOMEDIR/config/genesis_patched.json $HOMEDIR/config/genesis.json + + +# multicall (https://github.com/mds1/multicall3) +jq ' + .app_state.auth.accounts += [{ + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tac1eggmmczew7ekxyt8q2yx9032zuuhdjs3yd8s2h", + "pub_key": null, + "account_number": "2", + "sequence": "0" + }] + | .app_state.evm.accounts += [{ + "address": "0xca11bde05977b3631167028862be2a173976ca11", + "code": "6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033", + "storage": [] + }] +' $HOMEDIR/config/genesis.json > $HOMEDIR/config/genesis_patched.json && mv $HOMEDIR/config/genesis_patched.json $HOMEDIR/config/genesis.json + +# createx (https://github.com/pcaversaccio/createx) +jq ' + .app_state.auth.accounts += [{ + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tac1hf0dpxtr85anz0jdtaaacyc960pghf0draedhx", + "pub_key": null, + "account_number": "3", + "sequence": "0" + }] + | .app_state.evm.accounts += [{ + "address": "0xba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed", + "code": "60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed8361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a", + "storage": [] + }] +' $HOMEDIR/config/genesis.json > $HOMEDIR/config/genesis_patched.json && mv $HOMEDIR/config/genesis_patched.json $HOMEDIR/config/genesis.json + +# edit configs + +# set EVM config +# get ethereum chain id from CHAIN_ID +EVM_CHAIN_ID=$(echo $CHAIN_ID | sed -E 's/.*_([0-9]+)-.*/\1/') +if [[ -z $EVM_CHAIN_ID ]]; then + echo "Invalid CHAIN_ID format. Expected format: _-" + exit 1 +fi + +sed -i.bak "s/\"chain_id\": \"262144\"/\"chain_id\": \"$EVM_CHAIN_ID\"/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/\"denom\": \"atest\"/\"denom\": \"utac\"/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/\"evm_denom\": \"atest\"/\"evm_denom\": \"utac\"/g" $HOMEDIR/config/genesis.json + +# enable evm eip-3855 +sed -i.bak "s/\"extra_eips\": \[\]/\"extra_eips\": \[\"3855\"\]/g" $HOMEDIR/config/genesis.json + +# disable EIP-155 +sed -i.bak "s/\"allow_unprotected_txs\": false/\"allow_unprotected_txs\": true/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/allow-unprotected-txs = false/allow-unprotected-txs = true/g" $HOMEDIR/config/app.toml + +# set evm precompiles +sed -i.bak "s/\"active_static_precompiles\": \[\]/\"active_static_precompiles\": \[\"0x0000000000000000000000000000000000000100\",\"0x0000000000000000000000000000000000000400\",\"0x0000000000000000000000000000000000000800\",\"0x0000000000000000000000000000000000000801\",\"0x0000000000000000000000000000000000000802\",\"0x0000000000000000000000000000000000000803\",\"0x0000000000000000000000000000000000000804\",\"0x0000000000000000000000000000000000000805\",\"0x0000000000000000000000000000000000000806\",\"0x0000000000000000000000000000000000000807\"\]/g" $HOMEDIR/config/genesis.json + +# set x/feemarket min gas price +sed -i.bak "s/\"min_gas_price\": \"0.000000000000000000\"/\"min_gas_price\": \"$MIN_GAS_PRICE\"/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/\"base_fee\": \"1000000000.000000000000000000\"/\"base_fee\": \"$MIN_GAS_PRICE\"/g" $HOMEDIR/config/genesis.json + +# set max gas +sed -i.bak "s/\"max_gas\": \"-1\"/\"max_gas\": \"$MAX_GAS\"/g" $HOMEDIR/config/genesis.json + +# update blocks per year to match our block time +BLOCKS_PER_YEAR=$(echo "(365 * 24 * 60 * 60) / $BLOCK_TIME_SECONDS" | bc) +sed -i.bak "s/\"blocks_per_year\": \"6311520\"/\"blocks_per_year\": \"$BLOCKS_PER_YEAR\"/g" $HOMEDIR/config/genesis.json + +# set inflation +sed -i.bak "s/\"inflation_max\": \"0.200000000000000000\"/\"inflation_max\": \"$INFLATION_MAX\"/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/\"inflation_min\": \"0.070000000000000000\"/\"inflation_min\": \"$INFLATION_MIN\"/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/\"goal_bonded\": \"0.670000000000000000\"/\"goal_bonded\": \"$GOAL_BONDED\"/g" $HOMEDIR/config/genesis.json + +# set gov vote time +sed -i.bak "s/\"voting_period\": \"172800s\"/\"voting_period\": \"${GOV_TIME_SECONDS}s\"/g" $HOMEDIR/config/genesis.json +EXPEDITED_TIME_SECONDS=$((GOV_TIME_SECONDS / 2)) +sed -i.bak "s/\"expedited_voting_period\": \"86400s\"/\"expedited_voting_period\": \"${EXPEDITED_TIME_SECONDS}s\"/g" $HOMEDIR/config/genesis.json + +# set gov min initial deposit ratio +sed -i.bak "s/\"min_initial_deposit_ratio\": \"0.000000000000000000\"/\"min_initial_deposit_ratio\": \"$GOV_MIN_INITIAL_DEPOSIT_RATIO\"/g" $HOMEDIR/config/genesis.json + +# set min gov deposit +jq --arg GOV_MIN_DEPOSIT "$GOV_MIN_DEPOSIT" ' + .app_state.gov.params.min_deposit = [ + { + "denom": "utac", + "amount": $GOV_MIN_DEPOSIT + } + ] +' $HOMEDIR/config/genesis.json > $HOMEDIR/config/genesis_patched.json && mv $HOMEDIR/config/genesis_patched.json $HOMEDIR/config/genesis.json + +# set min expedited gov deposit +jq --arg GOV_MIN_EXPEDITED_DEPOSIT "$GOV_MIN_EXPEDITED_DEPOSIT" ' + .app_state.gov.params.expedited_min_deposit = [ + { + "denom": "utac", + "amount": $GOV_MIN_EXPEDITED_DEPOSIT + } + ] +' $HOMEDIR/config/genesis.json > $HOMEDIR/config/genesis_patched.json && mv $HOMEDIR/config/genesis_patched.json $HOMEDIR/config/genesis.json + +# enable apis +sed -i.bak "s/enable = false/enable = true/g" $HOMEDIR/config/app.toml + +# enable rpc cors +sed -i.bak "s/cors_allowed_origins = \[\]/cors_allowed_origins = \[\"*\"\]/g" $HOMEDIR/config/config.toml + +# set slashing +sed -i.bak "s/\"slash_fraction_downtime\": \"0.010000000000000000\"/\"slash_fraction_downtime\": \"$SLASH_DOWNTIME_PENALTY\"/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/\"signed_blocks_window\": \"100\"/\"signed_blocks_window\": \"$SLASH_SIGNED_BLOCKS_WINDOW\"/g" $HOMEDIR/config/genesis.json + +# add token metadata +jq ' + .app_state.bank.denom_metadata = [ + { + "description": "The native staking token for tacchaind.", + "denom_units": [ + { + "denom": "utac", + "exponent": 0, + "aliases": [] + }, + { + "denom": "tac", + "exponent": 18, + "aliases": [] + } + ], + "base": "utac", + "display": "tac", + "name": "TAC Token", + "symbol": "TAC", + "uri": "", + "uri_hash": "" + } + ] +' $HOMEDIR/config/genesis.json > $HOMEDIR/config/genesis_patched.json && mv $HOMEDIR/config/genesis_patched.json $HOMEDIR/config/genesis.json + +# set max validators +sed -i.bak "s/\"max_validators\": 100/\"max_validators\": $MAX_VALIDATORS/g" $HOMEDIR/config/genesis.json + +# set ports +sed -i.bak "s/127.0.0.1:26657/0.0.0.0:$RPC_PORT/g" $HOMEDIR/config/config.toml +sed -i.bak "s/26656/$P2P_PORT/g" $HOMEDIR/config/config.toml +sed -i.bak "s/localhost:9090/0.0.0.0:$GRPC_PORT/g" $HOMEDIR/config/app.toml +sed -i.bak "s/9091/$GRPC_WEB_PORT/g" $HOMEDIR/config/app.toml +sed -i.bak "s/1317/$API_PORT/g" $HOMEDIR/config/app.toml +sed -i.bak "s/8545/$JSON_RPC_PORT/g" $HOMEDIR/config/app.toml +sed -i.bak "s/8546/$JSON_WS_PORT/g" $HOMEDIR/config/app.toml +sed -i.bak "s/6065/$METRICS_PORT/g" $HOMEDIR/config/app.toml +sed -i.bak "s/26660/$PROMETHEUS_PORT/g" $HOMEDIR/config/config.toml +sed -i.bak "s/6060/$PPROF_PORT/g" $HOMEDIR/config/config.toml +sed -i.bak "s/26658/$PROXY_PORT/g" $HOMEDIR/config/config.toml + +# setup and add validator to genesis +echo $VALIDATOR_MNEMONIC | $TACCHAIND keys add validator --recover --keyring-backend $KEYRING_BACKEND --home $HOMEDIR +$TACCHAIND genesis add-genesis-account validator ${INITIAL_BALANCE}utac --keyring-backend $KEYRING_BACKEND --home $HOMEDIR +$TACCHAIND genesis gentx validator ${INITIAL_STAKE}utac --identity $VALIDATOR_IDENTITY --website $VALIDATOR_WEBSITE --ip $VALIDATOR_IP --chain-id $CHAIN_ID --keyring-backend $KEYRING_BACKEND --gas-prices ${MIN_GAS_PRICE}utac --gas 200000 --home $HOMEDIR +$TACCHAIND genesis collect-gentxs --keyring-backend $KEYRING_BACKEND --home $HOMEDIR \ No newline at end of file diff --git a/contrib/babylon/vigilante.yml b/contrib/babylon/vigilante.yml new file mode 100644 index 0000000..1183323 --- /dev/null +++ b/contrib/babylon/vigilante.yml @@ -0,0 +1,100 @@ +common: + retry-sleep-time: 1s + max-retry-sleep-time: 1m + log-format: "auto" + log-level: "debug" +btc: + disable-tls: true + no-client-tls: true # use true for bitcoind as it does not support tls + ca-file: ~ + endpoint: bitcoindsim:18443 # use port 18443 for bitcoind regtest + estimate-mode: CONSERVATIVE # only needed by bitcoind + tx-fee-max: 10000 # maximum tx fee, 10,000sat/kvb + tx-fee-min: 1000 # minimum tx fee, 1,000sat/kvb + default-fee: 1000 # 1,000sat/kvb + target-block-num: 2 + wallet-endpoint: ~ + wallet-password: walletpass + wallet-name: default + wallet-lock-time: 10 + wallet-ca-file: ~ + net-params: regtest # use regtest for bitcoind as it does not support simnet + username: rpcuser + password: rpcpass + reconnect-attempts: 3 + btc-backend: bitcoind # {btcd, bitcoind} + zmq-seq-endpoint: tcp://bitcoindsim:29000 + zmq-block-endpoint: tcp://bitcoindsim:29001 + zmq-tx-endpoint: tcp://bitcoindsim:29002 +babylon: + key: vigilante + chain-id: chain-test + rpc-addr: http://babylond:26657 + grpc-addr: https://babylond:9090 + account-prefix: bbn + keyring-backend: test + gas-adjustment: 1.5 + gas-prices: 2ubbn + key-directory: /home/vigilante/config + debug: true + timeout: 20s + block-timeout: 10s + output-format: json + submitter-address: bbn1v6k7k9s8md3k29cu9runasstq5zaa0lpznk27w + sign-mode: direct +grpc: + onetime-tls-key: true + rpc-key: "" + rpc-cert: /home/vigilante/config/rpc.cert + endpoints: + - localhost:8080 +grpcweb: + placeholder: grpcwebconfig +metrics: + host: 0.0.0.0 + server-port: 2112 +submitter: + netparams: regtest + buffer-size: 100 + polling-interval-seconds: 60 + resend-interval-seconds: 1800 + resubmit-fee-multiplier: 2 + dbconfig: + dbpath: /home/vigilante/submitter/data + dbfilename: submitter.db + nofreelistsync: true + autocompact: false + autocompactminage: 168h0m0s + dbtimeout: 1m0s +reporter: + netparams: regtest + btc_cache_size: 1000 + max_headers_in_msg: 100 +monitor: + checkpoint-buffer-size: 1000 + btc-block-buffer-size: 1000 + btc-cache-size: 1000 + btc-confirmation-depth: 6 + liveness-check-interval-seconds: 100 + max-live-btc-heights: 200 + enable-liveness-checker: true + enable-slasher: true + btcnetparams: regtest + dbconfig: + dbpath: /home/vigilante/monitor/data + dbfilename: monitor.db + nofreelistsync: true + autocompact: false + autocompactminage: 168h0m0s + dbtimeout: 1m0s +btcstaking-tracker: + check-delegations-interval: 10s + delegations-batch-size: 100 + check-if-delegation-active-interval: 10s + retry-submit-unbonding-interval: 10s + max-jitter-interval: 30s + btcnetparams: regtest + max-slashing-concurrency: 20 + indexer-addr: http://electrs:3003 + fetch-comet-block-interval: 3s + fetch-evidence-interval: 10s diff --git a/contrib/localnet/init.sh b/contrib/localnet/init.sh index 554371c..cfd836d 100755 --- a/contrib/localnet/init.sh +++ b/contrib/localnet/init.sh @@ -148,6 +148,7 @@ sed -i.bak "s/\"active_static_precompiles\": \[\]/\"active_static_precompiles\": # set x/feemarket min gas price sed -i.bak "s/\"min_gas_price\": \"0.000000000000000000\"/\"min_gas_price\": \"$MIN_GAS_PRICE\"/g" $HOMEDIR/config/genesis.json +sed -i.bak "s/\"base_fee\": \"1000000000.000000000000000000\"/\"base_fee\": \"$MIN_GAS_PRICE\"/g" $HOMEDIR/config/genesis.json # set max gas sed -i.bak "s/\"max_gas\": \"-1\"/\"max_gas\": \"$MAX_GAS\"/g" $HOMEDIR/config/genesis.json @@ -230,7 +231,7 @@ jq ' sed -i.bak "s/\"max_validators\": 100/\"max_validators\": $MAX_VALIDATORS/g" $HOMEDIR/config/genesis.json # set ports -sed -i.bak "s/26657/$RPC_PORT/g" $HOMEDIR/config/config.toml +sed -i.bak "s/127.0.0.1:26657/0.0.0.0:$RPC_PORT/g" $HOMEDIR/config/config.toml sed -i.bak "s/26656/$P2P_PORT/g" $HOMEDIR/config/config.toml sed -i.bak "s/9090/$GRPC_PORT/g" $HOMEDIR/config/app.toml sed -i.bak "s/9091/$GRPC_WEB_PORT/g" $HOMEDIR/config/app.toml diff --git a/go.mod b/go.mod index 8ad30c2..b1df1bf 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,9 @@ require ( cosmossdk.io/x/feegrant v0.1.1 cosmossdk.io/x/nft v0.1.1 cosmossdk.io/x/upgrade v0.1.4 + github.com/CosmWasm/wasmd v0.54.0 + github.com/babylonlabs-io/babylon-sdk/demo v0.0.0-20250619103401-4d396c49178b + github.com/babylonlabs-io/babylon-sdk/x v0.0.0-20250514041845-2ca20309f1f4 github.com/cometbft/cometbft v0.38.17 github.com/cosmos/cosmos-db v1.1.1 github.com/cosmos/cosmos-sdk v0.50.13 @@ -26,6 +29,7 @@ require ( github.com/ethereum/go-ethereum v1.13.15 github.com/onsi/ginkgo/v2 v2.22.2 github.com/onsi/gomega v1.36.2 + github.com/prometheus/client_golang v1.20.5 github.com/spf13/cast v1.7.1 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 @@ -46,12 +50,13 @@ require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/99designs/keyring v1.2.1 // indirect + github.com/CosmWasm/wasmvm/v2 v2.2.3 // indirect github.com/DataDog/datadog-go v3.2.0+incompatible // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/VictoriaMetrics/fastcache v1.12.1 // indirect - github.com/aws/aws-sdk-go v1.44.224 // indirect + github.com/aws/aws-sdk-go v1.44.312 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect @@ -62,7 +67,7 @@ require ( github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/bytedance/sonic v1.12.3 // indirect github.com/bytedance/sonic/loader v0.2.0 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cenkalti/backoff/v4 v4.2.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chzyer/readline v1.5.1 // indirect github.com/cloudwego/base64x v0.1.4 // indirect @@ -95,6 +100,7 @@ require ( github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v4 v4.2.0 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect + github.com/distribution/reference v0.5.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect github.com/dop251/goja v0.0.0-20230806174421-c933cf95e127 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -127,6 +133,7 @@ require ( github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v23.5.26+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/s2a-go v0.1.7 // indirect @@ -183,11 +190,11 @@ require ( github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -199,6 +206,7 @@ require ( github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.5 // indirect + github.com/shamaton/msgpack/v2 v2.2.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect @@ -267,6 +275,10 @@ replace ( // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 + // replace wasmd with our fork that adds dummy Copy method to the store to satisfy replaced cosmossdk.io/store + // See: https://github.com/CosmWasm/wasmd/compare/v0.54.0...Asphere-xyz:wasmd:v0.54.0-asphere + github.com/CosmWasm/wasmd => github.com/asphere-xyz/wasmd v0.0.0-20250403104749-bac39e6c2aaa + // Pin this pebble version to avoid breaking compilation of geth github.com/cockroachdb/pebble => github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 diff --git a/go.sum b/go.sum index 5edb6b4..00e68c9 100644 --- a/go.sum +++ b/go.sum @@ -227,6 +227,8 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25 github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CosmWasm/wasmvm/v2 v2.2.3 h1:LVaAdkCMbgfUTSFOANmp2OOU1rIgz4iylow4SFD/lqs= +github.com/CosmWasm/wasmvm/v2 v2.2.3/go.mod h1:bMhLQL4Yp9CzJi9A83aR7VO9wockOsSlZbT4ztOl6bg= github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= @@ -267,12 +269,18 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asphere-xyz/wasmd v0.0.0-20250403104749-bac39e6c2aaa h1:Q6wqYqjIfSqiqHMKWJcK5ph6do7vAQAyczGvLBmCRL4= +github.com/asphere-xyz/wasmd v0.0.0-20250403104749-bac39e6c2aaa/go.mod h1:8Zu/rj6RHbJ8Gx0WdqsGeHvgnEQb0rqchpqhgMxASRU= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.224 h1:09CiaaF35nRmxrzWZ2uRq5v6Ghg/d2RiPjZnSgtt+RQ= -github.com/aws/aws-sdk-go v1.44.224/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k= +github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/babylonlabs-io/babylon-sdk/demo v0.0.0-20250619103401-4d396c49178b h1:RZ95BP22N0ZKOYjmJ5IDYUmtDehZ+K63A7ctgiscEss= +github.com/babylonlabs-io/babylon-sdk/demo v0.0.0-20250619103401-4d396c49178b/go.mod h1:3Myjemu1e2TgxTV9UYkDsDZfF7sUAwRJzNvRzrVg63U= +github.com/babylonlabs-io/babylon-sdk/x v0.0.0-20250514041845-2ca20309f1f4 h1:7f9nuSbHjFGERG7/Vd5/uBBEa9YU4Kd7oKIeXzQl8XU= +github.com/babylonlabs-io/babylon-sdk/x v0.0.0-20250514041845-2ca20309f1f4/go.mod h1:ks4/p72aNJTIN8+CnCFxNX0HqfgHdClEwU4LxAxryJQ= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= @@ -325,8 +333,8 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -467,6 +475,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WAFKLNi6ZS0675eEUC9y3AlwSbQu1Y= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= +github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= @@ -574,12 +584,15 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= +github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -1086,6 +1099,8 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0 github.com/sasha-s/go-deadlock v0.3.5 h1:tNCOEEDG6tBqrNDOX35j/7hL5FcFViG6awUGROb2NsU= github.com/sasha-s/go-deadlock v0.3.5/go.mod h1:bugP6EGbdGYObIlx7pUZtWqlvo8k9H6vCBBsiChJQ5U= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shamaton/msgpack/v2 v2.2.0 h1:IP1m01pHwCrMa6ZccP9B3bqxEMKMSmMVAVKk54g3L/Y= +github.com/shamaton/msgpack/v2 v2.2.0/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= diff --git a/tests/wasmd/01-accounts.sh b/tests/wasmd/01-accounts.sh new file mode 100755 index 0000000..36a2631 --- /dev/null +++ b/tests/wasmd/01-accounts.sh @@ -0,0 +1,29 @@ +#!/bin/bash -e +set -o errexit -o nounset -o pipefail + +HOMEDIR=.test-wasmd + +BASE_ACCOUNT=$(tacchaind keys show validator -a --keyring-backend=test --home $HOMEDIR) +tacchaind q auth account "$BASE_ACCOUNT" -o json --home $HOMEDIR | jq + +echo "## Add new account" +tacchaind keys add fred --keyring-backend=test --home $HOMEDIR + +echo "## Check balance" +NEW_ACCOUNT=$(tacchaind keys show fred -a --keyring-backend=test --home $HOMEDIR) +tacchaind q bank balances "$NEW_ACCOUNT" -o json --home $HOMEDIR || true + +echo "## TEMP Feemarket params" +tacchaind q feemarket params -o json --home $HOMEDIR | jq + +echo "## Transfer tokens" +tacchaind tx bank send validator "$NEW_ACCOUNT" 50000000000000000utac --gas-prices 25000000000utac -y -b sync -o json --keyring-backend=test --home $HOMEDIR | jq +sleep 6 + +echo "## Check balance again" +BALANCE=$(tacchaind q bank balances "$NEW_ACCOUNT" -o json --home $HOMEDIR | jq -r '.balances[] | select(.denom=="utac") | .amount') +echo "Balance: $BALANCE utac" +if [[ -z "$BALANCE" || "$BALANCE" -lt 50000000000000000 ]]; then + echo "Error: Balance is less than 50000000000000000 utac" + exit 1 +fi diff --git a/tests/wasmd/02-contracts.sh b/tests/wasmd/02-contracts.sh new file mode 100755 index 0000000..87dd1e7 --- /dev/null +++ b/tests/wasmd/02-contracts.sh @@ -0,0 +1,114 @@ +#!/bin/bash -e +set -o errexit -o nounset -o pipefail -x + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" +HOMEDIR=.test-wasmd + +echo "-----------------------" +echo "## Add new CosmWasm contract" +RESP=$(tacchaind tx wasm store "$DIR/testdata/hackatom.wasm" \ + --from validator --gas 1500000 --gas-prices 25000000000utac -y -b sync -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +RESP=$(tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR) +CODE_ID=$(echo "$RESP" | jq -r '.events[]| select(.type=="store_code").attributes[]| select(.key=="code_id").value') +CODE_HASH=$(echo "$RESP" | jq -r '.events[]| select(.type=="store_code").attributes[]| select(.key=="code_checksum").value') +echo "* Code id: $CODE_ID" +echo "* Code checksum: $CODE_HASH" + +echo "* Download code" +TMPDIR=$(mktemp -d -t wasmdXXXXXX) +tacchaind q wasm code "$CODE_ID" "$TMPDIR/delme.wasm" --home $HOMEDIR +rm -f "$TMPDIR/delme.wasm" +echo "-----------------------" +echo "## List code" +tacchaind query wasm list-code --node=http://localhost:26657 -o json --home $HOMEDIR | jq + +echo "-----------------------" +echo "## Create new contract instance" +INIT="{\"verifier\":\"$(tacchaind keys show validator -a --keyring-backend=test --home $HOMEDIR)\", \"beneficiary\":\"$(tacchaind keys show fred -a --keyring-backend=test --home $HOMEDIR)\"}" +RESP=$(tacchaind tx wasm instantiate "$CODE_ID" "$INIT" --admin="$(tacchaind keys show validator -a --keyring-backend=test --home $HOMEDIR)" \ + --from validator --amount="100utac" --label "local0.1.0" \ + --gas 1000000 --gas-prices 25000000000utac -y -b sync -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR | jq + +CONTRACT=$(tacchaind query wasm list-contract-by-code "$CODE_ID" -o json --home $HOMEDIR | jq -r '.contracts[-1]') +echo "* Contract address: $CONTRACT" + +echo "## Create new contract instance with predictable address" +RESP=$(tacchaind tx wasm instantiate2 "$CODE_ID" "$INIT" $(echo -n "tacchain_2391-1" | xxd -ps) \ + --admin="$(tacchaind keys show validator -a --keyring-backend=test --home $HOMEDIR)" \ + --from validator --amount="100utac" --label "local0.1.0" \ + --fix-msg \ + --gas 1000000 --gas-prices 25000000000utac -y -b sync -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR | jq + + +predictedAddress=$(tacchaind q wasm build-address "$CODE_HASH" $(tacchaind keys show validator -a --keyring-backend=test --home $HOMEDIR) $(echo -n "tacchain_2391-1" | xxd -ps) "$INIT" --home $HOMEDIR | jq -r .address) +tacchaind q wasm contract $predictedAddress -o json --home $HOMEDIR | jq + +echo "### Query all" +RESP=$(tacchaind query wasm contract-state all "$CONTRACT" -o json --home $HOMEDIR) +echo "$RESP" | jq +echo "### Query smart" +tacchaind query wasm contract-state smart "$CONTRACT" '{"verifier":{}}' -o json --home $HOMEDIR | jq +echo "### Query raw" +KEY=$(echo "$RESP" | jq -r ".models[0].key") +tacchaind query wasm contract-state raw "$CONTRACT" "$KEY" -o json --home $HOMEDIR | jq + +echo "-----------------------" +echo "## Execute contract $CONTRACT" +MSG='{"release":{}}' +RESP=$(tacchaind tx wasm execute "$CONTRACT" "$MSG" \ + --from validator \ + --gas 1000000 --gas-prices 25000000000utac -y -b sync -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json | jq + + +echo "-----------------------" +echo "## Set new admin" +echo "### Query old admin: $(tacchaind q wasm contract "$CONTRACT" -o json --home $HOMEDIR | jq -r '.contract_info.admin')" +echo "### Update contract" +RESP=$(tacchaind tx wasm set-contract-admin "$CONTRACT" "$(tacchaind keys show fred -a --keyring-backend=test --home $HOMEDIR)" \ + --from validator --gas-prices 25000000000utac -y -b sync -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR | jq + +echo "### Query new admin: $(tacchaind q wasm contract "$CONTRACT" -o json --home $HOMEDIR | jq -r '.contract_info.admin')" + +echo "-----------------------" +echo "## Migrate contract" +echo "### Upload new code" +RESP=$(tacchaind tx wasm store "$DIR/testdata/burner.wasm" \ + --from validator --gas 1100000 --gas-prices 25000000000utac -y --node=http://localhost:26657 -b sync -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +RESP=$(tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR) +BURNER_CODE_ID=$(echo "$RESP" | jq -r '.events[]| select(.type=="store_code").attributes[]| select(.key=="code_id").value') + +echo "### Migrate to code id: $BURNER_CODE_ID" + +DEST_ACCOUNT=$(tacchaind keys show fred -a --keyring-backend=test --home $HOMEDIR) +RESP=$(tacchaind tx wasm migrate "$CONTRACT" "$BURNER_CODE_ID" "{\"payout\": \"$DEST_ACCOUNT\"}" --from fred \ + -b sync --gas-prices 25000000000utac -y -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR | jq + +echo "### Query destination account: $BURNER_CODE_ID" +tacchaind q bank balances "$DEST_ACCOUNT" -o json --home $HOMEDIR | jq +echo "### Query contract meta data: $CONTRACT" +tacchaind q wasm contract "$CONTRACT" -o json --home $HOMEDIR | jq + +echo "### Query contract meta history: $CONTRACT" +tacchaind q wasm contract-history "$CONTRACT" -o json --home $HOMEDIR | jq + +echo "-----------------------" +echo "## Clear contract admin" +echo "### Query old admin: $(tacchaind q wasm contract "$CONTRACT" -o json --home $HOMEDIR | jq -r '.contract_info.admin')" +echo "### Update contract" +RESP=$(tacchaind tx wasm clear-contract-admin "$CONTRACT" \ + --from fred --gas-prices 25000000000utac -y -b sync -o json --keyring-backend=test --home $HOMEDIR) +sleep 6 +tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR | jq +echo "### Query new admin: $(tacchaind q wasm contract "$CONTRACT" -o json --home $HOMEDIR | jq -r '.contract_info.admin')" diff --git a/tests/wasmd/03-grpc-queries.sh b/tests/wasmd/03-grpc-queries.sh new file mode 100755 index 0000000..2a83199 --- /dev/null +++ b/tests/wasmd/03-grpc-queries.sh @@ -0,0 +1,22 @@ +#!/bin/bash -e +set -o errexit -o nounset -o pipefail + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" + +echo "-----------------------" + +echo "### List all codes" +RESP=$(grpcurl -plaintext localhost:9090 cosmwasm.wasm.v1.Query/Codes) +echo "$RESP" | jq + +CODE_ID=$(echo "$RESP" | jq -r '.codeInfos[-1].codeId') +echo "### List contracts by code" +RESP=$(grpcurl -plaintext -d "{\"codeId\": $CODE_ID}" localhost:9090 cosmwasm.wasm.v1.Query/ContractsByCode) +echo "$RESP" | jq + +echo "### Show history for contract" +CONTRACT=$(echo "$RESP" | jq -r ".contracts[-1]") +grpcurl -plaintext -d "{\"address\": \"$CONTRACT\"}" localhost:9090 cosmwasm.wasm.v1.Query/ContractHistory | jq + +echo "### Show contract state" +grpcurl -plaintext -d "{\"address\": \"$CONTRACT\"}" localhost:9090 cosmwasm.wasm.v1.Query/AllContractState | jq diff --git a/tests/wasmd/04-gov.sh b/tests/wasmd/04-gov.sh new file mode 100755 index 0000000..8fcfbc6 --- /dev/null +++ b/tests/wasmd/04-gov.sh @@ -0,0 +1,22 @@ +#!/bin/bash -e +set -o errexit -o nounset -o pipefail + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" + +HOMEDIR=.test-wasmd + +sleep 1 +echo "## Submit a CosmWasm gov proposal" +RESP=$(tacchaind tx wasm submit-proposal store-instantiate "$DIR/testdata/reflect_2_0.wasm" \ + '{}' --label="testing" \ + --title "testing" --summary "Testing" --deposit "1000000000utac" \ + --admin $(tacchaind keys show -a validator --keyring-backend=test --home $HOMEDIR) \ + --amount 123utac \ + --keyring-backend=test \ + --gas 1500000 \ + --gas-prices 25000000000utac \ + --from validator -y --node=http://localhost:26657 -b sync -o json --home $HOMEDIR) +echo $RESP +sleep 6 +tacchaind q tx $(echo "$RESP"| jq -r '.txhash') -o json --home $HOMEDIR | jq + diff --git a/tests/wasmd/test-wasmd.sh b/tests/wasmd/test-wasmd.sh new file mode 100755 index 0000000..2140054 --- /dev/null +++ b/tests/wasmd/test-wasmd.sh @@ -0,0 +1,64 @@ +#!/bin/bash -e + +export HOMEDIR=.test-wasmd +export MIN_GAS_PRICE=25000000000 + +# start new network +echo "Starting localnet" +echo y | make localnet > /dev/null 2>&1 & + +# wait for network to start +echo "Waiting for network to start" +timeout=120 +elapsed=0 +interval=2 +while ! tacchaind query block --type=height 3 --node http://localhost:26657 > /dev/null 2>&1; do + sleep $interval + elapsed=$((elapsed + interval)) + if [ $elapsed -ge $timeout ]; then + echo "Failed to start network. Timeout waiting for block height 3" + + killall tacchaind + exit 1 + fi +done +echo "Network started successfully" + +# test accounts +echo "Testing accounts" +if ! $(dirname "$0")/01-accounts.sh; then + echo "Accounts test failed" + killall tacchaind + exit 1 +fi +echo "Accounts test passed successfully" + +# test contracts +echo "Testing contracts" +if ! $(dirname "$0")/02-contracts.sh; then + echo "Contracts test failed" + killall tacchaind + exit 1 +fi +echo "Contracts test passed successfully" + +# test gRPC queries +echo "Testing gRPC queries" +if ! $(dirname "$0")/03-grpc-queries.sh; then + echo "gRPC queries test failed" + killall tacchaind + exit 1 +fi +echo "gRPC queries test passed successfully" + +# test governance +echo "Testing governance" +if ! $(dirname "$0")/04-gov.sh; then + echo "Governance test failed" + killall tacchaind + exit 1 +fi +echo "Governance test passed successfully" + +killall tacchaind +echo "All tests passed successfully" diff --git a/tests/wasmd/testdata/burner.wasm b/tests/wasmd/testdata/burner.wasm new file mode 100644 index 0000000..dbfd0aa Binary files /dev/null and b/tests/wasmd/testdata/burner.wasm differ diff --git a/tests/wasmd/testdata/hackatom.wasm b/tests/wasmd/testdata/hackatom.wasm new file mode 100644 index 0000000..5333788 Binary files /dev/null and b/tests/wasmd/testdata/hackatom.wasm differ diff --git a/tests/wasmd/testdata/reflect_2_0.wasm b/tests/wasmd/testdata/reflect_2_0.wasm new file mode 100644 index 0000000..9791208 Binary files /dev/null and b/tests/wasmd/testdata/reflect_2_0.wasm differ