From d14724b492aba6052f1bfb95470fc6af1aa082a1 Mon Sep 17 00:00:00 2001 From: beer-1 <147697694+beer-1@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:15:57 +0900 Subject: [PATCH] feat: add submsg impl (#277) * add submsg impl to allow failure in cosmos stargate call and set upgrade handler for testnet upgrade * add diff command * fix condition * change default csr to zero * fix review comments * change comment --- Dockerfile | 2 +- app/upgrade.go | 32 ++++- cmd/initiad/root.go | 2 +- cmd/move/move.go | 19 ++- go.mod | 4 +- go.sum | 8 +- x/move/keeper/binaries/BasicCoin.mv | Bin 645 -> 645 bytes x/move/keeper/binaries/Vesting.mv | Bin 2852 -> 2852 bytes x/move/keeper/binaries/submsg.mv | Bin 0 -> 630 bytes x/move/keeper/common_test.go | 6 + x/move/keeper/contracts/sources/Submsg.move | 49 ++++++++ x/move/keeper/handler.go | 122 ++++++++++++++---- x/move/keeper/handler_test.go | 133 ++++++++++++++++++-- x/move/types/events.go | 5 + x/move/types/params.go | 2 +- 15 files changed, 336 insertions(+), 48 deletions(-) create mode 100644 x/move/keeper/binaries/submsg.mv create mode 100644 x/move/keeper/contracts/sources/Submsg.move diff --git a/Dockerfile b/Dockerfile index 45e94192..7310fbe9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ ARG TARGETARCH ARG GOARCH # See https://github.com/initia-labs/movevm/releases -ENV LIBMOVEVM_VERSION=v0.4.12 +ENV LIBMOVEVM_VERSION=v0.5.0 # Install necessary packages RUN set -eux; apk add --no-cache ca-certificates build-base git cmake diff --git a/app/upgrade.go b/app/upgrade.go index 8a4533ed..376d4f1b 100644 --- a/app/upgrade.go +++ b/app/upgrade.go @@ -2,19 +2,47 @@ package app import ( "context" + "encoding/base64" + "cosmossdk.io/errors" upgradetypes "cosmossdk.io/x/upgrade/types" "github.com/cosmos/cosmos-sdk/types/module" + + movetypes "github.com/initia-labs/initia/x/move/types" + vmtypes "github.com/initia-labs/movevm/types" ) -const upgradeName = "0.2.2" +const upgradeName = "0.5.4" // RegisterUpgradeHandlers returns upgrade handlers func (app *InitiaApp) RegisterUpgradeHandlers(cfg module.Configurator) { app.UpgradeKeeper.SetUpgradeHandler( upgradeName, func(ctx context.Context, _ upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { - return app.ModuleManager.RunMigrations(ctx, app.configurator, vm) + // diff: https://github.com/initia-labs/movevm/compare/v0.4.12...v0.5.0 + codes := []string{ + // cosmos.move + "oRzrCwYAAAALAQAQAhAaAyqXAQTBAQIFwwGQBAfTBZ4FCPEKIAaRCxoQqwt0Cp8MGgy5DPUJAAAACAAPABEAEgAZACgAMAABAwAABQMAAQcHAAIOBwEAAQMQCwAGJwgAAA0AAQAEEwIDAAEUBAUAABUGAQAAFgcBAAAXCAEAAAIBCgAAGAwKAAUaDQ0AARsEDgAAHAEKAAAdDAoAAB4QAQAAHxEBAAAgEgEAACEVAQAAIhcBAAAjGQEAACQaAQAAJRwBAAAmHgEAACkfAQAAKiEBAAArIgEAACwkAQAALSUBAAAuJwEAAS8TFAAHMSkTAQIAMisBABwoBAYMCAILAwEIBAMAAQYMAQUBBggCAQYKAgQFCgIGCwMBCAQDCgYMCAILAwEIBAMIAggCAwMDCAIKBQoCBgsDAQgEAwoCCgIDAwMKAgYKAgoCCgIGCwMBCAQKAgUBCAABAgIDCAIBAwEBAwMKAgEDBgwLAwEIBAMDBQYLAwEIBAMGBgwFCAIIAgoIAgoKAgEKAgEIAgcFBQoCCgIKCgIKCgIBDQYKCAIKCgIDAwoCCgIFBwoKAgYIAgoCAwoKAgEGBgwFCAIIAgoIAgoIAg8GCggCCgoCAwMKAgoCBQcKCgIGCAIKAgMKCgIKCgIKCgIBBAYMCgIKCAIKCgIFBQoCCgoCCgoCAQsGCggCCgoCAwMFBwoKAgYIAgoCAwoKAgEEBgwKAgoIAgoIAg0GCggCCgoCAwMFBwoKAgYIAgoCAwoKAgoKAgoKAgEKBgwIAgsDAQgFCggCCAIIAgMDAwgCCgUKAgYLAwEIBQoKAgoCCgIDAwMKAg4GCggCCgoCAwMGCwMBCAUKAgUHCgoCBggCCgIDCgoCCgIKAgkGDAgCCAILAwEIBAMLAwEIBAMLAwEIBAMJBQoCCgIGCwMBCAQDBgsDAQgEAwYLAwEIBAMGBgsDAQgEBgsDAQgEBgsDAQgECgIKAgUCBgwKAgMFCgIIAAIIAAUFBgwDCAIDCAIBCAEBBgkAAggBCgIDBgwKAggABmNvc21vcwdPcHRpb25zDWFsbG93X2ZhaWx1cmULY2FsbGJhY2tfaWQMY2FsbGJhY2tfZmlkC1ZvdGVSZXF1ZXN0Bl90eXBlXwZTdHJpbmcGc3RyaW5nC3Byb3Bvc2FsX2lkBXZvdGVyBm9wdGlvbghtZXRhZGF0YQhkZWxlZ2F0ZQZPYmplY3QGb2JqZWN0CE1ldGFkYXRhDmZ1bmdpYmxlX2Fzc2V0BnNpZ25lcgphZGRyZXNzX29mBWJ5dGVzEWRlbGVnYXRlX2ludGVybmFsCHRyYW5zZmVyEXRyYW5zZmVyX2ludGVybmFsG2FsbG93X2ZhaWx1cmVfd2l0aF9jYWxsYmFjawVlcnJvchBpbnZhbGlkX2FyZ3VtZW50CGlzX2VtcHR5EGRpc2FsbG93X2ZhaWx1cmUeZGlzYWxsb3dfZmFpbHVyZV93aXRoX2NhbGxiYWNrE2Z1bmRfY29tbXVuaXR5X3Bvb2wcZnVuZF9jb21tdW5pdHlfcG9vbF9pbnRlcm5hbAxtb3ZlX2V4ZWN1dGUVbW92ZV9leGVjdXRlX2ludGVybmFsFm1vdmVfZXhlY3V0ZV93aXRoX2pzb24LbW92ZV9zY3JpcHQUbW92ZV9zY3JpcHRfaW50ZXJuYWwVbW92ZV9zY3JpcHRfd2l0aF9qc29uDG5mdF90cmFuc2ZlcgpDb2xsZWN0aW9uCmNvbGxlY3Rpb24VbmZ0X3RyYW5zZmVyX2ludGVybmFsB3BheV9mZWUQcGF5X2ZlZV9pbnRlcm5hbAhzdGFyZ2F0ZRFzdGFyZ2F0ZV9pbnRlcm5hbA1zdGFyZ2F0ZV92b3RlBHV0ZjgEanNvbgdtYXJzaGFsFXN0YXJnYXRlX3dpdGhfb3B0aW9ucwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCgIXFi9jb3Ntb3MuZ292LnYxLk1zZ1ZvdGUUY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4wE2luaXRpYTo6bWV0YWRhdGFfdjBAAgEAAAAAAAAAFEVJTlZBTElEX0NBTExCQUNLX0lEAAIAAAAAAAAAFUVJTlZBTElEX0NBTExCQUNLX0ZJRAAAAAACAwIBAwMECgIBAgUGCAIJAwoIAgsDDAgCAAEEAAEJCwARAQ4BEQIUDgILAxEDAgQBBAAJGwsAEQEOARECFA4CDgQRAhQOBRECFA4JEQIUDAoMCwwMCwMLDAsLCwYLBwsICwoRBQIGAQAAAQUIBgAAAAAAAAAAQAsAAAAAAAAAABIAAgcBAAAPGAoABgAAAAAAAAAAJAQFBQgGAQAAAAAAAAARCCcOAREJAwwFDwYCAAAAAAAAABEIJwgOARECFAwDCwALAxIAAgMAAgAKAQAAAQUJBgAAAAAAAAAAQAsAAAAAAAAAABIAAgsBAAAPGAoABgAAAAAAAAAAJAQFBQgGAQAAAAAAAAARCCcOAREJAwwFDwYCAAAAAAAAABEIJwkOARECFAwDCwALAxIAAgwBBAABBgsAEQEOAQsCEQ0CDQACAA4BBAAWOQsAEQEOAhECFA4DEQIUDgQMBkATAAAAAAAAAAAMBwYAAAAAAAAAAAoGQRQMCAwJDAoMCwwMCgkKCCMEKAoGCglCFA0HDA0RAhQMDwsNCw9EEwsJBgEAAAAAAAAAFgwJBSsLBgEFLAUUCwcMEQkMEgsMCwELCwsKCxELBQsSEQ8CDwACABABBAAYXAsAEQEOAhECFA4DEQIUDgQMBkATAAAAAAAAAAAMBwYAAAAAAAAAAAoGQRQMCAwJDAoMCwwMCgkKCCMEKAoGCglCFA0HDA0RAhQMDwsNCw9EEwsJBgEAAAAAAAAAFgwJBSsLBgEFLAUUCwcMEQ4FDAZAEwAAAAAAAAAADBIGAAAAAAAAAAAKBkEUDAgMCQoJCggjBEsKBgoJQhQNEgwNEQIUDA8LDQsPRBMLCQYBAAAAAAAAABYMCQVOCwYBBU8FNwsSDBMIDBQLDAsBCwsLCgsRCxMLFBEPAhEBBAAbLwsAEQEOAgwEQBMAAAAAAAAAAAwFBgAAAAAAAAAACgRBFAwGDAcMCAoHCgYjBCAKBAoHQhQNBQwJEQIUDAsLCQsLRBMLBwYBAAAAAAAAABYMBwUjCwQBBSQFDAsFDA0JDA4LCAsBCw0LAwsOERICEgACABMBBAAdUgsAEQEOAgwEQBMAAAAAAAAAAAwFBgAAAAAAAAAACgRBFAwGDAcMCAoHCgYjBCAKBAoHQhQNBQwJEQIUDAsLCQsLRBMLBwYBAAAAAAAAABYMBwUjCwQBBSQFDAsFDA0OAwwEQBMAAAAAAAAAAAwOBgAAAAAAAAAACgRBFAwGDAcKBwoGIwRDCgQKB0IUDQ4MCRECFAwLCwkLC0QTCwcGAQAAAAAAAAAWDAcFRgsEAQVHBS8LDgwPCAwQCwgLAQsNCw8LEBESAhQBBAAgRAsAEQEOARECFA4CDgMMCkATAAAAAAAAAAAMCwYAAAAAAAAAAAoKQRQMDAwNDA4MDwwQCg0KDCMEJgoKCg1CFA0LDBERAhQMEwsRCxNEEwsNBgEAAAAAAAAAFgwNBSkLCgEFKgUSCwsMFQ4EEQIUDgURAhQOCRECFAwWDBcMEwsQCw8LDgsVCxMLFwsGCwcLCAsWERUCFQACABYBBAAjFAsAEQEOARECFA4CEQIUDgMOBQ4HDAkMCgsECwoLBgsJCwgRFwIXAAIAGAEEACYICwARAREKDAILAQsCERkCGQACABoBBAAqDwcAERsLAQsCCwMLBBIBDAUOBTgADAYLAAsGERgCHQEAAAEGCwARAQsBCwIRGQIFAAIAAA==", + // coin.move + "oRzrCwYAAAANAQAYAhhGA17pAgTHAyAF5wP4AgffBsIICKEPIAbBDzwQ/Q/jAgrgEjEMkRPmBg33GQwPgxoEAAAABAAGABYAGAAlADAAMgA3ADkASABRAAEGAAEDBwEAAQIFCwAABwABAAEACQYAAAsGAAAMCAACDgYAAhAGAAISBgAAEwYAAxUHAAIfAAAFJAcBAAABPwYAAUECAAAUAAEAAhQDAQEIABcFBAAEFwYEAQgAAgcAAAAZBwgAARoIAwEIABsAAQACGwMBAQgAHAAJAAIcAwkBCAAdCgsABB0MCwEIAB4NBAABIA4IAQgCHg8EAAAhEQQABCERBAAAIgoSAAQiDBIBCAAjABMAAiMDEwEIACYUFQACJhYVAAAnFwQABCYYBAAAKBEEAAQoEQQAACkZBAAAKhoEAAQpBgQBCAArABMAAisDEwEIACwbFQAELBwVAQgDLR0eAAEuHwgAAC8gIQAELyAhAAYxGggABzMLCwAANAEAAAM1HQsAAzYiAQAIOB0jAAk6IwgAADslBAAEPCYEAAA9KCkAAD4oKgABQCwtAARCLgQAAkMvMAACRC8xAAJFLzIAAUYvMwABRy8IAApJNQQBAgFKLwMBCAFLLzYAAEwIEgAATQcSAABOAAEAAU84EgEIA1AjAQALUjkjAQAIUx4BAANUOgQAAFUlBAABAgMCBgIIAgoCDAIOAhMCFQIeAiACIgI5NDoCPwJBCAELAQEIAgEICwEIAgELAQEJAAAEBgwFCwEBCAIDBAYMCwEBCQAFAwIFCAsBBQECAgULAQEIAgEDAgULAQEJAAIGCAAIDAEGCwEBCQACBggICAwCCwEBCAIFAgUIDAEBAQsNAQQCBggKAwEIDAIGCAcDAwYICgUDAwYIBwUDBQYMBgwFCwEBCAIDAQYMAwYMCwEBCAIDAwYMCwEBCQADAQYICwEGCgICBgUKAgMFCw0BBQICCgsBAQgCCgMDBggLAwMBCgIICgIICwEDBggLAwgLBQIGCAUFAwYICQUBBAsBAQgCBQEGCAkHBgwLDQEECAsICwIICwgLAwgKCAAIBQQICggACAUIDgMIBQgACAoCBgwKAgEIDwcGCA8LDQEECAsICwIICwgLAQYIDwEIBwEICAEICQEMAQgEAQkAAQgOCQoCCA8GCA8MCAkICAgHCAYLAQEIAgILAQEJAAUBBgkAAgcICwgLCQUFAQgLCAsICwgLCgIHCAsEY29pbg5CdXJuQ2FwYWJpbGl0eQhtZXRhZGF0YQZPYmplY3QGb2JqZWN0CE1ldGFkYXRhDmZ1bmdpYmxlX2Fzc2V0BENvaW4LZHVtbXlfZmllbGQQQ29pbkNyZWF0ZWRFdmVudA1tZXRhZGF0YV9hZGRyEEZyZWV6ZUNhcGFiaWxpdHkMTWFuYWdpbmdSZWZzCG1pbnRfcmVmB01pbnRSZWYIYnVybl9yZWYHQnVyblJlZgx0cmFuc2Zlcl9yZWYLVHJhbnNmZXJSZWYOTWludENhcGFiaWxpdHkEbmFtZQZTdHJpbmcGc3RyaW5nCHRyYW5zZmVyFnByaW1hcnlfZnVuZ2libGVfc3RvcmUQbWV0YWRhdGFfYWRkcmVzcxFhZGRyZXNzX3RvX29iamVjdAZzeW1ib2wIZGVjaW1hbHMHYmFsYW5jZQRidXJuDUZ1bmdpYmxlQXNzZXQOb2JqZWN0X2FkZHJlc3MHZGVwb3NpdAlpc19mcm96ZW4HbWF4aW11bQZPcHRpb24Gb3B0aW9uBG1pbnQHbWludF90bwxzdWRvX2RlcG9zaXQNc3Vkb190cmFuc2ZlcgpjaGVja19zdWRvBnN1cHBseQh3aXRoZHJhdwVieXRlcxVjcmVhdGVfb2JqZWN0X2FkZHJlc3MIYmFsYW5jZXMGc2lnbmVyCmFkZHJlc3Nfb2YFZXJyb3IRcGVybWlzc2lvbl9kZW5pZWQRZGVub21fdG9fbWV0YWRhdGEGbGVuZ3RoCnN1Yl9zdHJpbmcDaGV4DWRlY29kZV9zdHJpbmcIZnJvbV9iY3MKdG9fYWRkcmVzcxFmcmVlemVfY29pbl9zdG9yZQ9zZXRfZnJvemVuX2ZsYWcKaW5pdGlhbGl6ZSJpbml0aWFsaXplX2FuZF9nZW5lcmF0ZV9leHRlbmRfcmVmCUV4dGVuZFJlZhNjcmVhdGVfbmFtZWRfb2JqZWN0DkNvbnN0cnVjdG9yUmVmK2NyZWF0ZV9wcmltYXJ5X3N0b3JlX2VuYWJsZWRfZnVuZ2libGVfYXNzZXQRZ2VuZXJhdGVfbWludF9yZWYRZ2VuZXJhdGVfYnVybl9yZWYVZ2VuZXJhdGVfdHJhbnNmZXJfcmVmD2dlbmVyYXRlX3NpZ25lchxhZGRyZXNzX2Zyb21fY29uc3RydWN0b3JfcmVmBWV2ZW50BGVtaXQbb2JqZWN0X2Zyb21fY29uc3RydWN0b3JfcmVmE2dlbmVyYXRlX2V4dGVuZF9yZWYHaXNfY29pbhFpc19jb2luX2J5X3N5bWJvbBFtZXRhZGF0YV90b19kZW5vbQhpc19vd25lcgR1dGY4A2Jjcwh0b19ieXRlcxBlbmNvZGVfdG9fc3RyaW5nBmFwcGVuZBN1bmZyZWV6ZV9jb2luX3N0b3JlDG1hbmFnZWRfY29pbgdzdGFraW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCgIGBW1vdmUvCgIFBElOSVQKAgYFdWluaXQUY29tcGlsYXRpb25fbWV0YWRhdGEJAAMyLjADMi4wE2luaXRpYTo6bWV0YWRhdGFfdjCuAgIBAAAAAAAAAA1FVU5BVVRIT1JJWkVEAAIAAAAAAAAAG0VSUl9NQU5BR0lOR19SRUZTX05PVF9GT1VORBpNYW5hZ2luZ1JlZnMgaXMgbm90IGZvdW5kLgEQQ29pbkNyZWF0ZWRFdmVudAEEAA4EbmFtZQEBAAZzdXBwbHkBAQAGc3ltYm9sAQEAB2JhbGFuY2UBAQAHaXNfY29pbgEBAAdtYXhpbXVtAQEACGJhbGFuY2VzAQEACGRlY2ltYWxzAQEACG1ldGFkYXRhAQEACWlzX2Zyb3plbgEBABBtZXRhZGF0YV9hZGRyZXNzAQEAEWRlbm9tX3RvX21ldGFkYXRhAQEAEWlzX2NvaW5fYnlfc3ltYm9sAQEAEW1ldGFkYXRhX3RvX2Rlbm9tAQEAAAIBAgsBAQgCAwIBCAEEAgEKBQUCAQILAQEIAgYCAw0IBw8ICBEICQoCAQILAQEIAgABAAAEAwsAOAACAgEEAAQGCwALAgsBCwM4AQIEAQAABAULAAsBEQU4AgIHAQAABAMLADgDAgkBAAAEAwsAOAQCCwEAAAQECwALATgFAg0BAAEEEBMLABAAFAwCDgI4BgwDCgMpBAQLBQ0GAgAAAAAAAAAnCwMrBBABCwERDwIQAQAABAQLAAsBERECEgEAAAQECwALATgHAhQBAAAEAwsAOAgCFgEAAQQQEwsAEAIUDAIOAjgGDAMKAykEBAsFDQYCAAAAAAAAACcLAysEEAMLAREXAhgBAAEEEBQLABACFAwDDgM4BgwECgQpBAQLBQ0GAgAAAAAAAAAnCwQrBBADCwELAhEZAhoDAAAEBAsACwERGwIcAQQABAgLABEdCwELAwsCCwQ4CQIfAQAABAMLADgKAiEBAAAEBQsACwELAjgLAgUBAAAEBg4ADgERIxQRJAIlAQAABAULAAsBCwIRJgIdAAAABAoLABEnBwAhBAYFCQYBAAAAAAAAABEoJwIpAQAAJC4OABEqBgUAAAAAAAAAJAQSBwEMAQ4BDgAGAAAAAAAAAAAGBQAAAAAAAAARKwwCDgIRIyEMAwUUCQwDCwMEJw4AESoOAAYFAAAAAAAAAAwEDAUMBgsFCwQLBhErDAcOBxEsES0MCAUrBwALABEFDAgLCDgCAi4BAAEEJxQLABAEFAwCDgI4BgwDCgMpBAQLBQ0GAgAAAAAAAAAnCwMrBBAFCwEIES8CMAEAACsKCwALAQsCCwMLBAsFCwYRMQECMQEAADcyDgMRIxQMBwsACwcRMgwIDggMCQoJCwELAgsDCwQLBQsGETMKCRE0CgkRNQoJETYKCRE3DAoOCgwAEgQMDgsACw4tBAoJETgSAjgMCgk4DQwPCg8SBQoPEgALDxIDCwkROwI8AQAABAMLACkEAj0BAAAEBQsACwERBSkEAj4BAAA7Ng4AOAYMAQoAEQcLAAcAOA4MAwwECwMEFgoEDAUHAhFADAYLBQsGIQwDBRgJDAMLAwQeBwMRQAwEBR4HAAoEEQUKASEEJgsEAgcBEUAMBw4BOA8MCA4IEUINBwwJDAQLCQsEEUMLBwJEAQABBCcUCwAQBBQMAg4COAYMAwoDKQQECwUNBgIAAAAAAAAAJwsDKwQQBQsBCREvAgAABAEFAAQAAwAEAgBWAFcA", + } + + modules := make([]vmtypes.Module, len(codes)) + for i, code := range codes { + codeBz, err := base64.StdEncoding.DecodeString(code) + if err != nil { + return nil, errors.Wrap(err, "failed to decode module code") + } + + modules[i] = vmtypes.NewModule(codeBz) + } + + err := app.MoveKeeper.PublishModuleBundle(ctx, vmtypes.StdAddress, vmtypes.NewModuleBundle(modules...), movetypes.UpgradePolicy_COMPATIBLE) + if err != nil { + return nil, errors.Wrap(err, "failed to publish module bundle") + } + + return vm, nil }, ) } diff --git a/cmd/initiad/root.go b/cmd/initiad/root.go index 3b18d315..ef4c2d4a 100644 --- a/cmd/initiad/root.go +++ b/cmd/initiad/root.go @@ -193,7 +193,7 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig, b ) // add move commands - rootCmd.AddCommand(movecmd.MoveCommand(encodingConfig.InterfaceRegistry.SigningContext().AddressCodec())) + rootCmd.AddCommand(movecmd.MoveCommand(encodingConfig.InterfaceRegistry.SigningContext().AddressCodec(), false)) } func addModuleInitFlags(startCmd *cobra.Command) { diff --git a/cmd/move/move.go b/cmd/move/move.go index a0eca38d..51bb0d6f 100644 --- a/cmd/move/move.go +++ b/cmd/move/move.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path" + "runtime/debug" "strings" "cosmossdk.io/core/address" @@ -85,7 +86,7 @@ const ( defaultInstallDir = "." ) -func MoveCommand(ac address.Codec) *cobra.Command { +func MoveCommand(ac address.Codec, useMinlib bool) *cobra.Command { cmd := &cobra.Command{ Use: "move", Short: "move subcommands", @@ -98,7 +99,7 @@ func MoveCommand(ac address.Codec) *cobra.Command { moveBuildCmd(), moveTestCmd(), moveEncodeCmd(ac), - moveNewCmd(), + moveNewCmd(useMinlib), moveCleanCmd(), moveDeployCmd(ac), moveVerifyCmd(), @@ -307,7 +308,7 @@ func moveCoverageBytecodeCmd() *cobra.Command { return cmd } -func moveNewCmd() *cobra.Command { +func moveNewCmd(useMinlib bool) *cobra.Command { cmd := &cobra.Command{ Use: "new ", Short: "create a new move package", @@ -319,7 +320,17 @@ func moveNewCmd() *cobra.Command { return err } - _, err = api.CreateContractPackage(*arg, args[0]) + movevmVersion := "" + info, ok := debug.ReadBuildInfo() + if ok { + for _, dep := range info.Deps { + if dep.Path == "github.com/initia-labs/movevm" { + movevmVersion = dep.Version + } + } + } + + _, err = api.CreateContractPackage(*arg, args[0], movevmVersion, useMinlib) if err != nil { return err } diff --git a/go.mod b/go.mod index f9ed0a15..089f43b4 100644 --- a/go.mod +++ b/go.mod @@ -38,9 +38,9 @@ require ( github.com/gorilla/mux v1.8.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/hashicorp/go-metrics v0.5.3 - github.com/initia-labs/OPinit v0.5.2 + github.com/initia-labs/OPinit v0.5.3 // we also need to update `LIBMOVEVM_VERSION` of Dockerfile#9 - github.com/initia-labs/movevm v0.4.12 + github.com/initia-labs/movevm v0.5.0 github.com/noble-assets/forwarding/v2 v2.0.0-20240521090705-86712c4c9e43 github.com/pelletier/go-toml v1.9.5 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index a69917b9..d8488e41 100644 --- a/go.sum +++ b/go.sum @@ -726,14 +726,14 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/initia-labs/OPinit v0.5.2 h1:KEiC72KGBa+X5DDMRrzVJCqNEGi7KX5cOYH/zAoDaQk= -github.com/initia-labs/OPinit v0.5.2/go.mod h1:lx1amLMszculwPu8ln+btJno38UV28fd2nP7XC88ZeE= +github.com/initia-labs/OPinit v0.5.3 h1:DytQyPXs68L4yrBFeHz1TX4tiHsa4tqLTQBUMVgOx0o= +github.com/initia-labs/OPinit v0.5.3/go.mod h1:lx1amLMszculwPu8ln+btJno38UV28fd2nP7XC88ZeE= github.com/initia-labs/OPinit/api v0.5.1 h1:zwyJf7HtKJCKvLJ1R9PjVfJO1L+d/jKoeFyT7WTLHFI= github.com/initia-labs/OPinit/api v0.5.1/go.mod h1:gHK6DEWb3/DqQD5LjKirUx9jilAh2UioXanoQdgqVfU= github.com/initia-labs/cometbft v0.0.0-20240923045653-ba99eb347236 h1:+HmPQ1uptOe4r5oQHuHMG5zF1F3maNoEba5uiTUMnlk= github.com/initia-labs/cometbft v0.0.0-20240923045653-ba99eb347236/go.mod h1:GPHp3/pehPqgX1930HmK1BpBLZPxB75v/dZg8Viwy+o= -github.com/initia-labs/movevm v0.4.12 h1:P30q4U2jUN/al3bX391ZkXr3t59owNTwr9qmC4d1S0Q= -github.com/initia-labs/movevm v0.4.12/go.mod h1:aUWdvFZPdULjJ2McQTE+mLnfnG3CLAz0TWJRFzFFUwg= +github.com/initia-labs/movevm v0.5.0 h1:dBSxoVyUumSE4x6/ZSOWtvbtZpw+V4W25/NH6qLU0uQ= +github.com/initia-labs/movevm v0.5.0/go.mod h1:aUWdvFZPdULjJ2McQTE+mLnfnG3CLAz0TWJRFzFFUwg= github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= diff --git a/x/move/keeper/binaries/BasicCoin.mv b/x/move/keeper/binaries/BasicCoin.mv index 0199116a2597fcc913b913242add0b4f0f6a12d5..d751e983590e7a085496cc88b9de04a7f2cdd843 100644 GIT binary patch delta 12 TcmZo=ZDpNM%gD5`j-3er7$*Z= delta 12 TcmZo=ZDpNM%gDB|j-3er7&`-D diff --git a/x/move/keeper/binaries/Vesting.mv b/x/move/keeper/binaries/Vesting.mv index 91cb16fda570b8868b47f4dc7379a98cd5d5b3bb..b543592d767d0bde6b7f202fa4a8c31636869426 100644 GIT binary patch delta 18 ZcmZ1?wnS_~E+hBEyhV&mn*|w#xd1sS1q1*9 delta 18 ZcmZ1?wnS_~E+fapyhV&`n*|w#xd1sJ1qA>A diff --git a/x/move/keeper/binaries/submsg.mv b/x/move/keeper/binaries/submsg.mv new file mode 100644 index 0000000000000000000000000000000000000000..e909391861142094b513e1a404cfd3c41f8e176d GIT binary patch literal 630 zcmaJ5Ur~InAz@8XVyp{5$_=&9>tRof=3}9ava*3cGI{!Bhx*4&p*ju@NaqZ z9!QO=q7b$Z-BqvNtAcv{XaB)!05AxKOesEnk>8{`JIuzvm_O2Kc`r`QqbQ5t@(chG z2?a_}1fU7zECVbB06zdZ@nr;p*p>=tC!5&S%mB_U0`77owakSsm_q`UE)2J0nJ!Ra zjyMC%xxz>;m}ZE{alBl`g>L$|>Z9_vzDqiWMdt?{(-69a{o&)dOy8%<-kbPmNWU(g zh#wlaTwc27y1rwqUaLR81N$*O, + allow_failure: bool, + id: u64, // callback id + fid: String, // function id + ) { + if (allow_failure) { + cosmos::stargate_with_options(account, data, cosmos::allow_failure_with_callback(id, fid)); + } else { + cosmos::stargate_with_options(account, data, cosmos::disallow_failure_with_callback(id, fid)); + } + } + + #[event] + struct ResultEvent has drop { + id: u64, + success: bool, + } + + #[event] + struct ResultEventWithSigner has drop { + account: address, + id: u64, + success: bool, + } + + public entry fun callback_with_signer( + account: &signer, + id: u64, + success: bool, + ) { + event::emit(ResultEventWithSigner { account: signer::address_of(account), id, success }); + + } + + public entry fun callback_without_signer( + id: u64, + success: bool, + ) { + event::emit(ResultEvent { id, success }); + } +} \ No newline at end of file diff --git a/x/move/keeper/handler.go b/x/move/keeper/handler.go index 69c01380..61bcde79 100644 --- a/x/move/keeper/handler.go +++ b/x/move/keeper/handler.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "encoding/json" "errors" + "fmt" "strings" "unsafe" @@ -413,44 +414,115 @@ func (k Keeper) handleExecuteResponse( func (k Keeper) DispatchMessages(ctx context.Context, messages []vmtypes.CosmosMessage) error { sdkCtx := sdk.UnwrapSDKContext(ctx) for _, message := range messages { - var msg proto.Message - var err error - if stargateMsg, ok := message.(*vmtypes.CosmosMessage__Stargate); ok { - msg, err = k.HandleVMStargateMsg(ctx, &stargateMsg.Value) - if err != nil { - return err + err := k.dispatchMessage(sdkCtx, message) + if err != nil { + return err + } + } + + return nil +} + +func (k Keeper) dispatchMessage(parentCtx sdk.Context, message vmtypes.CosmosMessage) (err error) { + var allowFailure bool + var callback *vmtypes.StargateCallback + var callbackSender vmtypes.AccountAddress + + ctx, commit := parentCtx.CacheContext() + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("panic: %v", r) + } + + success := err == nil + + // create submsg event + event := sdk.NewEvent( + types.EventTypeSubmsg, + sdk.NewAttribute(types.AttributeKeySuccess, fmt.Sprintf("%v", success)), + ) + + if !success { + // return error if failed and not allowed to fail + if !allowFailure { + return } + + // emit failed reason event if failed and allowed to fail + event.AppendAttributes(sdk.NewAttribute(types.AttributeKeyReason, err.Error())) } else { - msg, err = types.ConvertToSDKMessage(ctx, NewMoveBankKeeper(&k), NewNftKeeper(&k), message, k.ac, k.vc) - if err != nil { - return err - } + // commit if success + commit() } - // validate msg - if msg, ok := msg.(sdk.HasValidateBasic); ok { - if err := msg.ValidateBasic(); err != nil { - return err - } + // reset error because it's allowed to fail + err = nil + + // emit submessage event + parentCtx.EventManager().EmitEvent(event) + + // if callback exists, execute it with parent context becuase it's already committed + if callback != nil { + err = k.ExecuteEntryFunctionJSON( + parentCtx, + callbackSender, + callback.ModuleAddress, + callback.ModuleName, + callback.FunctionName, + []vmtypes.TypeTag{}, + []string{ + fmt.Sprintf("\"%d\"", callback.Id), + fmt.Sprintf("%v", success), + }, + ) } + }() - // find the handler - handler := k.msgRouter.Handler(msg) - if handler == nil { - return types.ErrNotSupportedCosmosMessage + var msg proto.Message + if stargateMsg, ok := message.(*vmtypes.CosmosMessage__Stargate); ok { + // validate basic & signer check is done in HandleVMStargateMsg + msg, err = k.HandleVMStargateMsg(ctx, &stargateMsg.Value) + if err != nil { + return } - // and execute it - res, err := handler(sdkCtx, msg) + // callback only exists in stargate message + allowFailure = stargateMsg.Value.AllowFailure + callback = stargateMsg.Value.Callback + callbackSender = stargateMsg.Value.Sender + } else { + // signer check had been done in moveVM + msg, err = types.ConvertToSDKMessage(ctx, NewMoveBankKeeper(&k), NewNftKeeper(&k), message, k.ac, k.vc) if err != nil { - return err + return + } + + // conduct validate basic + if msg, ok := msg.(sdk.HasValidateBasic); ok { + err = msg.ValidateBasic() + if err != nil { + return + } } + } - // emit events - sdkCtx.EventManager().EmitEvents(res.GetEvents()) + // find the handler + handler := k.msgRouter.Handler(msg) + if handler == nil { + err = types.ErrNotSupportedCosmosMessage + return } - return nil + // and execute it + res, err := handler(ctx, msg) + if err != nil { + return + } + + // emit events + ctx.EventManager().EmitEvents(res.GetEvents()) + + return } // DistributeContractSharedRevenue distribute a portion of gas fee to contract creator account diff --git a/x/move/keeper/handler_test.go b/x/move/keeper/handler_test.go index 3f79910d..3a023cfd 100644 --- a/x/move/keeper/handler_test.go +++ b/x/move/keeper/handler_test.go @@ -166,7 +166,7 @@ func TestDispatchDelegateMessage(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("delegate", sdk.NewAttribute("delegator_address", delegator.String()), @@ -200,7 +200,7 @@ func TestDispatchFundCommunityPoolMessage(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("fund_community_pool", sdk.NewAttribute("depositor_address", depositor.String()), @@ -269,7 +269,7 @@ func TestDispatchTransferMessage(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("transfer", sdk.NewAttribute("sender", sender.String()), @@ -336,7 +336,7 @@ func TestDispatchPayFeeMessage(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("pay_fee", sdk.NewAttribute("signer", sender.String()), @@ -387,7 +387,7 @@ func TestDispatchFundMoveExecute(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("move_execute", sdk.NewAttribute("sender", sender.String()), @@ -437,7 +437,7 @@ func TestDispatchFundMoveExecuteWithJson(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("move_execute_with_json", sdk.NewAttribute("sender", sender.String()), @@ -480,7 +480,7 @@ func TestDispatchFundMoveScript(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("move_script", sdk.NewAttribute("sender", sender.String()), @@ -521,7 +521,7 @@ func TestDispatchFundMoveScriptWithJson(t *testing.T) { require.NoError(t, err) events := ctx.EventManager().Events() - event := events[len(events)-1] + event := events[len(events)-2] require.Equal(t, sdk.NewEvent("move_script_with_json", sdk.NewAttribute("sender", sender.String()), @@ -581,3 +581,120 @@ func Test_ContractSharedRevenue(t *testing.T) { require.Equal(t, math.ZeroInt(), input.BankKeeper.GetBalance(ctx, types.ConvertVMAddressToSDKAddress(stdAddr), bondDenom).Amount) require.Equal(t, revenueRatio.MulInt64(200).TruncateInt(), input.BankKeeper.GetBalance(ctx, types.ConvertVMAddressToSDKAddress(twoAddr), bondDenom).Amount) } + +func TestSubmsgCallback(t *testing.T) { + ctx, input := createDefaultTestInput(t) + + err := input.MoveKeeper.PublishModuleBundle(ctx, vmtypes.TestAddress, vmtypes.NewModuleBundle(vmtypes.NewModule(submsgModule)), types.UpgradePolicy_COMPATIBLE) + require.NoError(t, err) + + sender := addrs[0] + senderAddr, err := vmtypes.NewAccountAddressFromBytes(sender) + require.NoError(t, err) + + // submsg bytes + msg := types.NewMsgExecuteJSON( + sender.String(), + vmtypes.StdAddress.String(), + "module_name", + "fail", + []string{"type_arg1", "type_arg2"}, + []string{"\"arg1\"", "\"arg2\""}, + ) + msgData, err := input.EncodingConfig.Codec.MarshalInterfaceJSON(msg) + require.NoError(t, err) + + // 1. callback without signer + err = input.MoveKeeper.ExecuteEntryFunctionJSON(ctx, senderAddr, vmtypes.TestAddress, + "submsg", + "stargate", + []vmtypes.TypeTag{}, + []string{ + fmt.Sprintf("\"%s\"", hex.EncodeToString(msgData)), + "true", + "\"123\"", + fmt.Sprintf("\"%s::submsg::callback_without_signer\"", vmtypes.TestAddress), + }) + require.NoError(t, err) + + events := ctx.EventManager().Events() + event := events[len(events)-1] + + require.Equal(t, sdk.NewEvent("move", + sdk.NewAttribute("type_tag", "0x2::submsg::ResultEvent"), + sdk.NewAttribute("data", "{\"id\":\"123\",\"success\":false}"), + ), event) + + // events should not be committed + for _, e := range events { + require.NotEqual(t, e.Type, "move_execute_with_json") + } + + // 2. callback with signer + err = input.MoveKeeper.ExecuteEntryFunctionJSON(ctx, senderAddr, vmtypes.TestAddress, + "submsg", + "stargate", + []vmtypes.TypeTag{}, + []string{ + fmt.Sprintf("\"%s\"", hex.EncodeToString(msgData)), + "true", + "\"234\"", + fmt.Sprintf("\"%s::submsg::callback_with_signer\"", vmtypes.TestAddress), + }) + require.NoError(t, err) + + events = ctx.EventManager().Events() + event = events[len(events)-1] + + require.Equal(t, sdk.NewEvent("move", + sdk.NewAttribute("type_tag", "0x2::submsg::ResultEventWithSigner"), + sdk.NewAttribute("data", fmt.Sprintf("{\"account\":\"%s\",\"id\":\"234\",\"success\":false}", senderAddr)), + ), event) + + // events should not be committed + for _, e := range events { + require.NotEqual(t, e.Type, "move_execute_with_json") + } + + // 3. success case + msg = types.NewMsgExecuteJSON( + sender.String(), + vmtypes.StdAddress.String(), + "module_name", + "function_name", + []string{"type_arg1", "type_arg2"}, + []string{"\"arg1\"", "\"arg2\""}, + ) + msgData, err = input.EncodingConfig.Codec.MarshalInterfaceJSON(msg) + require.NoError(t, err) + + err = input.MoveKeeper.ExecuteEntryFunctionJSON(ctx, senderAddr, vmtypes.TestAddress, + "submsg", + "stargate", + []vmtypes.TypeTag{}, + []string{ + fmt.Sprintf("\"%s\"", hex.EncodeToString(msgData)), + "true", + "\"345\"", + fmt.Sprintf("\"%s::submsg::callback_with_signer\"", vmtypes.TestAddress), + }) + require.NoError(t, err) + + events = ctx.EventManager().Events() + event = events[len(events)-1] + + require.Equal(t, sdk.NewEvent("move", + sdk.NewAttribute("type_tag", "0x2::submsg::ResultEventWithSigner"), + sdk.NewAttribute("data", fmt.Sprintf("{\"account\":\"%s\",\"id\":\"345\",\"success\":true}", senderAddr)), + ), event) + + // events should be committed + var found bool + for _, e := range events { + if e.Type == "move_execute_with_json" { + found = true + break + } + } + require.True(t, found) +} diff --git a/x/move/types/events.go b/x/move/types/events.go index b3938b3b..b890c808 100644 --- a/x/move/types/events.go +++ b/x/move/types/events.go @@ -9,6 +9,7 @@ const ( EventTypeMove = "move" EventTypeUpgradePolicy = "upgrade_policy" EventTypeContractSharedRevenue = "contract_shared_revenue" + EventTypeSubmsg = "submsg" AttributeKeySender = "sender" AttributeKeyModuleAddr = "module_addr" @@ -24,4 +25,8 @@ const ( // upgrade policy attributes AttributeKeyOriginPolicy = "origin_policy" AttributeKeyNewPolicy = "new_policy" + + // submessage event attributes + AttributeKeySuccess = "success" + AttributeKeyReason = "reason" ) diff --git a/x/move/types/params.go b/x/move/types/params.go index ac6c7c5f..92148113 100644 --- a/x/move/types/params.go +++ b/x/move/types/params.go @@ -20,7 +20,7 @@ const ( var ( DefaultBaseMinGasPrice = math.LegacyNewDecWithPrec(15, 2) // 0.15 - DefaultContractSharedRevenueRatio = math.LegacyNewDecWithPrec(50, 2) // 0.5 + DefaultContractSharedRevenueRatio = math.LegacyZeroDec() ) const (