diff --git a/Makefile b/Makefile index ae685268..ddc23c44 100644 --- a/Makefile +++ b/Makefile @@ -158,6 +158,10 @@ substrate-start-bob: --rpc-port 9946 \ --validator +start-network-aura: + cd ../../../..; \ + WASMTIME_BACKTRACE_DETAILS=1 RUST_LOG=runtime=trace ./target/release/node-template --dev --execution=wasm + start-network-babe: cd polkadot-sdk/substrate/bin/node/cli; \ cargo build --release; \ diff --git a/api/account_nonce/module.go b/api/account_nonce/module.go index 53cf7e8c..6609b119 100644 --- a/api/account_nonce/module.go +++ b/api/account_nonce/module.go @@ -24,10 +24,10 @@ const ( type Module struct { systemModule system.Module memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(systemModule system.Module, logger log.Logger) Module { +func New(systemModule system.Module, logger log.RuntimeLogger) Module { return Module{ systemModule: systemModule, memUtils: utils.NewMemoryTranslator(), diff --git a/api/aura/module.go b/api/aura/module.go index 99f2c393..dccfb2a7 100644 --- a/api/aura/module.go +++ b/api/aura/module.go @@ -22,10 +22,10 @@ const ( type Module struct { aura aura.AuraModule memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(aura aura.AuraModule, logger log.Logger) Module { +func New(aura aura.AuraModule, logger log.RuntimeLogger) Module { return Module{ aura: aura, memUtils: utils.NewMemoryTranslator(), diff --git a/api/babe/module.go b/api/babe/module.go index 2fcb3606..174f2be8 100644 --- a/api/babe/module.go +++ b/api/babe/module.go @@ -22,10 +22,10 @@ const ( type Module struct { babe babe.Module memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(babe babe.Module, logger log.Logger) Module { +func New(babe babe.Module, logger log.RuntimeLogger) Module { return Module{ babe: babe, memUtils: utils.NewMemoryTranslator(), diff --git a/api/benchmarking/module.go b/api/benchmarking/module.go index ba61d187..68319344 100644 --- a/api/benchmarking/module.go +++ b/api/benchmarking/module.go @@ -2,6 +2,7 @@ package benchmarking import ( "bytes" + sc "github.com/LimeChain/goscale" "github.com/LimeChain/gosemble/execution/types" "github.com/LimeChain/gosemble/frame/support" @@ -24,10 +25,10 @@ type Module struct { decoder types.RuntimeDecoder memUtils utils.WasmMemoryTranslator hashing io.Hashing - logger log.Logger + logger log.RuntimeLogger } -func New(systemIndex sc.U8, modules []primitives.Module, decoder types.RuntimeDecoder, logger log.Logger) Module { +func New(systemIndex sc.U8, modules []primitives.Module, decoder types.RuntimeDecoder, logger log.RuntimeLogger) Module { systemModule := primitives.MustGetModule(systemIndex, modules).(system.Module) return Module{ @@ -161,7 +162,7 @@ func (m Module) BenchmarkHook(dataPtr int32, dataLen int32) int64 { return m.memUtils.BytesToOffsetAndSize(benchmarkResult.Bytes()) } -func measureHooks(modules []primitives.Module, hookFn func(module primitives.DispatchModule) error, logger log.Logger) float64 { +func measureHooks(modules []primitives.Module, hookFn func(module primitives.DispatchModule) error, logger log.RuntimeLogger) float64 { var start, end int64 for _, module := range modules { diff --git a/api/block_builder/module.go b/api/block_builder/module.go index 16aa892b..54bc10af 100644 --- a/api/block_builder/module.go +++ b/api/block_builder/module.go @@ -36,10 +36,10 @@ type Module struct { decoder types.RuntimeDecoder memUtils utils.WasmMemoryTranslator mdGenerator *primitives.MetadataTypeGenerator - logger log.Logger + logger log.RuntimeLogger } -func New(runtimeExtrinsic extrinsic.RuntimeExtrinsic, executive executive.Module, decoder types.RuntimeDecoder, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(runtimeExtrinsic extrinsic.RuntimeExtrinsic, executive executive.Module, decoder types.RuntimeDecoder, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { return Module{ runtimeExtrinsic: runtimeExtrinsic, executive: executive, @@ -80,16 +80,17 @@ func (m Module) ApplyExtrinsic(dataPtr int32, dataLen int32) int64 { } err = m.executive.ApplyExtrinsic(uxt) + var applyExtrinsicResult primitives.ApplyExtrinsicResult switch typedErr := err.(type) { + case nil: + dispatchOutcome := primitives.DispatchOutcome(sc.NewVaryingData(sc.Empty{})) + applyExtrinsicResult, err = primitives.NewApplyExtrinsicResult(dispatchOutcome) case primitives.TransactionValidityError: applyExtrinsicResult, err = primitives.NewApplyExtrinsicResult(typedErr) case primitives.DispatchError: dispatchOutcome := primitives.DispatchOutcome(sc.NewVaryingData(typedErr)) applyExtrinsicResult, err = primitives.NewApplyExtrinsicResult(dispatchOutcome) - case nil: - dispatchOutcome := primitives.DispatchOutcome(sc.NewVaryingData(sc.Empty{})) - applyExtrinsicResult, err = primitives.NewApplyExtrinsicResult(dispatchOutcome) } if err != nil { m.logger.Critical(err.Error()) diff --git a/api/core/module.go b/api/core/module.go index c6227171..d2c38725 100644 --- a/api/core/module.go +++ b/api/core/module.go @@ -34,10 +34,10 @@ type Module struct { runtimeVersion *primitives.RuntimeVersion memUtils utils.WasmMemoryTranslator mdGenerator *primitives.MetadataTypeGenerator - logger log.Logger + logger log.RuntimeLogger } -func New(module executive.Module, decoder types.RuntimeDecoder, runtimeVersion *primitives.RuntimeVersion, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(module executive.Module, decoder types.RuntimeDecoder, runtimeVersion *primitives.RuntimeVersion, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { return Module{ executive: module, decoder: decoder, diff --git a/api/genesis_builder/module.go b/api/genesis_builder/module.go index 85700cb0..1c72f16e 100644 --- a/api/genesis_builder/module.go +++ b/api/genesis_builder/module.go @@ -29,10 +29,10 @@ type GenesisBuilder interface { type Module struct { modules []primitives.Module memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(modules []primitives.Module, logger log.Logger) Module { +func New(modules []primitives.Module, logger log.RuntimeLogger) Module { return Module{ modules: modules, memUtils: utils.NewMemoryTranslator(), diff --git a/api/grandpa/module.go b/api/grandpa/module.go index dc94eced..74da8f7e 100644 --- a/api/grandpa/module.go +++ b/api/grandpa/module.go @@ -26,10 +26,10 @@ const ( type Module struct { grandpa grandpa.Module memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(grandpa grandpa.Module, logger log.Logger) Module { +func New(grandpa grandpa.Module, logger log.RuntimeLogger) Module { return Module{ grandpa: grandpa, memUtils: utils.NewMemoryTranslator(), diff --git a/api/metadata/module.go b/api/metadata/module.go index abbfe206..d9f4b766 100644 --- a/api/metadata/module.go +++ b/api/metadata/module.go @@ -36,10 +36,10 @@ type Module struct { runtimeExtrinsic extrinsic.RuntimeExtrinsic memUtils utils.WasmMemoryTranslator generator *primitives.MetadataTypeGenerator - logger log.Logger + logger log.RuntimeLogger } -func New(runtimeExtrinsic extrinsic.RuntimeExtrinsic, runtimeApiModules []primitives.RuntimeApiModule, logger log.Logger, generator *primitives.MetadataTypeGenerator) Module { +func New(runtimeExtrinsic extrinsic.RuntimeExtrinsic, runtimeApiModules []primitives.RuntimeApiModule, logger log.RuntimeLogger, generator *primitives.MetadataTypeGenerator) Module { return Module{ runtimeApiModules: runtimeApiModules, runtimeExtrinsic: runtimeExtrinsic, diff --git a/api/offchain_worker/module.go b/api/offchain_worker/module.go index c49b3efd..2fdb6b09 100644 --- a/api/offchain_worker/module.go +++ b/api/offchain_worker/module.go @@ -25,10 +25,10 @@ const ( type Module struct { executive executive.Module memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(executive executive.Module, logger log.Logger) Module { +func New(executive executive.Module, logger log.RuntimeLogger) Module { return Module{ executive: executive, memUtils: utils.NewMemoryTranslator(), diff --git a/api/session_keys/module.go b/api/session_keys/module.go index 30e7ecae..bdcde2fd 100644 --- a/api/session_keys/module.go +++ b/api/session_keys/module.go @@ -25,10 +25,10 @@ type Module struct { sessions []types.Session crypto io.Crypto memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(sessions []types.Session, logger log.Logger) Module { +func New(sessions []types.Session, logger log.RuntimeLogger) Module { return Module{ sessions: sessions, crypto: io.NewCrypto(), diff --git a/api/tagged_transaction_queue/module.go b/api/tagged_transaction_queue/module.go index 06361080..b65362bb 100644 --- a/api/tagged_transaction_queue/module.go +++ b/api/tagged_transaction_queue/module.go @@ -31,10 +31,10 @@ type Module struct { decoder types.RuntimeDecoder memUtils utils.WasmMemoryTranslator mdGenerator *primitives.MetadataTypeGenerator - logger log.Logger + logger log.RuntimeLogger } -func New(executive executive.Module, decoder types.RuntimeDecoder, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(executive executive.Module, decoder types.RuntimeDecoder, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { return Module{ executive: executive, decoder: decoder, diff --git a/api/transaction_payment/module.go b/api/transaction_payment/module.go index 62c49b85..508d2ec8 100644 --- a/api/transaction_payment/module.go +++ b/api/transaction_payment/module.go @@ -28,10 +28,10 @@ type Module struct { decoder types.RuntimeDecoder txPayments transaction_payment.Module memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(decoder types.RuntimeDecoder, txPayments transaction_payment.Module, logger log.Logger) Module { +func New(decoder types.RuntimeDecoder, txPayments transaction_payment.Module, logger log.RuntimeLogger) Module { return Module{ decoder: decoder, txPayments: txPayments, diff --git a/api/transaction_payment_call/module.go b/api/transaction_payment_call/module.go index 6975de4d..bccdc28e 100644 --- a/api/transaction_payment_call/module.go +++ b/api/transaction_payment_call/module.go @@ -27,10 +27,10 @@ type Module struct { decoder types.RuntimeDecoder txPayments transaction_payment.Module memUtils utils.WasmMemoryTranslator - logger log.Logger + logger log.RuntimeLogger } -func New(decoder types.RuntimeDecoder, txPayments transaction_payment.Module, logger log.Logger) Module { +func New(decoder types.RuntimeDecoder, txPayments transaction_payment.Module, logger log.RuntimeLogger) Module { return Module{ decoder: decoder, txPayments: txPayments, diff --git a/build/runtime-benchmarks.wasm b/build/runtime-benchmarks.wasm index 11a571cd..a6a1ff51 100755 Binary files a/build/runtime-benchmarks.wasm and b/build/runtime-benchmarks.wasm differ diff --git a/build/runtime.wasm b/build/runtime.wasm index e7fb5377..07d6c436 100755 Binary files a/build/runtime.wasm and b/build/runtime.wasm differ diff --git a/docs/docs/development/test.md b/docs/docs/development/test.md index 444c3e51..fe2ce8a9 100644 --- a/docs/docs/development/test.md +++ b/docs/docs/development/test.md @@ -8,6 +8,14 @@ permalink: /development/test Currently, the project contains unit and integration tests. Integration tests use [Gossamer](https://github.com/LimeChain/gossamer), which imports all the necessary Host functions and interacts with the Runtime. +Before running the tests, make sure to build the runtime with the benchmarking features enabled, as there are some tests that rely on them. + +````bash +make build-benchmarking +```` + +And then run the tests with: + ```bash make test ``` diff --git a/execution/extrinsic/runtime_extrinsic.go b/execution/extrinsic/runtime_extrinsic.go index 435a1800..68ca8266 100644 --- a/execution/extrinsic/runtime_extrinsic.go +++ b/execution/extrinsic/runtime_extrinsic.go @@ -26,10 +26,10 @@ type runtimeExtrinsic struct { modules []primitives.Module extra primitives.SignedExtra mdGenerator *primitives.MetadataTypeGenerator - logger log.DebugLogger + logger log.RuntimeLogger } -func New(modules []primitives.Module, extra primitives.SignedExtra, mdGenerator *primitives.MetadataTypeGenerator, logger log.DebugLogger) RuntimeExtrinsic { +func New(modules []primitives.Module, extra primitives.SignedExtra, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) RuntimeExtrinsic { return runtimeExtrinsic{ modules: modules, extra: extra, diff --git a/execution/types/checked_extrinsic.go b/execution/types/checked_extrinsic.go index 7dd8c1b5..02c0f454 100644 --- a/execution/types/checked_extrinsic.go +++ b/execution/types/checked_extrinsic.go @@ -19,7 +19,7 @@ type checkedExtrinsic struct { transactional support.Transactional[primitives.PostDispatchInfo] } -func NewCheckedExtrinsic(signer sc.Option[primitives.AccountId], function primitives.Call, extra primitives.SignedExtra, logger log.WarnLogger) primitives.CheckedExtrinsic { +func NewCheckedExtrinsic(signer sc.Option[primitives.AccountId], function primitives.Call, extra primitives.SignedExtra, logger log.RuntimeLogger) primitives.CheckedExtrinsic { return checkedExtrinsic{ signer: signer, function: function, @@ -67,12 +67,12 @@ func (c checkedExtrinsic) Apply(validator primitives.UnsignedValidator, info *pr maybeWho, maybePre = sc.NewOption[primitives.AccountId](nil), sc.NewOption[sc.Sequence[primitives.Pre]](nil) } + // TODO: revise if the error handling is correct postInfo, err := c.transactional.WithStorageLayer( func() (primitives.PostDispatchInfo, error) { return c.dispatch(maybeWho) }, ) - // TODO: handle error if err := c.extra.PostDispatch(maybePre, info, &postInfo, length, err); err != nil { return primitives.PostDispatchInfo{}, err diff --git a/execution/types/runtime_api.go b/execution/types/runtime_api.go index ab66eaf2..a5369de9 100644 --- a/execution/types/runtime_api.go +++ b/execution/types/runtime_api.go @@ -8,10 +8,10 @@ import ( type RuntimeApi struct { apis []primitives.ApiModule - logger log.Logger + logger log.RuntimeLogger } -func NewRuntimeApi(apis []primitives.ApiModule, logger log.Logger) RuntimeApi { +func NewRuntimeApi(apis []primitives.ApiModule, logger log.RuntimeLogger) RuntimeApi { return RuntimeApi{apis: apis, logger: logger} } diff --git a/execution/types/runtime_api_test.go b/execution/types/runtime_api_test.go index 95e1cd49..69310d0d 100644 --- a/execution/types/runtime_api_test.go +++ b/execution/types/runtime_api_test.go @@ -31,11 +31,13 @@ var ( func Test_RuntimeApi_New(t *testing.T) { target := setupRuntimeApi() + expect := RuntimeApi{ apis: []primitives.ApiModule{ mockApiModuleOne, mockApiModuleTwo, }, + logger: logger, } assert.Equal(t, expect, target) diff --git a/execution/types/runtime_decoder.go b/execution/types/runtime_decoder.go index 2f5bba72..8a9b7224 100644 --- a/execution/types/runtime_decoder.go +++ b/execution/types/runtime_decoder.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + sc "github.com/LimeChain/goscale" "github.com/LimeChain/gosemble/primitives/log" "github.com/LimeChain/gosemble/primitives/types" @@ -29,10 +30,10 @@ type runtimeDecoder struct { modules []types.Module extra primitives.SignedExtra sudoIndex sc.U8 // Used for additional decoding related to Sudo calls. Default is 0 and not considered a valid sudo index. - logger log.WarnLogger + logger log.RuntimeLogger } -func NewRuntimeDecoder(modules []types.Module, extra primitives.SignedExtra, sudoIndex sc.U8, logger log.WarnLogger) RuntimeDecoder { +func NewRuntimeDecoder(modules []types.Module, extra primitives.SignedExtra, sudoIndex sc.U8, logger log.RuntimeLogger) RuntimeDecoder { return runtimeDecoder{ modules: modules, extra: extra, diff --git a/execution/types/unchecked_extrinsic.go b/execution/types/unchecked_extrinsic.go index df7ac4cf..9091081d 100644 --- a/execution/types/unchecked_extrinsic.go +++ b/execution/types/unchecked_extrinsic.go @@ -41,11 +41,11 @@ type uncheckedExtrinsic struct { initializePayload PayloadInitializer crypto io.Crypto hashing io.Hashing - logger log.WarnLogger + logger log.RuntimeLogger } // NewUncheckedExtrinsic returns a new instance of an unchecked extrinsic. -func NewUncheckedExtrinsic(version sc.U8, signature sc.Option[primitives.ExtrinsicSignature], function primitives.Call, extra primitives.SignedExtra, logger log.WarnLogger) primitives.UncheckedExtrinsic { +func NewUncheckedExtrinsic(version sc.U8, signature sc.Option[primitives.ExtrinsicSignature], function primitives.Call, extra primitives.SignedExtra, logger log.RuntimeLogger) primitives.UncheckedExtrinsic { return uncheckedExtrinsic{ version: version, signature: signature, diff --git a/frame/aura/module.go b/frame/aura/module.go index 856c4893..5a373190 100644 --- a/frame/aura/module.go +++ b/frame/aura/module.go @@ -50,10 +50,10 @@ type Module struct { mdGenerator *primitives.MetadataTypeGenerator logDepositor system.LogDepositor disabledValidators primitives.DisabledValidators - logger log.Logger + logger log.RuntimeLogger } -func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { storage := newStorage() return Module{ diff --git a/frame/authorship/module.go b/frame/authorship/module.go index 53955499..92927c54 100644 --- a/frame/authorship/module.go +++ b/frame/authorship/module.go @@ -28,10 +28,10 @@ type module struct { functions map[sc.U8]primitives.Call systemModule system.Module mdGenerator *primitives.MetadataTypeGenerator - logger log.Logger + logger log.RuntimeLogger } -func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { storage := newStorage() return module{ diff --git a/frame/babe/call_plan_config_change.go b/frame/babe/call_plan_config_change.go index 97619f4e..b890f3b4 100644 --- a/frame/babe/call_plan_config_change.go +++ b/frame/babe/call_plan_config_change.go @@ -6,6 +6,7 @@ import ( sc "github.com/LimeChain/goscale" "github.com/LimeChain/gosemble/frame/support" + "github.com/LimeChain/gosemble/frame/system" babetypes "github.com/LimeChain/gosemble/primitives/babe" primitives "github.com/LimeChain/gosemble/primitives/types" ) @@ -80,12 +81,10 @@ func (_ callPlanConfigChange) PaysFee(baseWeight primitives.Weight) primitives.P } func (c callPlanConfigChange) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return primitives.PostDispatchInfo{}, err - // } + err := system.EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } config := args[0].(NextConfigDescriptor) diff --git a/frame/babe/call_plan_config_change_test.go b/frame/babe/call_plan_config_change_test.go index cc8cca2d..bc45d344 100644 --- a/frame/babe/call_plan_config_change_test.go +++ b/frame/babe/call_plan_config_change_test.go @@ -160,6 +160,18 @@ func Test_Call_PlanConfigChange_Dispatch(t *testing.T) { mockStoragePendingEpochConfigChange.AssertCalled(t, "Put", nextConfig) } +func Test_Call_PlanConfigChange_Dispatch_BadOrigin(t *testing.T) { + call := setupCallPlanConfigChange() + + call, err := call.DecodeArgs(bytes.NewBuffer(somePlanConfigChangeArgs.Bytes())) + assert.Nil(t, err) + + _, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + mockStoragePendingEpochConfigChange.AssertNotCalled(t, "Put", nextConfig) +} + func setupCallPlanConfigChange() primitives.Call { mockStoragePendingEpochConfigChange = new(mocks.StorageValue[NextConfigDescriptor]) diff --git a/frame/babe/module.go b/frame/babe/module.go index 2550e2aa..bd7e8792 100644 --- a/frame/babe/module.go +++ b/frame/babe/module.go @@ -84,7 +84,7 @@ type module struct { constants *consts functions map[sc.U8]primitives.Call storage *storage - logger log.Logger + logger log.RuntimeLogger systemModule system.Module disabledValidators primitives.DisabledValidators epochChangeTrigger EpochChangeTrigger @@ -92,7 +92,7 @@ type module struct { mdGenerator *primitives.MetadataTypeGenerator } -func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { storage := newStorage() functions := map[sc.U8]primitives.Call{ diff --git a/frame/balances/call_force_free.go b/frame/balances/call_force_free.go index b22a0597..d5a0633c 100644 --- a/frame/balances/call_force_free.go +++ b/frame/balances/call_force_free.go @@ -14,10 +14,10 @@ import ( type callForceFree struct { primitives.Callable transfer - logger log.DebugLogger + logger log.RuntimeLogger } -func newCallForceFree(moduleId sc.U8, functionId sc.U8, storedMap primitives.StoredMap, constants *consts, mutator accountMutator, logger log.DebugLogger) primitives.Call { +func newCallForceFree(moduleId sc.U8, functionId sc.U8, storedMap primitives.StoredMap, constants *consts, mutator accountMutator, logger log.RuntimeLogger) primitives.Call { call := callForceFree{ Callable: primitives.Callable{ ModuleId: moduleId, diff --git a/frame/balances/call_transfer_all.go b/frame/balances/call_transfer_all.go index 6b860a56..00ca3677 100644 --- a/frame/balances/call_transfer_all.go +++ b/frame/balances/call_transfer_all.go @@ -12,10 +12,10 @@ import ( type callTransferAll struct { primitives.Callable transfer - logger log.DebugLogger + logger log.RuntimeLogger } -func newCallTransferAll(moduleId sc.U8, functionId sc.U8, storedMap primitives.StoredMap, constants *consts, mutator accountMutator, logger log.DebugLogger) primitives.Call { +func newCallTransferAll(moduleId sc.U8, functionId sc.U8, storedMap primitives.StoredMap, constants *consts, mutator accountMutator, logger log.RuntimeLogger) primitives.Call { call := callTransferAll{ Callable: primitives.Callable{ ModuleId: moduleId, diff --git a/frame/balances/module.go b/frame/balances/module.go index 2adacada..3526902e 100644 --- a/frame/balances/module.go +++ b/frame/balances/module.go @@ -36,7 +36,7 @@ type Module struct { mdGenerator *primitives.MetadataTypeGenerator } -func New(index sc.U8, config *Config, logger log.DebugLogger, mdGenerator *primitives.MetadataTypeGenerator) Module { +func New(index sc.U8, config *Config, logger log.RuntimeLogger, mdGenerator *primitives.MetadataTypeGenerator) Module { constants := newConstants(config.DbWeight, config.MaxLocks, config.MaxReserves, config.ExistentialDeposit) storage := newStorage() diff --git a/frame/executive/executive.go b/frame/executive/executive.go index 8d9ced36..a98f0ab6 100644 --- a/frame/executive/executive.go +++ b/frame/executive/executive.go @@ -35,10 +35,10 @@ type module struct { onRuntimeUpgrade primitives.OnRuntimeUpgrade runtimeExtrinsic extrinsic.RuntimeExtrinsic hashing io.Hashing - logger log.TraceLogger + logger log.RuntimeLogger } -func New(systemModule system.Module, runtimeExtrinsic extrinsic.RuntimeExtrinsic, onRuntimeUpgrade primitives.OnRuntimeUpgrade, logger log.TraceLogger) Module { +func New(systemModule system.Module, runtimeExtrinsic extrinsic.RuntimeExtrinsic, onRuntimeUpgrade primitives.OnRuntimeUpgrade, logger log.RuntimeLogger) Module { return module{ system: systemModule, onRuntimeUpgrade: onRuntimeUpgrade, @@ -95,14 +95,17 @@ func (m module) ExecuteBlock(block primitives.Block) error { return err } - // TODO: handle error - m.executeExtrinsicsWithBookKeeping(block) + err = m.executeExtrinsicsWithBookKeeping(block) + if err != nil { + return err + } header := block.Header() err = m.finalChecks(&header) if err != nil { return err } + return nil } @@ -133,6 +136,7 @@ func (m module) ApplyExtrinsic(uxt primitives.UncheckedExtrinsic) error { dispatchInfo := primitives.GetDispatchInfo(checked.Function()) m.logger.Tracef("get_dispatch_info: weight ref time %d", dispatchInfo.Weight.RefTime) unsignedValidator := extrinsic.NewUnsignedValidatorForChecked(m.runtimeExtrinsic) + res, err := checked.Apply(unsignedValidator, &dispatchInfo, encodedLen) if err != nil { _, isDispatchErr := err.(primitives.DispatchError) @@ -144,9 +148,9 @@ func (m module) ApplyExtrinsic(uxt primitives.UncheckedExtrinsic) error { // // The entire block should be discarded if an inherent fails to apply. Otherwise // it may open an attack vector. - if isMendatory, err := dispatchInfo.IsMendatory(); err != nil { + if IsMandatory, err := dispatchInfo.IsMandatory(); err != nil { return err - } else if isMendatory { + } else if IsMandatory { return primitives.NewTransactionValidityError(primitives.NewInvalidTransactionBadMandatory()) } } @@ -203,9 +207,9 @@ func (m module) ValidateTransaction(source primitives.TransactionSource, uxt pri m.logger.Trace("dispatch_info") dispatchInfo := primitives.GetDispatchInfo(checked.Function()) - if isMendatory, err := dispatchInfo.IsMendatory(); err != nil { + if IsMandatory, err := dispatchInfo.IsMandatory(); err != nil { return primitives.ValidTransaction{}, err - } else if isMendatory { + } else if IsMandatory { return primitives.ValidTransaction{}, primitives.NewTransactionValidityError(primitives.NewInvalidTransactionMandatoryValidation()) } @@ -261,9 +265,11 @@ func (m module) idleAndFinalizeHook(blockNumber sc.U64) error { func (m module) executeExtrinsicsWithBookKeeping(block primitives.Block) error { for _, ext := range block.Extrinsics() { - if err := m.ApplyExtrinsic(ext); err != nil { - return err + switch err.(type) { + case primitives.TransactionValidityError: + m.logger.Critical(err.Error()) + } } } diff --git a/frame/executive/executive_test.go b/frame/executive/executive_test.go index 38d3f80e..29baf33d 100644 --- a/frame/executive/executive_test.go +++ b/frame/executive/executive_test.go @@ -877,19 +877,23 @@ func Test_Executive_idleAndFinalizeHook_OnFinalize_Error(t *testing.T) { mockRuntimeExtrinsic.AssertCalled(t, "OnFinalize", blockNumber) } -func Test_executeExtrinsicsWithBookKeeping_ApplyExtrinsic_Error(t *testing.T) { +func Test_executeExtrinsicsWithBookKeeping_ApplyExtrinsic_TransactionValidityError(t *testing.T) { + invalidTransactionBadProofError := primitives.NewTransactionValidityError(primitives.NewInvalidTransactionBadProof()) + setup() block := types.NewBlock(header, sc.Sequence[primitives.UncheckedExtrinsic]{mockUncheckedExtrinsic}) mockUncheckedExtrinsic.On("Bytes").Return(encodedExtrinsic) - mockUncheckedExtrinsic.On("Check").Return(nil, errPanic) + mockUncheckedExtrinsic.On("Check").Return(nil, invalidTransactionBadProofError) - err := target.executeExtrinsicsWithBookKeeping(block) + assert.PanicsWithValue(t, invalidTransactionBadProofError.Error(), func() { + target.executeExtrinsicsWithBookKeeping(block) + }) - assert.Equal(t, errPanic, err) mockUncheckedExtrinsic.AssertCalled(t, "Bytes") mockUncheckedExtrinsic.AssertCalled(t, "Check") + mockSystemModule.AssertNotCalled(t, "NoteFinishedExtrinsics") } func Test_executeExtrinsicsWithBookKeepingNoteFinishedExtrinsics_Error(t *testing.T) { diff --git a/frame/grandpa/equivocation.go b/frame/grandpa/equivocation.go index 4cf864b4..db8945c0 100644 --- a/frame/grandpa/equivocation.go +++ b/frame/grandpa/equivocation.go @@ -40,10 +40,10 @@ type EquivocationReportSystem struct { grandpaModule Module authorshipModule authorship.Module sessionHistoricalModule session_historical.Module - logger log.Logger + logger log.RuntimeLogger } -func NewEquivocationReportSystem(sessionHistoricalModule session_historical.Module, authorshipModule authorship.Module, logger log.Logger) EquivocationReportSystem { +func NewEquivocationReportSystem(sessionHistoricalModule session_historical.Module, authorshipModule authorship.Module, logger log.RuntimeLogger) EquivocationReportSystem { return EquivocationReportSystem{ authorshipModule: authorshipModule, sessionHistoricalModule: sessionHistoricalModule, diff --git a/frame/grandpa/module.go b/frame/grandpa/module.go index 139bc1fd..a7dfaa6d 100644 --- a/frame/grandpa/module.go +++ b/frame/grandpa/module.go @@ -62,10 +62,10 @@ type module struct { systemModule system.Module sessionModule session.Module mdGenerator *primitives.MetadataTypeGenerator - logger log.Logger + logger log.RuntimeLogger } -func New(index sc.U8, config *Config, logger log.Logger, mdGenerator *primitives.MetadataTypeGenerator) Module { +func New(index sc.U8, config *Config, logger log.RuntimeLogger, mdGenerator *primitives.MetadataTypeGenerator) Module { functions := map[sc.U8]primitives.Call{} moduleInstance := module{ diff --git a/frame/session/module.go b/frame/session/module.go index c3dbc506..d4e52a18 100644 --- a/frame/session/module.go +++ b/frame/session/module.go @@ -51,10 +51,10 @@ type module struct { systemModule system.Module handler Handler manager Manager - logger log.Logger + logger log.RuntimeLogger } -func New(index sc.U8, config Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(index sc.U8, config Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { functions := make(map[sc.U8]primitives.Call) module := module{ diff --git a/frame/session_historical/module.go b/frame/session_historical/module.go index 0cacf04d..f94a4864 100644 --- a/frame/session_historical/module.go +++ b/frame/session_historical/module.go @@ -30,10 +30,10 @@ type module struct { constants *consts sessionModule session.Module mdGenerator *primitives.MetadataTypeGenerator - logger log.Logger + logger log.RuntimeLogger } -func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { storage := newStorage() return module{ diff --git a/frame/sudo/module.go b/frame/sudo/module.go index 1cfe24ec..4f82b975 100644 --- a/frame/sudo/module.go +++ b/frame/sudo/module.go @@ -1,13 +1,14 @@ package sudo import ( + "reflect" + sc "github.com/LimeChain/goscale" "github.com/LimeChain/gosemble/constants/metadata" "github.com/LimeChain/gosemble/frame/system" "github.com/LimeChain/gosemble/hooks" "github.com/LimeChain/gosemble/primitives/log" primitives "github.com/LimeChain/gosemble/primitives/types" - "reflect" ) const ( @@ -30,10 +31,10 @@ type Module struct { mdGenerator *primitives.MetadataTypeGenerator storage *storage eventDepositor primitives.EventDepositor - logger log.Logger + logger log.RuntimeLogger } -func New(index sc.U8, config Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(index sc.U8, config Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { functions := make(map[sc.U8]primitives.Call) module := Module{ diff --git a/frame/support/transactional.go b/frame/support/transactional.go index d3c4c4b4..07838105 100644 --- a/frame/support/transactional.go +++ b/frame/support/transactional.go @@ -29,10 +29,10 @@ type Transactional[T sc.Encodable] interface { type transactional[T sc.Encodable] struct { storage StorageValue[sc.U32] transactionBroker io.TransactionBroker - logger log.WarnLogger + logger log.RuntimeLogger } -func NewTransactional[T sc.Encodable](logger log.WarnLogger) Transactional[T] { +func NewTransactional[T sc.Encodable](logger log.RuntimeLogger) Transactional[T] { storageVal := NewSimpleStorageValue(keyTransactionLevel, sc.DecodeU32) return transactional[T]{ storage: storageVal, diff --git a/frame/system/call_authorize_upgrade.go b/frame/system/call_authorize_upgrade.go index 6ff4ce8f..731d931a 100644 --- a/frame/system/call_authorize_upgrade.go +++ b/frame/system/call_authorize_upgrade.go @@ -74,12 +74,10 @@ func (_ callAuthorizeUpgrade) PaysFee(baseWeight primitives.Weight) primitives.P } func (c callAuthorizeUpgrade) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } codeHash := args[0].(primitives.H256) diff --git a/frame/system/call_authorize_upgrade_test.go b/frame/system/call_authorize_upgrade_test.go index 0a077202..cec5b2a9 100644 --- a/frame/system/call_authorize_upgrade_test.go +++ b/frame/system/call_authorize_upgrade_test.go @@ -149,6 +149,17 @@ func Test_Call_AuthorizeUpgrade_Dispatch(t *testing.T) { codeUpgrader.AssertCalled(t, "DoAuthorizeUpgrade", codeHash, sc.Bool(true)) } +func Test_Call_AuthorizeUpgrade_Dispatch_BadOrigin(t *testing.T) { + call := setupCallAuthorizeUpgrade() + call, err := call.DecodeArgs(bytes.NewBuffer(someAuthorizeUpgradeArgs.Bytes())) + assert.Nil(t, err) + + _, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + codeUpgrader.AssertNotCalled(t, "DoAuthorizeUpgrade", codeHash, sc.Bool(true)) +} + func setupCallAuthorizeUpgrade() primitives.Call { codeUpgrader = new(mocks.SystemModule) return newCallAuthorizeUpgrade(moduleId, functionAuthorizeUpgradeIndex, dbWeight, codeUpgrader) diff --git a/frame/system/call_authorize_upgrade_without_checks.go b/frame/system/call_authorize_upgrade_without_checks.go index 0c4ebca0..f1486a8f 100644 --- a/frame/system/call_authorize_upgrade_without_checks.go +++ b/frame/system/call_authorize_upgrade_without_checks.go @@ -74,12 +74,10 @@ func (_ callAuthorizeUpgradeWithoutChecks) PaysFee(baseWeight primitives.Weight) } func (c callAuthorizeUpgradeWithoutChecks) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } codeHash := args[0].(primitives.H256) diff --git a/frame/system/call_authorize_upgrade_without_checks_test.go b/frame/system/call_authorize_upgrade_without_checks_test.go index e0c7f93d..ef7aa376 100644 --- a/frame/system/call_authorize_upgrade_without_checks_test.go +++ b/frame/system/call_authorize_upgrade_without_checks_test.go @@ -138,6 +138,17 @@ func Test_Call_AuthorizeUpgradeWithoutChecks_Dispatch(t *testing.T) { codeUpgrader.AssertCalled(t, "DoAuthorizeUpgrade", codeHash, sc.Bool(false)) } +func Test_Call_AuthorizeUpgradeWithoutChecks_Dispatch_BadOrigin(t *testing.T) { + call := setupCallAuthorizeUpgradeWithoutChecks() + call, err := call.DecodeArgs(bytes.NewBuffer(someAuthorizeUpgradeArgs.Bytes())) + assert.Nil(t, err) + + _, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + codeUpgrader.AssertNotCalled(t, "DoAuthorizeUpgrade", codeHash, sc.Bool(false)) +} + func setupCallAuthorizeUpgradeWithoutChecks() primitives.Call { codeUpgrader = new(mocks.SystemModule) return newCallAuthorizeUpgradeWithoutChecks(moduleId, functionAuthorizeUpgradeWithoutChecksIndex, dbWeight, codeUpgrader) diff --git a/frame/system/call_kill_prefix.go b/frame/system/call_kill_prefix.go index dc7a6b25..8487a037 100644 --- a/frame/system/call_kill_prefix.go +++ b/frame/system/call_kill_prefix.go @@ -81,12 +81,10 @@ func (_ callKillPrefix) PaysFee(baseWeight primitives.Weight) primitives.Pays { } func (c callKillPrefix) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return primitives.PostDispatchInfo{}, err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } prefix := args[0].(sc.Sequence[sc.U8]) subkeys := args[1].(sc.U32) diff --git a/frame/system/call_kill_prefix_test.go b/frame/system/call_kill_prefix_test.go index 31e2a892..d5736911 100644 --- a/frame/system/call_kill_prefix_test.go +++ b/frame/system/call_kill_prefix_test.go @@ -148,6 +148,17 @@ func Test_Call_KillPrefix_Dispatch(t *testing.T) { mockIoStorage.AssertCalled(t, "ClearPrefix", prefixBytes, sc.NewOption[sc.U32](subkeys).Bytes()) } +func Test_Call_KillPrefix_Dispatch_BadOrigin(t *testing.T) { + call := setupCallKillPrefix() + call, err := call.DecodeArgs(bytes.NewBuffer(someKillPrefixArgs.Bytes())) + assert.Nil(t, err) + + _, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + mockIoStorage.AssertNotCalled(t, "ClearPrefix", prefixBytes, sc.NewOption[sc.U32](subkeys).Bytes()) +} + func setupCallKillPrefix() primitives.Call { initMockStorage() return newCallKillPrefix(moduleId, functionKillPrefixIndex, dbWeight, mockIoStorage) diff --git a/frame/system/call_kill_storage.go b/frame/system/call_kill_storage.go index b0bd4e51..004b22cc 100644 --- a/frame/system/call_kill_storage.go +++ b/frame/system/call_kill_storage.go @@ -77,12 +77,10 @@ func (_ callKillStorage) PaysFee(baseWeight primitives.Weight) primitives.Pays { } func (c callKillStorage) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return primitives.PostDispatchInfo{}, err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } keys := args[0].(sc.Sequence[sc.Sequence[sc.U8]]) diff --git a/frame/system/call_kill_storage_test.go b/frame/system/call_kill_storage_test.go index 700e78fd..1a933214 100644 --- a/frame/system/call_kill_storage_test.go +++ b/frame/system/call_kill_storage_test.go @@ -153,6 +153,18 @@ func Test_Call_KillStorage_Dispatch(t *testing.T) { mockIoStorage.AssertCalled(t, "Clear", []byte("testkey2")) } +func Test_Call_KillStorage_Dispatch_BadOrigin(t *testing.T) { + call := setupCallKillStorage() + call, err := call.DecodeArgs(bytes.NewBuffer(someKillStorageArgs.Bytes())) + assert.Nil(t, err) + + _, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + mockIoStorage.AssertNotCalled(t, "Clear", []byte("testkey1")) + mockIoStorage.AssertNotCalled(t, "Clear", []byte("testkey2")) +} + func setupCallKillStorage() primitives.Call { initMockStorage() return newCallKillStorage(moduleId, functionKillStorageIndex, dbWeight, mockIoStorage) diff --git a/frame/system/call_set_code.go b/frame/system/call_set_code.go index 8ba74476..6c008123 100644 --- a/frame/system/call_set_code.go +++ b/frame/system/call_set_code.go @@ -86,16 +86,14 @@ func (_ callSetCode) PaysFee(baseWeight primitives.Weight) primitives.Pays { } func (c callSetCode) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return primitives.PostDispatchInfo{}, err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } codeBlob := args[0].(sc.Sequence[sc.U8]) - err := c.codeUpgrader.CanSetCode(codeBlob) + err = c.codeUpgrader.CanSetCode(codeBlob) if err != nil { return primitives.PostDispatchInfo{}, err } diff --git a/frame/system/call_set_code_test.go b/frame/system/call_set_code_test.go index 6de7f350..60ae9add 100644 --- a/frame/system/call_set_code_test.go +++ b/frame/system/call_set_code_test.go @@ -196,6 +196,20 @@ func Test_Call_SetCode_Dispatch(t *testing.T) { assert.Equal(t, sc.NewOption[primitives.Weight](blockWeights.MaxBlock), res.ActualWeight) } +func Test_Call_SetCode_Dispatch_BadOrigin(t *testing.T) { + call := setupCallSetCode() + call, err := call.DecodeArgs(bytes.NewBuffer(someSetCodeArgs.Bytes())) + assert.Nil(t, err) + + res, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + mockCodeUpgrader.AssertNotCalled(t, "CanSetCode", codeBlob) + mockOnSetCode.AssertNotCalled(t, "SetCode", codeBlob) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + assert.Equal(t, sc.NewOption[primitives.Weight](nil), res.ActualWeight) +} + func setupCallSetCode() primitives.Call { mockCodeUpgrader = new(mocks.SystemModule) mockOnSetCode = new(mocks.DefaultOnSetCode) diff --git a/frame/system/call_set_code_without_checks.go b/frame/system/call_set_code_without_checks.go index c1f002fe..9796b5fd 100644 --- a/frame/system/call_set_code_without_checks.go +++ b/frame/system/call_set_code_without_checks.go @@ -83,16 +83,14 @@ func (_ callSetCodeWithoutChecks) PaysFee(baseWeight primitives.Weight) primitiv } func (c callSetCodeWithoutChecks) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return primitives.PostDispatchInfo{}, err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } codeBlob := args[0].(sc.Sequence[sc.U8]) - err := c.hookOnSetCode.SetCode(codeBlob) + err = c.hookOnSetCode.SetCode(codeBlob) if err != nil { return primitives.PostDispatchInfo{}, err } diff --git a/frame/system/call_set_code_without_checks_test.go b/frame/system/call_set_code_without_checks_test.go index 3de9b268..0741912b 100644 --- a/frame/system/call_set_code_without_checks_test.go +++ b/frame/system/call_set_code_without_checks_test.go @@ -151,6 +151,19 @@ func Test_Call_SetCodeWithoutChecks_Dispatch(t *testing.T) { assert.Equal(t, sc.NewOption[primitives.Weight](blockWeights.MaxBlock), res.ActualWeight) } +func Test_Call_SetCodeWithoutChecks_Dispatch_BadOrigin(t *testing.T) { + call := setupCallSetCodeWithoutChecks() + call, err := call.DecodeArgs(bytes.NewBuffer(someSetCodeWithoutChecksArgs.Bytes())) + assert.Nil(t, err) + + res, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + mockOnSetCode.AssertNotCalled(t, "SetCode", codeBlob) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + assert.Equal(t, sc.NewOption[primitives.Weight](nil), res.ActualWeight) +} + func setupCallSetCodeWithoutChecks() primitives.Call { mockOnSetCode = new(mocks.DefaultOnSetCode) return newCallSetCodeWithoutChecks(moduleId, functionSetCodeWithoutChecksIndex, dbWeight, *moduleConstants, mockOnSetCode) diff --git a/frame/system/call_set_heap_pages.go b/frame/system/call_set_heap_pages.go index 1edcbf1c..3ce46809 100644 --- a/frame/system/call_set_heap_pages.go +++ b/frame/system/call_set_heap_pages.go @@ -83,12 +83,10 @@ func (_ callSetHeapPages) PaysFee(baseWeight primitives.Weight) primitives.Pays } func (c callSetHeapPages) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return primitives.PostDispatchInfo{}, err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } pages := args[0].(sc.U64) diff --git a/frame/system/call_set_heap_pages_test.go b/frame/system/call_set_heap_pages_test.go index 5a98553e..8cc74987 100644 --- a/frame/system/call_set_heap_pages_test.go +++ b/frame/system/call_set_heap_pages_test.go @@ -151,7 +151,21 @@ func Test_Call_SetHeapPages_Dispatch_Success(t *testing.T) { mockLogDepositor.AssertCalled(t, "DepositLog", digestItem) } +func Test_Call_SetHeapPages_Dispatch_Success_BadOrigin(t *testing.T) { + call := setupCallSetHeapPages() + call, err := call.DecodeArgs(bytes.NewBuffer(someSetHeapPagesArgs.Bytes())) + assert.Nil(t, err) + + _, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + + mockStorageHeapPages.AssertNotCalled(t, "Put", pages) + mockLogDepositor.AssertNotCalled(t, "DepositLog", digestItem) +} + func setupCallSetHeapPages() primitives.Call { + mockStorageHeapPages = new(mocks.StorageValue[sc.U64]) mockLogDepositor = new(mocks.SystemModule) return newCallSetHeapPages(moduleId, functionSetHeapPagesIndex, dbWeight, mockStorageHeapPages, mockLogDepositor) } diff --git a/frame/system/call_set_storage.go b/frame/system/call_set_storage.go index 2983885e..bc5708da 100644 --- a/frame/system/call_set_storage.go +++ b/frame/system/call_set_storage.go @@ -77,12 +77,10 @@ func (_ callSetStorage) PaysFee(baseWeight primitives.Weight) primitives.Pays { } func (c callSetStorage) Dispatch(origin primitives.RuntimeOrigin, args sc.VaryingData) (primitives.PostDispatchInfo, error) { - // TODO: enable once 'sudo' module is implemented - // - // err := EnsureRoot(origin) - // if err != nil { - // return primitives.PostDispatchInfo{}, err - // } + err := EnsureRoot(origin) + if err != nil { + return primitives.PostDispatchInfo{}, err + } items := args[0].(sc.Sequence[KeyValue]) diff --git a/frame/system/call_set_storage_test.go b/frame/system/call_set_storage_test.go index 0963d5fd..18d80562 100644 --- a/frame/system/call_set_storage_test.go +++ b/frame/system/call_set_storage_test.go @@ -160,6 +160,19 @@ func Test_Call_SetStorage_Dispatch(t *testing.T) { mockIoStorage.AssertCalled(t, "Set", []byte("testkey2"), []byte("testvalue2")) } +func Test_Call_SetStorage_Dispatch_BadOrigin(t *testing.T) { + call := setupCallSetStorage() + + call, err := call.DecodeArgs(bytes.NewBuffer(someSetStorageArgs.Bytes())) + assert.Nil(t, err) + + _, dispatchErr := call.Dispatch(primitives.NewRawOriginNone(), call.Args()) + + assert.Equal(t, primitives.NewDispatchErrorBadOrigin(), dispatchErr) + mockIoStorage.AssertNotCalled(t, "Set", []byte("testkey1"), []byte("testvalue1")) + mockIoStorage.AssertNotCalled(t, "Set", []byte("testkey2"), []byte("testvalue2")) +} + func setupCallSetStorage() primitives.Call { initMockStorage() return newCallSetStorage(moduleId, functionSetStorageIndex, dbWeight, mockIoStorage) diff --git a/frame/system/module.go b/frame/system/module.go index 3cf79dab..0ea51704 100644 --- a/frame/system/module.go +++ b/frame/system/module.go @@ -105,11 +105,11 @@ type module struct { ioStorage io.Storage ioMisc io.Misc ioHashing io.Hashing - logger log.Logger + logger log.RuntimeLogger mdGenerator *primitives.MetadataTypeGenerator } -func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.Logger) Module { +func New(index sc.U8, config *Config, mdGenerator *primitives.MetadataTypeGenerator, logger log.RuntimeLogger) Module { functions := make(map[sc.U8]primitives.Call) storage := newStorage() constants := newConstants(config.BlockHashCount, config.BlockWeights, config.BlockLength, config.DbWeight, *config.Version) diff --git a/primitives/log/interface.go b/primitives/log/interface.go new file mode 100644 index 00000000..d930d45b --- /dev/null +++ b/primitives/log/interface.go @@ -0,0 +1,26 @@ +package log + +type logLevel int + +const target = "runtime" + +const ( + CriticalLevel logLevel = iota + WarnLevel + InfoLevel + DebugLevel + TraceLevel +) + +type RuntimeLogger interface { + Info(message string) + Infof(message string, a ...any) + Trace(message string) + Tracef(message string, a ...any) + Debug(message string) + Debugf(message string, a ...any) + Warn(message string) + Warnf(message string, a ...any) + Critical(message string) + Criticalf(message string, a ...any) +} diff --git a/primitives/log/logger.go b/primitives/log/logger.go index 838b3b44..7f34b793 100644 --- a/primitives/log/logger.go +++ b/primitives/log/logger.go @@ -9,86 +9,59 @@ import ( "github.com/LimeChain/gosemble/utils" ) -const ( - CriticalLevel = iota - WarnLevel - InfoLevel - DebugLevel - TraceLevel -) - -const target = "runtime" - -type TraceLogger interface { - Trace(message string) - Tracef(message string, a ...any) -} - -type DebugLogger interface { - TraceLogger - Debug(message string) - Debugf(message string, a ...any) -} - -type WarnLogger interface { - DebugLogger - Warn(message string) - Warnf(message string, a ...any) -} - -type Logger struct { +type logger struct { memUtils utils.WasmMemoryTranslator } -func NewLogger() Logger { - return Logger{ +func NewLogger() RuntimeLogger { + return logger{ memUtils: utils.NewMemoryTranslator(), } } -func (l Logger) Critical(message string) { +func (l logger) Critical(message string) { l.log(CriticalLevel, []byte(target), []byte(message)) panic(message) } -func (l Logger) Criticalf(message string, a ...any) { +func (l logger) Criticalf(message string, a ...any) { l.Critical(fmt.Sprintf(message, a...)) } -func (l Logger) Warn(message string) { +func (l logger) Warn(message string) { l.log(WarnLevel, []byte(target), []byte(message)) } -func (l Logger) Warnf(message string, a ...any) { +func (l logger) Warnf(message string, a ...any) { l.Warn(fmt.Sprintf(message, a...)) } -func (l Logger) Info(message string) { +func (l logger) Info(message string) { l.log(InfoLevel, []byte(target), []byte(message)) } -func (l Logger) Infof(message string, a ...any) { +func (l logger) Infof(message string, a ...any) { l.Info(fmt.Sprintf(message, a...)) } -func (l Logger) Debug(message string) { +func (l logger) Debug(message string) { l.log(DebugLevel, []byte(target), []byte(message)) } -func (l Logger) Debugf(message string, a ...any) { +func (l logger) Debugf(message string, a ...any) { l.Debug(fmt.Sprintf(message, a...)) } -func (l Logger) Trace(message string) { +func (l logger) Trace(message string) { l.log(TraceLevel, []byte(target), []byte(message)) } -func (l Logger) Tracef(message string, a ...any) { +func (l logger) Tracef(message string, a ...any) { l.Trace(fmt.Sprintf(message, a...)) } -func (l Logger) log(level int32, target []byte, message []byte) { +func (l logger) log(level logLevel, target []byte, message []byte) { targetOffsetSize := l.memUtils.BytesToOffsetAndSize(target) messageOffsetSize := l.memUtils.BytesToOffsetAndSize(message) - env.ExtLoggingLogVersion1(level, targetOffsetSize, messageOffsetSize) + env.ExtLoggingLogVersion1(int32(level), targetOffsetSize, messageOffsetSize) } diff --git a/primitives/log/logger_nonwasm.go b/primitives/log/logger_nonwasm.go index feb4f54b..82c8c929 100644 --- a/primitives/log/logger_nonwasm.go +++ b/primitives/log/logger_nonwasm.go @@ -4,101 +4,70 @@ package log import "fmt" -type logLevel int +type logger struct{} -const ( - CriticalLevel logLevel = iota - WarnLevel - InfoLevel - DebugLevel - TraceLevel -) - -func (level logLevel) string() string { - switch level { - case CriticalLevel: - return "CRITICAL" - case WarnLevel: - return "WARN" - case InfoLevel: - return "INFO" - case DebugLevel: - return "DEBUG" - case TraceLevel: - return "TRACE" - default: - return "" - } +func NewLogger() RuntimeLogger { + return logger{} } -const target = "runtime" - -type TraceLogger interface { - Trace(message string) - Tracef(message string, a ...any) -} - -type DebugLogger interface { - TraceLogger - Debug(message string) - Debugf(message string, a ...any) -} - -type WarnLogger interface { - DebugLogger - Info(message string) - Infof(message string, a ...any) - Warn(message string) - Warnf(message string, a ...any) -} - -type Logger struct{} - -func NewLogger() Logger { - return Logger{} -} - -func (l Logger) Critical(message string) { +func (l logger) Critical(message string) { l.log(CriticalLevel, []byte(target), []byte(message)) panic(message) } -func (l Logger) Criticalf(message string, a ...any) { +func (l logger) Criticalf(message string, a ...any) { l.Critical(fmt.Sprintf(message, a...)) } -func (l Logger) Warn(message string) { +func (l logger) Warn(message string) { l.log(WarnLevel, []byte(target), []byte(message)) } -func (l Logger) Warnf(message string, a ...any) { +func (l logger) Warnf(message string, a ...any) { l.Warn(fmt.Sprintf(message, a...)) } -func (l Logger) Info(message string) { +func (l logger) Info(message string) { l.log(InfoLevel, []byte(target), []byte(message)) } -func (l Logger) Infof(message string, a ...any) { +func (l logger) Infof(message string, a ...any) { l.Info(fmt.Sprintf(message, a...)) } -func (l Logger) Debug(message string) { +func (l logger) Debug(message string) { l.log(DebugLevel, []byte(target), []byte(message)) } -func (l Logger) Debugf(message string, a ...any) { +func (l logger) Debugf(message string, a ...any) { l.Debug(fmt.Sprintf(message, a...)) } -func (l Logger) Trace(message string) { +func (l logger) Trace(message string) { l.log(TraceLevel, []byte(target), []byte(message)) } -func (l Logger) Tracef(message string, a ...any) { +func (l logger) Tracef(message string, a ...any) { l.Trace(fmt.Sprintf(message, a...)) } -func (l Logger) log(level logLevel, target []byte, message []byte) { +func (l logger) log(level logLevel, target []byte, message []byte) { fmt.Println(fmt.Sprintf("%s target=%s message=%s", level.string(), string(target), string(message))) } + +func (level logLevel) string() string { + switch level { + case CriticalLevel: + return "CRITICAL" + case WarnLevel: + return "WARN" + case InfoLevel: + return "INFO" + case DebugLevel: + return "DEBUG" + case TraceLevel: + return "TRACE" + default: + return "" + } +} diff --git a/primitives/types/dispatch_info.go b/primitives/types/dispatch_info.go index 591e0e29..00981e54 100644 --- a/primitives/types/dispatch_info.go +++ b/primitives/types/dispatch_info.go @@ -50,7 +50,7 @@ func (di DispatchInfo) Bytes() []byte { return sc.EncodedBytes(di) } -func (di DispatchInfo) IsMendatory() (sc.Bool, error) { +func (di DispatchInfo) IsMandatory() (sc.Bool, error) { return di.Class.Is(DispatchClassMandatory) } diff --git a/primitives/types/dispatch_info_test.go b/primitives/types/dispatch_info_test.go index f95f9a9d..9c6f8d59 100644 --- a/primitives/types/dispatch_info_test.go +++ b/primitives/types/dispatch_info_test.go @@ -77,7 +77,7 @@ func Test_IsMendatory(t *testing.T) { }, } { t.Run(tt.name, func(t *testing.T) { - res, err := DispatchInfo{Class: tt.class}.IsMendatory() + res, err := DispatchInfo{Class: tt.class}.IsMandatory() assert.Equal(t, tt.expectedErr, err) assert.Equal(t, sc.Bool(tt.expectedRes), res) }) diff --git a/primitives/types/transaction_validity_error.go b/primitives/types/transaction_validity_error.go index 14fe3f8e..5cff159b 100644 --- a/primitives/types/transaction_validity_error.go +++ b/primitives/types/transaction_validity_error.go @@ -2,7 +2,6 @@ package types import ( "bytes" - "reflect" sc "github.com/LimeChain/goscale" ) @@ -17,55 +16,50 @@ const ( ) // TransactionValidityError Errors that can occur while checking the validity of a transaction. -type TransactionValidityError sc.VaryingData +type TransactionValidityError struct { + sc.VaryingData +} func NewTransactionValidityError(value sc.Encodable) error { // InvalidTransaction = 0 - Transaction is invalid. - // UnknownTransaction = 1 - Transaction validity can’t be determined. + // UnknownTransaction = 1 - Transaction validity can't be determined. switch value.(type) { - case InvalidTransaction, UnknownTransaction: + case InvalidTransaction: + return TransactionValidityError{sc.NewVaryingData(TransactionValidityErrorInvalidTransaction, value)} + case UnknownTransaction: + return TransactionValidityError{sc.NewVaryingData(TransactionValidityErrorUnknownTransaction, value)} + default: + return errInvalidTransactionValidityErrorType + } +} + +func (e TransactionValidityError) Encode(buffer *bytes.Buffer) error { + if len(e.VaryingData) != 2 { + return errInvalidTransactionValidityErrorType + } + switch e.VaryingData[0] { + case TransactionValidityErrorUnknownTransaction, TransactionValidityErrorInvalidTransaction: + return e.VaryingData.Encode(buffer) default: return errInvalidTransactionValidityErrorType } - return TransactionValidityError(sc.NewVaryingData(value)) } func (err TransactionValidityError) Error() string { - if len(err) == 0 { + if len(err.VaryingData) != 2 { return errInvalidTransactionValidityErrorType.Error() } - switch err[0] { + switch err.VaryingData[0] { case TransactionValidityErrorUnknownTransaction: - return err[1].(UnknownTransaction).Error() + return err.VaryingData[1].(UnknownTransaction).Error() case TransactionValidityErrorInvalidTransaction: - return err[1].(InvalidTransaction).Error() + return err.VaryingData[1].(InvalidTransaction).Error() default: return errInvalidTransactionValidityErrorType.Error() } } -func (e TransactionValidityError) Encode(buffer *bytes.Buffer) error { - value := e[0] - - switch reflect.TypeOf(value) { - case reflect.TypeOf(*new(InvalidTransaction)): - err := TransactionValidityErrorInvalidTransaction.Encode(buffer) - if err != nil { - return err - } - case reflect.TypeOf(*new(UnknownTransaction)): - err := TransactionValidityErrorUnknownTransaction.Encode(buffer) - if err != nil { - return err - } - default: - return errInvalidTransactionValidityErrorType - } - - return value.Encode(buffer) -} - func DecodeTransactionValidityError(buffer *bytes.Buffer) (TransactionValidityError, error) { b, err := sc.DecodeU8(buffer) if err != nil { @@ -98,10 +92,6 @@ func DecodeTransactionValidityError(buffer *bytes.Buffer) (TransactionValidityEr } } -func (e TransactionValidityError) Bytes() []byte { - return sc.EncodedBytes(e) -} - func (e TransactionValidityError) MetadataDefinition(typesInvalidTxId int, typesUnknownTxId int) *MetadataTypeDefinition { def := NewMetadataTypeDefinitionVariant( sc.Sequence[MetadataDefinitionVariant]{ diff --git a/primitives/types/transaction_validity_error_test.go b/primitives/types/transaction_validity_error_test.go index ace12a75..487cbfcd 100644 --- a/primitives/types/transaction_validity_error_test.go +++ b/primitives/types/transaction_validity_error_test.go @@ -52,7 +52,7 @@ func Test_TransactionValidityError_Encode(t *testing.T) { func Test_TransactionValidityError_Encode_TypeError(t *testing.T) { buffer := &bytes.Buffer{} - tve := TransactionValidityError(sc.NewVaryingData(sc.U8(6))) + tve := TransactionValidityError{sc.NewVaryingData(sc.U8(6))} err := tve.Encode(buffer) diff --git a/runtime/templates/poa/system_apply_authorized_upgrade_test.go b/runtime/templates/poa/system_apply_authorized_upgrade_test.go index 7ebf06f3..cc736bed 100644 --- a/runtime/templates/poa/system_apply_authorized_upgrade_test.go +++ b/runtime/templates/poa/system_apply_authorized_upgrade_test.go @@ -26,7 +26,14 @@ func Test_ApplyAuthorizedUpgrade_DispatchOutcome(t *testing.T) { assert.NoError(t, err) codeHash := common.MustBlake2bHash(codeSpecVersion101) - call, err := ctypes.NewCall(metadata, "System.authorize_upgrade", codeHash) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + + callArg, err := ctypes.NewCall(metadata, "System.authorize_upgrade", codeHash) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) diff --git a/runtime/templates/poa/system_authorize_upgrade_test.go b/runtime/templates/poa/system_authorize_upgrade_test.go index 8e22dcd0..6973cf8a 100644 --- a/runtime/templates/poa/system_authorize_upgrade_test.go +++ b/runtime/templates/poa/system_authorize_upgrade_test.go @@ -22,13 +22,20 @@ func Test_AuthorizeUpgrade_DispatchOutcome(t *testing.T) { runtimeVersion, err := rt.Version() assert.NoError(t, err) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + testhelpers.InitializeBlock(t, rt, testhelpers.ParentHash, testhelpers.StateRoot, testhelpers.ExtrinsicsRoot, testhelpers.BlockNumber) codeSpecVersion101, err := os.ReadFile(testhelpers.RuntimeWasmSpecVersion101) assert.NoError(t, err) codeHash := common.MustBlake2bHash(codeSpecVersion101) - call, err := ctypes.NewCall(metadata, "System.authorize_upgrade", codeHash) + callArg, err := ctypes.NewCall(metadata, "System.authorize_upgrade", codeHash) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) @@ -67,7 +74,7 @@ func Test_AuthorizeUpgrade_DispatchOutcome(t *testing.T) { decodedCount, err := sc.DecodeCompact[sc.U32](buffer) assert.NoError(t, err) - assert.Equal(t, sc.U32(3), decodedCount.Number) + assert.Equal(t, sc.U32(4), decodedCount.Number) testhelpers.AssertEmittedSystemEvent(t, system.EventUpgradeAuthorized, buffer) diff --git a/runtime/templates/poa/system_kill_prefix_test.go b/runtime/templates/poa/system_kill_prefix_test.go index b81bfecf..e1343ad3 100644 --- a/runtime/templates/poa/system_kill_prefix_test.go +++ b/runtime/templates/poa/system_kill_prefix_test.go @@ -18,12 +18,19 @@ func Test_KillPrefix_DispatchOutcome(t *testing.T) { runtimeVersion, err := rt.Version() assert.NoError(t, err) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + testhelpers.InitializeBlock(t, rt, testhelpers.ParentHash, testhelpers.StateRoot, testhelpers.ExtrinsicsRoot, testhelpers.BlockNumber) prefix := []byte("test") limit := uint32(2) - call, err := ctypes.NewCall(metadata, "System.kill_prefix", prefix, limit) + callArg, err := ctypes.NewCall(metadata, "System.kill_prefix", prefix, limit) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) diff --git a/runtime/templates/poa/system_kill_storage_test.go b/runtime/templates/poa/system_kill_storage_test.go index d2d4d4ad..e1f0a05d 100644 --- a/runtime/templates/poa/system_kill_storage_test.go +++ b/runtime/templates/poa/system_kill_storage_test.go @@ -18,6 +18,10 @@ func Test_KillStorage_DispatchOutcome(t *testing.T) { runtimeVersion, err := rt.Version() assert.NoError(t, err) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + testhelpers.InitializeBlock(t, rt, testhelpers.ParentHash, testhelpers.StateRoot, testhelpers.ExtrinsicsRoot, testhelpers.BlockNumber) keys := [][]byte{ @@ -25,7 +29,10 @@ func Test_KillStorage_DispatchOutcome(t *testing.T) { []byte("testkey2"), } - call, err := ctypes.NewCall(metadata, "System.kill_storage", keys) + callArg, err := ctypes.NewCall(metadata, "System.kill_storage", keys) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) diff --git a/runtime/templates/poa/system_set_code_test.go b/runtime/templates/poa/system_set_code_test.go index 7dfedb88..2033b883 100644 --- a/runtime/templates/poa/system_set_code_test.go +++ b/runtime/templates/poa/system_set_code_test.go @@ -5,10 +5,8 @@ import ( "os" "testing" - gossamertypes "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/pkg/scale" sc "github.com/LimeChain/goscale" - "github.com/LimeChain/gosemble/frame/aura" + sudo "github.com/LimeChain/gosemble/frame/sudo" "github.com/LimeChain/gosemble/frame/system" "github.com/LimeChain/gosemble/frame/transaction_payment" "github.com/LimeChain/gosemble/primitives/types" @@ -26,12 +24,19 @@ func Test_SetCode_Success(t *testing.T) { runtimeVersion, err := rt.Version() assert.NoError(t, err) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + testhelpers.InitializeBlock(t, rt, testhelpers.ParentHash, testhelpers.StateRoot, testhelpers.ExtrinsicsRoot, testhelpers.BlockNumber) codeSpecVersion101, err := os.ReadFile(testhelpers.RuntimeWasmSpecVersion101) assert.NoError(t, err) - call, err := ctypes.NewCall(metadata, "System.set_code", codeSpecVersion101) + callArg, err := ctypes.NewCall(metadata, "System.set_code", codeSpecVersion101) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) @@ -66,16 +71,19 @@ func Test_SetCode_Success(t *testing.T) { // Events are emitted buffer := &bytes.Buffer{} - testhelpers.AssertStorageSystemEventCount(t, storage, uint32(3)) + testhelpers.AssertStorageSystemEventCount(t, storage, uint32(4)) buffer.Write((*storage).Get(append(testhelpers.KeySystemHash, testhelpers.KeyEventsHash...))) decodedCount, err := sc.DecodeCompact[sc.U32](buffer) assert.NoError(t, err) - assert.Equal(t, uint32(decodedCount.Number.(sc.U32)), uint32(3)) + assert.Equal(t, uint32(decodedCount.Number.(sc.U32)), uint32(4)) // Event system code updated testhelpers.AssertEmittedSystemEvent(t, system.EventCodeUpdated, buffer) + // Event sudo + testhelpers.AssertEmittedSudoEvent(t, sudo.EventSudid, buffer) + // Event txpayment transaction fee paid testhelpers.AssertEmittedTransactionPaymentEvent(t, transaction_payment.EventTransactionFeePaid, buffer) @@ -91,107 +99,3 @@ func Test_SetCode_Success(t *testing.T) { assert.Equal(t, testhelpers.ApplyExtrinsicResultOutcome.Bytes(), res) } - -func Test_Block_Execution_After_Code_Upgrade(t *testing.T) { - rt, storage := testhelpers.NewRuntimeInstance(t) - metadata := testhelpers.RuntimeMetadata(t, rt) - - runtimeVersion, err := rt.Version() - assert.NoError(t, err) - - bytesSlotDuration, err := rt.Exec("AuraApi_slot_duration", []byte{}) - assert.NoError(t, err) - - buffer := &bytes.Buffer{} - buffer.Write(bytesSlotDuration) - - slotDuration, err := sc.DecodeU64(buffer) - assert.Nil(t, err) - buffer.Reset() - - slot := sc.U64(dateTime.UnixMilli()) / slotDuration - - preRuntimeDigest := gossamertypes.PreRuntimeDigest{ - ConsensusEngineID: aura.EngineId, - Data: slot.Bytes(), - } - digest := gossamertypes.NewDigest() - assert.NoError(t, digest.Add(preRuntimeDigest)) - - header := gossamertypes.NewHeader(testhelpers.ParentHash, storageRoot, testhelpers.ExtrinsicsRoot, uint(testhelpers.BlockNumber), digest) - encodedHeader, err := scale.Marshal(*header) - assert.NoError(t, err) - - _, err = rt.Exec("Core_initialize_block", encodedHeader) - assert.NoError(t, err) - - idata := gossamertypes.NewInherentData() - err = idata.SetInherent(gossamertypes.Timstap0, uint64(dateTime.UnixMilli())) - assert.NoError(t, err) - - ienc, err := idata.Encode() - assert.NoError(t, err) - - inherentExt, err := rt.Exec("BlockBuilder_inherent_extrinsics", ienc) - assert.NoError(t, err) - assert.NotNil(t, inherentExt) - - buffer.Write([]byte{inherentExt[0]}) - - totalInherents, err := sc.DecodeCompact[sc.U128](buffer) - assert.Nil(t, err) - assert.Equal(t, int64(1), totalInherents.ToBigInt().Int64()) - buffer.Reset() - - applyResult, err := rt.Exec("BlockBuilder_apply_extrinsic", inherentExt[1:]) - assert.NoError(t, err) - - assert.Equal(t, testhelpers.ApplyExtrinsicResultOutcome.Bytes(), applyResult) - - codeSpecVersion101, err := os.ReadFile(testhelpers.RuntimeWasmSpecVersion101) - assert.NoError(t, err) - - call, err := ctypes.NewCall(metadata, "System.set_code_without_checks", codeSpecVersion101) - assert.NoError(t, err) - - extrinsic := ctypes.NewExtrinsic(call) - - o := ctypes.SignatureOptions{ - BlockHash: ctypes.Hash(testhelpers.ParentHash), - Era: ctypes.ExtrinsicEra{IsImmortalEra: true}, - GenesisHash: ctypes.Hash(testhelpers.ParentHash), - Nonce: ctypes.NewUCompactFromUInt(0), - SpecVersion: ctypes.U32(runtimeVersion.SpecVersion), - Tip: ctypes.NewUCompactFromUInt(0), - TransactionVersion: ctypes.U32(runtimeVersion.TransactionVersion), - } - - err = extrinsic.Sign(signature.TestKeyringPairAlice, o) - assert.NoError(t, err) - - extEnc := bytes.Buffer{} - encoder := cscale.NewEncoder(&extEnc) - err = extrinsic.Encode(*encoder) - assert.NoError(t, err) - - res, err := rt.Exec("BlockBuilder_apply_extrinsic", extEnc.Bytes()) - assert.NoError(t, err) - - // Code is written to storage - assert.Equal(t, codeSpecVersion101, (*storage).LoadCode()) - - // Runtime version is updated - rt, storage = testhelpers.NewRuntimeInstanceFromCode(t, rt, (*storage).LoadCode()) - - runtimeVersion, err = rt.Version() - assert.NoError(t, err) - assert.Equal(t, runtimeVersion.SpecVersion, uint32(101)) - - assert.Equal(t, testhelpers.ApplyExtrinsicResultOutcome.Bytes(), res) - - bytesResult, err := rt.Exec("BlockBuilder_finalize_block", []byte{}) - assert.NoError(t, err) - - resultHeader := gossamertypes.NewEmptyHeader() - assert.NoError(t, scale.Unmarshal(bytesResult, resultHeader)) -} diff --git a/runtime/templates/poa/system_set_code_without_checks_test.go b/runtime/templates/poa/system_set_code_without_checks_test.go index 21d2b848..63fc3bf7 100644 --- a/runtime/templates/poa/system_set_code_without_checks_test.go +++ b/runtime/templates/poa/system_set_code_without_checks_test.go @@ -5,7 +5,11 @@ import ( "os" "testing" + gossamertypes "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/pkg/scale" sc "github.com/LimeChain/goscale" + "github.com/LimeChain/gosemble/frame/aura" + "github.com/LimeChain/gosemble/frame/sudo" "github.com/LimeChain/gosemble/frame/system" "github.com/LimeChain/gosemble/frame/transaction_payment" "github.com/LimeChain/gosemble/primitives/types" @@ -23,12 +27,19 @@ func Test_SetCodeWithoutChecks_DispatchOutcome(t *testing.T) { runtimeVersion, err := rt.Version() assert.NoError(t, err) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + testhelpers.InitializeBlock(t, rt, testhelpers.ParentHash, testhelpers.StateRoot, testhelpers.ExtrinsicsRoot, testhelpers.BlockNumber) codeSpecVersion101, err := os.ReadFile(testhelpers.RuntimeWasmSpecVersion101) assert.NoError(t, err) - call, err := ctypes.NewCall(metadata, "System.set_code_without_checks", codeSpecVersion101) + callArg, err := ctypes.NewCall(metadata, "System.set_code_without_checks", codeSpecVersion101) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) @@ -63,18 +74,21 @@ func Test_SetCodeWithoutChecks_DispatchOutcome(t *testing.T) { // Events are emitted buffer := &bytes.Buffer{} - testhelpers.AssertStorageSystemEventCount(t, storage, uint32(3)) + testhelpers.AssertStorageSystemEventCount(t, storage, uint32(4)) buffer.Reset() buffer.Write((*storage).Get(append(testhelpers.KeySystemHash, testhelpers.KeyEventsHash...))) decodedCount, err := sc.DecodeCompact[sc.U32](buffer) assert.NoError(t, err) - assert.Equal(t, uint32(decodedCount.Number.(sc.U32)), uint32(3)) + assert.Equal(t, uint32(decodedCount.Number.(sc.U32)), uint32(4)) // Event system code updated testhelpers.AssertEmittedSystemEvent(t, system.EventCodeUpdated, buffer) + // Event sudo + testhelpers.AssertEmittedSudoEvent(t, sudo.EventSudid, buffer) + // Event txpayment transaction fee paid testhelpers.AssertEmittedTransactionPaymentEvent(t, transaction_payment.EventTransactionFeePaid, buffer) @@ -90,3 +104,114 @@ func Test_SetCodeWithoutChecks_DispatchOutcome(t *testing.T) { assert.Equal(t, testhelpers.ApplyExtrinsicResultOutcome.Bytes(), res) } + +func Test_Block_Execution_After_Code_Upgrade(t *testing.T) { + rt, storage := testhelpers.NewRuntimeInstance(t) + metadata := testhelpers.RuntimeMetadata(t, rt) + + runtimeVersion, err := rt.Version() + assert.NoError(t, err) + + bytesSlotDuration, err := rt.Exec("AuraApi_slot_duration", []byte{}) + assert.NoError(t, err) + + buffer := &bytes.Buffer{} + buffer.Write(bytesSlotDuration) + + slotDuration, err := sc.DecodeU64(buffer) + assert.Nil(t, err) + buffer.Reset() + + slot := sc.U64(dateTime.UnixMilli()) / slotDuration + + preRuntimeDigest := gossamertypes.PreRuntimeDigest{ + ConsensusEngineID: aura.EngineId, + Data: slot.Bytes(), + } + digest := gossamertypes.NewDigest() + assert.NoError(t, digest.Add(preRuntimeDigest)) + + header := gossamertypes.NewHeader(testhelpers.ParentHash, storageRoot, testhelpers.ExtrinsicsRoot, uint(testhelpers.BlockNumber), digest) + encodedHeader, err := scale.Marshal(*header) + assert.NoError(t, err) + + _, err = rt.Exec("Core_initialize_block", encodedHeader) + assert.NoError(t, err) + + idata := gossamertypes.NewInherentData() + err = idata.SetInherent(gossamertypes.Timstap0, uint64(dateTime.UnixMilli())) + assert.NoError(t, err) + + ienc, err := idata.Encode() + assert.NoError(t, err) + + inherentExt, err := rt.Exec("BlockBuilder_inherent_extrinsics", ienc) + assert.NoError(t, err) + assert.NotNil(t, inherentExt) + + buffer.Write([]byte{inherentExt[0]}) + + totalInherents, err := sc.DecodeCompact[sc.U128](buffer) + assert.Nil(t, err) + assert.Equal(t, int64(1), totalInherents.ToBigInt().Int64()) + buffer.Reset() + + applyResult, err := rt.Exec("BlockBuilder_apply_extrinsic", inherentExt[1:]) + assert.NoError(t, err) + + assert.Equal(t, testhelpers.ApplyExtrinsicResultOutcome.Bytes(), applyResult) + + codeSpecVersion101, err := os.ReadFile(testhelpers.RuntimeWasmSpecVersion101) + assert.NoError(t, err) + + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + + callArg, err := ctypes.NewCall(metadata, "System.set_code_without_checks", codeSpecVersion101) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) + assert.NoError(t, err) + + extrinsic := ctypes.NewExtrinsic(call) + + o := ctypes.SignatureOptions{ + BlockHash: ctypes.Hash(testhelpers.ParentHash), + Era: ctypes.ExtrinsicEra{IsImmortalEra: true}, + GenesisHash: ctypes.Hash(testhelpers.ParentHash), + Nonce: ctypes.NewUCompactFromUInt(0), + SpecVersion: ctypes.U32(runtimeVersion.SpecVersion), + Tip: ctypes.NewUCompactFromUInt(0), + TransactionVersion: ctypes.U32(runtimeVersion.TransactionVersion), + } + + err = extrinsic.Sign(signature.TestKeyringPairAlice, o) + assert.NoError(t, err) + + extEnc := bytes.Buffer{} + encoder := cscale.NewEncoder(&extEnc) + err = extrinsic.Encode(*encoder) + assert.NoError(t, err) + + res, err := rt.Exec("BlockBuilder_apply_extrinsic", extEnc.Bytes()) + assert.NoError(t, err) + + // Code is written to storage + assert.Equal(t, codeSpecVersion101, (*storage).LoadCode()) + + // Runtime version is updated + rt, storage = testhelpers.NewRuntimeInstanceFromCode(t, rt, (*storage).LoadCode()) + + runtimeVersion, err = rt.Version() + assert.NoError(t, err) + assert.Equal(t, runtimeVersion.SpecVersion, uint32(101)) + + assert.Equal(t, testhelpers.ApplyExtrinsicResultOutcome.Bytes(), res) + + bytesResult, err := rt.Exec("BlockBuilder_finalize_block", []byte{}) + assert.NoError(t, err) + + resultHeader := gossamertypes.NewEmptyHeader() + assert.NoError(t, scale.Unmarshal(bytesResult, resultHeader)) +} diff --git a/runtime/templates/poa/system_set_heap_pages_test.go b/runtime/templates/poa/system_set_heap_pages_test.go index e8f4714f..5d8ab682 100644 --- a/runtime/templates/poa/system_set_heap_pages_test.go +++ b/runtime/templates/poa/system_set_heap_pages_test.go @@ -28,9 +28,16 @@ func Test_SetHeapPages_DispatchOutcome(t *testing.T) { runtimeVersion, err := rt.Version() assert.NoError(t, err) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + testhelpers.InitializeBlock(t, rt, testhelpers.ParentHash, testhelpers.StateRoot, testhelpers.ExtrinsicsRoot, testhelpers.BlockNumber) - call, err := ctypes.NewCall(metadata, "System.set_heap_pages", pages) + callArg, err := ctypes.NewCall(metadata, "System.set_heap_pages", pages) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) diff --git a/runtime/templates/poa/system_set_storage_test.go b/runtime/templates/poa/system_set_storage_test.go index 1dcbe336..5a6595b5 100644 --- a/runtime/templates/poa/system_set_storage_test.go +++ b/runtime/templates/poa/system_set_storage_test.go @@ -21,6 +21,10 @@ func Test_SetStorage_DispatchOutcome(t *testing.T) { // Initialize block testhelpers.InitializeBlock(t, rt, testhelpers.ParentHash, testhelpers.StateRoot, testhelpers.ExtrinsicsRoot, testhelpers.BlockNumber) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + items := []struct { Key []byte Value []byte @@ -35,7 +39,10 @@ func Test_SetStorage_DispatchOutcome(t *testing.T) { }, } - call, err := ctypes.NewCall(metadata, "System.set_storage", items) + callArg, err := ctypes.NewCall(metadata, "System.set_storage", items) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) diff --git a/runtime/templates/pos/babe_plan_config_change_test.go b/runtime/templates/pos/babe_plan_config_change_test.go index d04ed6d6..74cabbcf 100644 --- a/runtime/templates/pos/babe_plan_config_change_test.go +++ b/runtime/templates/pos/babe_plan_config_change_test.go @@ -48,7 +48,14 @@ func Test_Babe_Plan_Config_Change(t *testing.T) { SecondarySlots: 2, } - call, err := ctypes.NewCall(metadata, "Babe.plan_config_change", versionedNextConfigData) + // Set Sudo Key + err := (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + + callArg, err := ctypes.NewCall(metadata, "Babe.plan_config_change", versionedNextConfigData) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) + assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) diff --git a/runtime/templates/pos/system_set_code_test.go b/runtime/templates/pos/system_set_code_test.go index ba627a1a..31d62fbf 100644 --- a/runtime/templates/pos/system_set_code_test.go +++ b/runtime/templates/pos/system_set_code_test.go @@ -62,7 +62,14 @@ func Test_Block_Execution_After_Code_Upgrade(t *testing.T) { codeSpecVersion101, err := os.ReadFile(testhelpers.RuntimeWasmSpecVersion101) assert.NoError(t, err) - call, err := ctypes.NewCall(metadata, "System.set_code_without_checks", codeSpecVersion101) + // Set Sudo Key + err = (*storage).Put(append(testhelpers.KeySudoHash, testhelpers.KeyKeyHash...), signature.TestKeyringPairAlice.PublicKey) + assert.NoError(t, err) + + callArg, err := ctypes.NewCall(metadata, "System.set_code_without_checks", codeSpecVersion101) + assert.NoError(t, err) + + call, err := ctypes.NewCall(metadata, "Sudo.sudo", callArg) assert.NoError(t, err) extrinsic := ctypes.NewExtrinsic(call) diff --git a/testdata/runtimes/gosemble_poa_template_spec_version_101.wasm b/testdata/runtimes/gosemble_poa_template_spec_version_101.wasm new file mode 100755 index 00000000..64f2b257 Binary files /dev/null and b/testdata/runtimes/gosemble_poa_template_spec_version_101.wasm differ diff --git a/testdata/runtimes/gosemble_spec_version_101.wasm b/testdata/runtimes/gosemble_spec_version_101.wasm deleted file mode 100755 index 60d3bf30..00000000 Binary files a/testdata/runtimes/gosemble_spec_version_101.wasm and /dev/null differ diff --git a/testhelpers/testhelpers.go b/testhelpers/testhelpers.go index 6d532460..5b92480a 100644 --- a/testhelpers/testhelpers.go +++ b/testhelpers/testhelpers.go @@ -32,7 +32,7 @@ import ( ) const RuntimeWasm = "../../../build/runtime-benchmarks.wasm" -const RuntimeWasmSpecVersion101 = "../../../testdata/runtimes/gosemble_spec_version_101.wasm" +const RuntimeWasmSpecVersion101 = "../../../testdata/runtimes/gosemble_poa_template_spec_version_101.wasm" const ( SystemIndex sc.U8 = iota @@ -290,6 +290,16 @@ func AssertStorageDigestItem(t *testing.T, storage *runtime.Storage, digestItem } } +func AssertEmittedSudoEvent(t assert.TestingT, event sc.U8, buffer *bytes.Buffer) { + var emitted bool + eventRecord, err := types.DecodeEventRecord(SudoIndex, sudo.DecodeEvent, buffer) + assert.NoError(t, err) + if eventRecord.Event.VaryingData[1] == event { + emitted = true + } + assert.True(t, emitted) +} + func SetStorageAccountInfo(t *testing.T, storage *runtime.Storage, account []byte, freeBalance *big.Int, nonce uint32) (storageKey []byte, info gossamertypes.AccountInfo) { accountInfo := gossamertypes.AccountInfo{ Nonce: nonce,