diff --git a/lib/babe/helpers_test.go b/lib/babe/helpers_test.go index 697103cf6f..b49fd3b45a 100644 --- a/lib/babe/helpers_test.go +++ b/lib/babe/helpers_test.go @@ -184,6 +184,8 @@ func createTestService(t *testing.T, cfg ServiceConfig, genesis genesis.Genesis, dbSrv := state.NewService(config) dbSrv.UseMemDB() + dbSrv.Transaction = state.NewTransactionState(telemetryMock) + err := dbSrv.Initialise(&genesis, &genesisHeader, &genesisTrie) require.NoError(t, err) @@ -215,6 +217,7 @@ func createTestService(t *testing.T, cfg ServiceConfig, genesis genesis.Genesis, nodeStorage.BaseDB = dbSrv.Base rtCfg.NodeStorage = nodeStorage + rtCfg.Transaction = dbSrv.Transaction runtime, err := wasmer.NewRuntimeFromGenesis(rtCfg) require.NoError(t, err) cfg.BlockState.(*state.BlockState).StoreRuntime(cfg.BlockState.BestBlockHash(), runtime) diff --git a/lib/babe/verify.go b/lib/babe/verify.go index 3b8d98360d..7c1342b757 100644 --- a/lib/babe/verify.go +++ b/lib/babe/verify.go @@ -4,6 +4,7 @@ package babe import ( + "errors" "fmt" "sync" @@ -13,6 +14,8 @@ import ( "github.com/ChainSafe/gossamer/pkg/scale" ) +var errEmptyKeyOwnershipProof = errors.New("key ownership proof is nil") + // verifierInfo contains the information needed to verify blocks // it remains the same for an epoch type verifierInfo struct { @@ -360,6 +363,8 @@ func (b *verifier) submitAndReportEquivocation( keyOwnershipProof, err := runtimeInstance.BabeGenerateKeyOwnershipProof(slot, offenderPublicKey) if err != nil { return fmt.Errorf("getting key ownership proof from runtime: %w", err) + } else if keyOwnershipProof == nil { + return fmt.Errorf("%w", errEmptyKeyOwnershipProof) } equivocationProof := &types.BabeEquivocationProof{ diff --git a/lib/babe/verify_integration_test.go b/lib/babe/verify_integration_test.go index 3c864f91ef..bb0f2f8cbc 100644 --- a/lib/babe/verify_integration_test.go +++ b/lib/babe/verify_integration_test.go @@ -433,18 +433,11 @@ func TestVerifyAuthorshipRight(t *testing.T) { require.NoError(t, err) } -// TODO this test failing is related too issue #3136 func TestVerifyAuthorshipRight_Equivocation(t *testing.T) { - t.Skip() - kp, err := sr25519.GenerateKeypair() - require.NoError(t, err) - - cfg := ServiceConfig{ - Keypair: kp, - } - genesis, genesisTrie, genesisHeader := newWestendDevGenesisWithTrieAndHeader(t) - babeService := createTestService(t, cfg, genesis, genesisTrie, genesisHeader, nil) + babeService := createTestService(t, ServiceConfig{}, genesis, genesisTrie, genesisHeader, nil) + verificationManager := NewVerificationManager(babeService.blockState, babeService.epochState) + epochData, err := babeService.initiateEpoch(testEpochIndex) require.NoError(t, err) @@ -452,19 +445,6 @@ func TestVerifyAuthorshipRight_Equivocation(t *testing.T) { runtime, err := babeService.blockState.GetRuntime(bestBlockHash) require.NoError(t, err) - epochData.threshold = maxThreshold - epochData.authorities = []types.Authority{ - { - Key: kp.Public().(*sr25519.PublicKey), - }, - } - - verifier := newVerifier(babeService.blockState, testEpochIndex, &verifierInfo{ - authorities: epochData.authorities, - threshold: epochData.threshold, - randomness: epochData.randomness, - }) - // slots are 6 seconds on westend and using time.Now() allows us to create a block at any point in the slot. // So we need to manually set time to produce consistent results. See here: // https://github.com/paritytech/substrate/blob/09de7b41599add51cf27eca8f1bc4c50ed8e9453/frame/timestamp/src/lib.rs#L229 @@ -481,13 +461,13 @@ func TestVerifyAuthorshipRight_Equivocation(t *testing.T) { err = babeService.blockState.AddBlock(block) require.NoError(t, err) - err = verifier.verifyAuthorshipRight(&block.Header) + err = verificationManager.VerifyBlock(&block.Header) require.NoError(t, err) err = babeService.blockState.AddBlock(block2) require.NoError(t, err) - err = verifier.verifyAuthorshipRight(&block2.Header) + err = verificationManager.VerifyBlock(&block2.Header) require.ErrorIs(t, err, ErrProducerEquivocated) require.EqualError(t, err, fmt.Sprintf("%s for block header %s", ErrProducerEquivocated, block2.Header.Hash())) } diff --git a/lib/grandpa/vote_message.go b/lib/grandpa/vote_message.go index 43ba96ee60..6fe9555ebc 100644 --- a/lib/grandpa/vote_message.go +++ b/lib/grandpa/vote_message.go @@ -17,7 +17,10 @@ import ( "github.com/libp2p/go-libp2p/core/peer" ) -var errBeforeFinalizedBlock = errors.New("before latest finalized block") +var ( + errBeforeFinalizedBlock = errors.New("before latest finalized block") + errEmptyKeyOwnershipProof = errors.New("key ownership proof is nil") +) type networkVoteMessage struct { from peer.ID @@ -284,6 +287,8 @@ func (s *Service) reportEquivocation(stage Subround, existingVote *SignedVote, c opaqueKeyOwnershipProof, err := runtime.GrandpaGenerateKeyOwnershipProof(setID, pubKey) if err != nil { return fmt.Errorf("getting key ownership proof: %w", err) + } else if opaqueKeyOwnershipProof == nil { + return fmt.Errorf("%w", errEmptyKeyOwnershipProof) } grandpaEquivocation := types.GrandpaEquivocation{ diff --git a/lib/runtime/wasmer/exports.go b/lib/runtime/wasmer/exports.go index b7298cb574..e659d01f8e 100644 --- a/lib/runtime/wasmer/exports.go +++ b/lib/runtime/wasmer/exports.go @@ -5,6 +5,7 @@ package wasmer import ( "bytes" + "errors" "fmt" "github.com/ChainSafe/gossamer/dot/types" @@ -14,6 +15,8 @@ import ( "github.com/ChainSafe/gossamer/pkg/scale" ) +var errEmptyKeyOwnershipProof = errors.New("key ownership proof is nil") + // ValidateTransaction runs the extrinsic through the runtime function // TaggedTransactionQueue_validate_transaction and returns *transaction.Validity. The error can // be a VDT of either transaction.InvalidTransaction or transaction.UnknownTransaction, or can represent @@ -110,13 +113,18 @@ func (in *Instance) BabeGenerateKeyOwnershipProof(slot uint64, authorityID [32]b return nil, fmt.Errorf("executing %s: %w", runtime.BabeAPIGenerateKeyOwnershipProof, err) } - keyOwnershipProof := types.OpaqueKeyOwnershipProof{} + var keyOwnershipProof *types.OpaqueKeyOwnershipProof err = scale.Unmarshal(encodedKeyOwnershipProof, &keyOwnershipProof) if err != nil { return nil, fmt.Errorf("scale decoding key ownership proof: %w", err) } - return keyOwnershipProof, nil + // TODO check with team if returning error is preferred or should we keep just returning empty value + if keyOwnershipProof == nil { + return nil, nil + } + + return *keyOwnershipProof, nil } // BabeSubmitReportEquivocationUnsignedExtrinsic reports equivocation report to the runtime. @@ -297,13 +305,17 @@ func (in *Instance) GrandpaGenerateKeyOwnershipProof(authSetID uint64, authority return nil, err } - keyOwnershipProof := types.GrandpaOpaqueKeyOwnershipProof{} + var keyOwnershipProof *types.GrandpaOpaqueKeyOwnershipProof err = scale.Unmarshal(encodedOpaqueKeyOwnershipProof, &keyOwnershipProof) if err != nil { return nil, fmt.Errorf("scale decoding: %w", err) } - return keyOwnershipProof, nil + if keyOwnershipProof == nil { + return nil, nil + } + + return *keyOwnershipProof, nil } // GrandpaSubmitReportEquivocationUnsignedExtrinsic reports an equivocation report to the runtime. diff --git a/lib/runtime/wasmer/exports_test.go b/lib/runtime/wasmer/exports_test.go index a6da3188ac..7303e6a3e7 100644 --- a/lib/runtime/wasmer/exports_test.go +++ b/lib/runtime/wasmer/exports_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 ChainSafe Systems (ON) +// Copyright 2023 ChainSafe Systems (ON) // SPDX-License-Identifier: LGPL-3.0-only package wasmer @@ -6,6 +6,7 @@ package wasmer import ( "bytes" "encoding/json" + "github.com/centrifuge/go-substrate-rpc-client/v4/signature" "math/big" "os" "testing" @@ -21,7 +22,6 @@ import ( "github.com/ChainSafe/gossamer/lib/trie" "github.com/ChainSafe/gossamer/lib/utils" "github.com/ChainSafe/gossamer/pkg/scale" - "github.com/centrifuge/go-substrate-rpc-client/v4/signature" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -161,7 +161,7 @@ func balanceKey(t *testing.T, pub []byte) []byte { return append(append(append(h0, h1...), h2...), pub...) } -func TestNodeRuntime_ValidateTransaction(t *testing.T) { +func TestWestendRuntime_ValidateTransaction(t *testing.T) { genesisPath := utils.GetWestendDevRawGenesisPath(t) gen := genesisFromRawJSON(t, genesisPath) genTrie, err := NewTrieFromGenesis(gen) @@ -316,8 +316,9 @@ func TestInstance_BabeGenerateKeyOwnershipProof(t *testing.T) { authorityID := babeConfig.GenesisAuthorities[0].Key const slot = uint64(10) - _, err = rt.BabeGenerateKeyOwnershipProof(slot, authorityID) + res, err := rt.BabeGenerateKeyOwnershipProof(slot, authorityID) require.NoError(t, err) + require.Nil(t, res) }) } } @@ -506,6 +507,22 @@ func TestInstance_ExecuteBlock_PolkadotRuntime(t *testing.T) { require.NoError(t, err) } +// TODO fix +//func TestInstance_ExecuteBlock_PolkadotRuntime(t *testing.T) { +// DefaultTestLogLvl = 0 +// +// instance := NewTestInstance(t, runtime.POLKADOT_RUNTIME) +// +// block := runtime.InitializeRuntimeToTest(t, instance, &types.Header{}) +// +// // reset state back to parent state before executing +// parentState := storage.NewTrieState(nil) +// instance.SetContextStorage(parentState) +// +// _, err := instance.ExecuteBlock(block) +// require.NoError(t, err) +//} + func TestInstance_ExecuteBlock_PolkadotRuntime_PolkadotBlock1(t *testing.T) { genesisPath := utils.GetPolkadotGenesisPath(t) gen := genesisFromRawJSON(t, genesisPath) @@ -1103,10 +1120,10 @@ func TestInstance_GrandpaGenerateKeyOwnershipProof(t *testing.T) { identityPubKey, _ := ed25519.NewPublicKey(identity) authorityID := identityPubKey.AsBytes() - encodedOpaqueKeyOwnershipProof, err := instance.GrandpaGenerateKeyOwnershipProof(uint64(0), authorityID) - require.NoError(t, err) + res, err := instance.GrandpaGenerateKeyOwnershipProof(uint64(0), authorityID) // Since the input is not valid with respect to the instance, an empty proof is returned - require.Empty(t, encodedOpaqueKeyOwnershipProof) + require.NoError(t, err) + require.Nil(t, res) } func TestInstance_GrandpaSubmitReportEquivocationUnsignedExtrinsic(t *testing.T) { diff --git a/lib/runtime/wasmer/genesis_test.go b/lib/runtime/wasmer/genesis_test.go index b5e93df355..6f74c1801e 100644 --- a/lib/runtime/wasmer/genesis_test.go +++ b/lib/runtime/wasmer/genesis_test.go @@ -1,4 +1,4 @@ -// Copyright 2022 ChainSafe Systems (ON) +// Copyright 2023 ChainSafe Systems (ON) // SPDX-License-Identifier: LGPL-3.0-only package wasmer diff --git a/lib/runtime/wasmer/helpers_test.go b/lib/runtime/wasmer/helpers_test.go index 6e6f5fc941..38fb5e6946 100644 --- a/lib/runtime/wasmer/helpers_test.go +++ b/lib/runtime/wasmer/helpers_test.go @@ -5,15 +5,17 @@ package wasmer import ( "encoding/json" + "github.com/stretchr/testify/assert" + "errors" "math" - "os" - "path/filepath" - "testing" "github.com/ChainSafe/gossamer/lib/genesis" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "os" + "path/filepath" + "testing" ) func genesisFromRawJSON(t *testing.T, jsonFilepath string) (gen genesis.Genesis) { diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index 04943208ae..1b9bf7ce10 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -652,7 +652,7 @@ func ext_crypto_sr25519_verify_version_1(env interface{}, args []wasmer.Value) ( pub, err := sr25519.NewPublicKey(memory[key : key+32]) if err != nil { logger.Error("invalid sr25519 public key") - return []wasmer.Value{wasmer.NewI32(0)}, nil //nolint + return []wasmer.Value{wasmer.NewI32(0)}, nil } logger.Debugf( @@ -703,7 +703,7 @@ func ext_crypto_sr25519_verify_version_2(env interface{}, args []wasmer.Value) ( pub, err := sr25519.NewPublicKey(memory[key : key+32]) if err != nil { logger.Error("invalid sr25519 public key") - return []wasmer.Value{wasmer.NewI32(0)}, nil //nolint + return []wasmer.Value{wasmer.NewI32(0)}, nil } logger.Debugf( diff --git a/lib/runtime/wasmer/imports_test.go b/lib/runtime/wasmer/imports_test.go index 1bc47992b6..351dff53c7 100644 --- a/lib/runtime/wasmer/imports_test.go +++ b/lib/runtime/wasmer/imports_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 ChainSafe Systems (ON) +// Copyright 2023 ChainSafe Systems (ON) // SPDX-License-Identifier: LGPL-3.0-only package wasmer @@ -1572,6 +1572,7 @@ func Test_ext_default_child_storage_storage_kill_version_3(t *testing.T) { errMsg string }{ { + // TODO this test case is causing grief key: []byte(`fakekey`), limit: optLimit2, expected: []byte{0, 0, 0, 0, 0}, diff --git a/lib/runtime/wasmer/instance_test.go b/lib/runtime/wasmer/instance_test.go index e2f20d3410..f2d9a84270 100644 --- a/lib/runtime/wasmer/instance_test.go +++ b/lib/runtime/wasmer/instance_test.go @@ -5,12 +5,11 @@ package wasmer import ( "context" - "os" - "testing" - "github.com/ChainSafe/gossamer/lib/runtime" "github.com/klauspost/compress/zstd" "github.com/stretchr/testify/require" + "os" + "testing" ) // test used for ensuring runtime exec calls can be made concurrently diff --git a/lib/runtime/wasmer/test_helpers.go b/lib/runtime/wasmer/test_helpers.go index ac5c5a900d..a8b87fa7b7 100644 --- a/lib/runtime/wasmer/test_helpers.go +++ b/lib/runtime/wasmer/test_helpers.go @@ -5,8 +5,6 @@ package wasmer import ( "context" - "testing" - "github.com/ChainSafe/gossamer/internal/log" "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/keystore" @@ -16,6 +14,7 @@ import ( "github.com/ChainSafe/gossamer/lib/trie" "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "testing" ) // DefaultTestLogLvl is the log level used for test runtime instances