From 14dda74c86ab08751ca1bb6ed9725b0031c88343 Mon Sep 17 00:00:00 2001 From: Kishan Sagathiya Date: Fri, 7 Oct 2022 23:32:00 +0800 Subject: [PATCH] Implement parachain inherents (#2566) - Added support for parachain inherent and newheads - Improved inherentsData's encode function - Made inherent identifers enums - Common setInherent function --- dot/sync/test_helpers.go | 6 +- dot/types/babe_digest.go | 6 +- dot/types/consensus_digest.go | 16 +- dot/types/digest.go | 8 +- dot/types/inherents.go | 108 ++++++--- dot/types/inherents_test.go | 45 ++++ lib/babe/build.go | 26 +- lib/babe/build_integration_test.go | 10 +- lib/babe/errors.go | 34 +-- lib/babe/parachain_inherents.go | 345 +++++++++++++++++++++++++++ lib/babe/parachain_inherents_test.go | 301 +++++++++++++++++++++++ lib/grandpa/message.go | 12 +- lib/runtime/constants.go | 5 + lib/runtime/test_helpers.go | 9 +- lib/runtime/wasmer/imports.go | 6 +- tests/stress/grandpa_test.go | 6 +- 16 files changed, 849 insertions(+), 94 deletions(-) create mode 100644 dot/types/inherents_test.go create mode 100644 lib/babe/parachain_inherents.go create mode 100644 lib/babe/parachain_inherents_test.go diff --git a/dot/sync/test_helpers.go b/dot/sync/test_helpers.go index 5766bd5dec..8dd6897265 100644 --- a/dot/sync/test_helpers.go +++ b/dot/sync/test_helpers.go @@ -29,11 +29,11 @@ func BuildBlock(t *testing.T, instance runtime.Instance, parent *types.Header, e err = instance.InitializeBlock(header) require.NoError(t, err) - idata := types.NewInherentsData() - err = idata.SetInt64Inherent(types.Timstap0, uint64(time.Now().Unix())) + idata := types.NewInherentData() + err = idata.SetInherent(types.Timstap0, uint64(time.Now().Unix())) require.NoError(t, err) - err = idata.SetInt64Inherent(types.Babeslot, 1) + err = idata.SetInherent(types.Babeslot, uint64(1)) require.NoError(t, err) ienc, err := idata.Encode() diff --git a/dot/types/babe_digest.go b/dot/types/babe_digest.go index 6e404300d0..6826c5cf4e 100644 --- a/dot/types/babe_digest.go +++ b/dot/types/babe_digest.go @@ -61,7 +61,7 @@ func (d *BabePrimaryPreDigest) ToPreRuntimeDigest() (*PreRuntimeDigest, error) { return toPreRuntimeDigest(*d) } -// Index Returns VDT index +// Index returns VDT index func (BabePrimaryPreDigest) Index() uint { return 1 } // BabeSecondaryPlainPreDigest is included in a block built by a secondary slot authorized producer @@ -83,7 +83,7 @@ func (d *BabeSecondaryPlainPreDigest) ToPreRuntimeDigest() (*PreRuntimeDigest, e return toPreRuntimeDigest(*d) } -// Index Returns VDT index +// Index returns VDT index func (BabeSecondaryPlainPreDigest) Index() uint { return 2 } // BabeSecondaryVRFPreDigest is included in a block built by a secondary slot authorized producer @@ -111,7 +111,7 @@ func (d *BabeSecondaryVRFPreDigest) ToPreRuntimeDigest() (*PreRuntimeDigest, err return toPreRuntimeDigest(*d) } -// Index Returns VDT index +// Index returns VDT index func (BabeSecondaryVRFPreDigest) Index() uint { return 3 } // toPreRuntimeDigest returns the VaryingDataTypeValue as a PreRuntimeDigest diff --git a/dot/types/consensus_digest.go b/dot/types/consensus_digest.go index 6a4dc219e8..2de9de9e28 100644 --- a/dot/types/consensus_digest.go +++ b/dot/types/consensus_digest.go @@ -26,7 +26,7 @@ type GrandpaScheduledChange struct { Delay uint32 } -// Index Returns VDT index +// Index returns VDT index func (GrandpaScheduledChange) Index() uint { return 1 } // GrandpaForcedChange represents a GRANDPA forced authority change @@ -39,7 +39,7 @@ type GrandpaForcedChange struct { Delay uint32 } -// Index Returns VDT index +// Index returns VDT index func (GrandpaForcedChange) Index() uint { return 2 } // GrandpaOnDisabled represents a GRANDPA authority being disabled @@ -47,7 +47,7 @@ type GrandpaOnDisabled struct { ID uint64 } -// Index Returns VDT index +// Index returns VDT index func (GrandpaOnDisabled) Index() uint { return 3 } // GrandpaPause represents an authority set pause @@ -55,7 +55,7 @@ type GrandpaPause struct { Delay uint32 } -// Index Returns VDT index +// Index returns VDT index func (GrandpaPause) Index() uint { return 4 } // GrandpaResume represents an authority set resume @@ -63,7 +63,7 @@ type GrandpaResume struct { Delay uint32 } -// Index Returns VDT index +// Index returns VDT index func (GrandpaResume) Index() uint { return 5 } // NextEpochData is the digest that contains the data for the upcoming BABE epoch. @@ -73,7 +73,7 @@ type NextEpochData struct { Randomness [RandomnessLength]byte } -// Index Returns VDT index +// Index returns VDT index func (NextEpochData) Index() uint { return 1 } func (d NextEpochData) String() string { @@ -98,7 +98,7 @@ type BABEOnDisabled struct { ID uint32 } -// Index Returns VDT index +// Index returns VDT index func (BABEOnDisabled) Index() uint { return 2 } // NextConfigData is the digest that contains changes to the BABE configuration. @@ -109,7 +109,7 @@ type NextConfigData struct { SecondarySlots byte } -// Index Returns VDT index +// Index returns VDT index func (NextConfigData) Index() uint { return 3 } // ToConfigData returns the NextConfigData as ConfigData diff --git a/dot/types/digest.go b/dot/types/digest.go index 2d156cca45..899ef58500 100644 --- a/dot/types/digest.go +++ b/dot/types/digest.go @@ -44,7 +44,7 @@ type ChangesTrieRootDigest struct { Hash common.Hash } -// Index Returns VDT index +// Index returns VDT index func (ChangesTrieRootDigest) Index() uint { return 2 } // String returns the digest as a string @@ -58,7 +58,7 @@ type PreRuntimeDigest struct { Data []byte } -// Index Returns VDT index +// Index returns VDT index func (PreRuntimeDigest) Index() uint { return 6 } // NewBABEPreRuntimeDigest returns a PreRuntimeDigest with the BABE consensus ID @@ -80,7 +80,7 @@ type ConsensusDigest struct { Data []byte } -// Index Returns VDT index +// Index returns VDT index func (ConsensusDigest) Index() uint { return 4 } // String returns the digest as a string @@ -94,7 +94,7 @@ type SealDigest struct { Data []byte } -// Index Returns VDT index +// Index returns VDT index func (SealDigest) Index() uint { return 5 } // String returns the digest as a string diff --git a/dot/types/inherents.go b/dot/types/inherents.go index 9c199a03c7..ab13b8e07e 100644 --- a/dot/types/inherents.go +++ b/dot/types/inherents.go @@ -5,68 +5,87 @@ package types import ( "bytes" - "encoding/binary" - "errors" "fmt" "math/big" + "sort" "github.com/ChainSafe/gossamer/pkg/scale" ) -var ( - // Timstap0 is an inherent key. - Timstap0 = []byte("timstap0") - // Babeslot is an inherent key. - Babeslot = []byte("babeslot") - // Uncles00 is an inherent key. - Uncles00 = []byte("uncles00") +// InherentIdentifier is an identifier for an inherent. +type InherentIdentifier uint + +const ( + // Timstap0 is the identifier for the `timestamp` inherent. + Timstap0 InherentIdentifier = iota + // Babeslot is the BABE inherent identifier. + Babeslot + // Uncles00 is the identifier for the `uncles` inherent. + Uncles00 + // Parachn0 is an inherent key for parachains inherent. + Parachn0 + // Newheads is an inherent key for new minimally-attested parachain heads. + Newheads ) -// InherentsData contains a mapping of inherent keys to values +// Bytes returns a byte array of given inherent identifier. +func (ii InherentIdentifier) Bytes() [8]byte { + + kb := [8]byte{} + switch ii { + case Timstap0: + copy(kb[:], []byte("timstap0")) + case Babeslot: + copy(kb[:], []byte("babeslot")) + case Uncles00: + copy(kb[:], []byte("uncles00")) + case Parachn0: + copy(kb[:], []byte("parachn0")) + case Newheads: + copy(kb[:], []byte("newheads")) + default: + panic("invalid inherent identifier") + } + + return kb +} + +// InherentData contains a mapping of inherent keys to values // keys must be 8 bytes, values are a scale-encoded byte array -type InherentsData struct { - data map[[8]byte]([]byte) +type InherentData struct { + Data map[[8]byte][]byte } -// NewInherentsData returns InherentsData -func NewInherentsData() *InherentsData { - return &InherentsData{ - data: make(map[[8]byte]([]byte)), +// NewInherentData returns InherentData +func NewInherentData() *InherentData { + return &InherentData{ + Data: make(map[[8]byte][]byte), } } -func (d *InherentsData) String() string { +func (d *InherentData) String() string { str := "" - for k, v := range d.data { + for k, v := range d.Data { str = str + fmt.Sprintf("key=%v\tvalue=%v\n", k, v) } return str } -// SetInt64Inherent set an inherent of type uint64 -func (d *InherentsData) SetInt64Inherent(key []byte, data uint64) error { - if len(key) != 8 { - return errors.New("inherent key must be 8 bytes") - } - - val := make([]byte, 8) - binary.LittleEndian.PutUint64(val, data) - - venc, err := scale.Marshal(val) +// SetInherent sets a inherent. +func (d *InherentData) SetInherent(inherentIdentifier InherentIdentifier, value any) error { + data, err := scale.Marshal(value) if err != nil { return err } - kb := [8]byte{} - copy(kb[:], key) + d.Data[inherentIdentifier.Bytes()] = data - d.data[kb] = venc return nil } // Encode will encode a given []byte using scale.Encode -func (d *InherentsData) Encode() ([]byte, error) { - length := big.NewInt(int64(len(d.data))) +func (d *InherentData) Encode() ([]byte, error) { + length := big.NewInt(int64(len(d.Data))) buffer := bytes.Buffer{} l, err := scale.Marshal(length) @@ -79,15 +98,32 @@ func (d *InherentsData) Encode() ([]byte, error) { return nil, err } - for k, v := range d.data { - _, err = buffer.Write(k[:]) + keys := [][8]byte{} + for key := range d.Data { + keys = append(keys, key) + } + + sort.Slice(keys, func(i, j int) bool { + return bytes.Compare(keys[i][:], keys[j][:]) < 0 + }) + + for _, key := range keys { + v := d.Data[key] + + _, err = buffer.Write(key[:]) if err != nil { return nil, err } - _, err = buffer.Write(v) + + venc, err := scale.Marshal(v) + if err != nil { + return nil, fmt.Errorf("scale encoding encoded value: %w", err) + } + _, err = buffer.Write(venc) if err != nil { return nil, err } } + return buffer.Bytes(), nil } diff --git a/dot/types/inherents_test.go b/dot/types/inherents_test.go new file mode 100644 index 0000000000..52c7d3f4e3 --- /dev/null +++ b/dot/types/inherents_test.go @@ -0,0 +1,45 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestInherentDataMarshal(t *testing.T) { + tests := []struct { + name string + getInherentData func(t *testing.T) *InherentData + want []byte + }{ + { + /* + let mut data = InherentData::new(); + let timestamp: u64 = 99; + data.put_data(*b"babeslot", ×tamp).unwrap(); + data.put_data(*b"timstap0", ×tamp).unwrap(); + */ + getInherentData: func(t *testing.T) *InherentData { + id := NewInherentData() + err := id.SetInherent(Babeslot, uint64(99)) + require.NoError(t, err) + + err = id.SetInherent(Timstap0, uint64(99)) + require.NoError(t, err) + return id + }, + want: []byte{8, 98, 97, 98, 101, 115, 108, 111, 116, 32, 99, 0, 0, 0, 0, 0, 0, 0, 116, 105, 109, 115, 116, 97, 112, 48, 32, 99, 0, 0, 0, 0, 0, 0, 0}, //nolint:lll + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + idata := tt.getInherentData(t) + got, err := idata.Encode() + require.NoError(t, err) + require.Equal(t, tt.want, got) + }) + } +} diff --git a/lib/babe/build.go b/lib/babe/build.go index 024e210988..2d691ed004 100644 --- a/lib/babe/build.go +++ b/lib/babe/build.go @@ -97,7 +97,7 @@ func (b *BlockBuilder) buildBlock(parent *types.Header, slot Slot, rt runtime.In logger.Trace("initialised block") // add block inherents - inherents, err := buildBlockInherents(slot, rt) + inherents, err := buildBlockInherents(slot, rt, parent) if err != nil { return nil, fmt.Errorf("cannot build inherents: %s", err) } @@ -226,21 +226,37 @@ func (b *BlockBuilder) buildBlockExtrinsics(slot Slot, rt runtime.Instance) []*t return included } -func buildBlockInherents(slot Slot, rt runtime.Instance) ([][]byte, error) { +func buildBlockInherents(slot Slot, rt runtime.Instance, parent *types.Header) ([][]byte, error) { // Setup inherents: add timstap0 - idata := types.NewInherentsData() + idata := types.NewInherentData() timestamp := uint64(time.Now().UnixMilli()) - err := idata.SetInt64Inherent(types.Timstap0, timestamp) + err := idata.SetInherent(types.Timstap0, timestamp) if err != nil { return nil, err } // add babeslot - err = idata.SetInt64Inherent(types.Babeslot, slot.number) + err = idata.SetInherent(types.Babeslot, slot.number) if err != nil { return nil, err } + parachainInherent := ParachainInherentData{ + ParentHeader: *parent, + } + + // add parachn0 and newheads + // for now we can use "empty" values, as we require parachain-specific + // logic to actually provide the data. + + if err = idata.SetInherent(types.Parachn0, parachainInherent); err != nil { + return nil, fmt.Errorf("setting inherent %q: %w", types.Parachn0, err) + } + + if err = idata.SetInherent(types.Newheads, []byte{0}); err != nil { + return nil, fmt.Errorf("setting inherent %q: %w", types.Newheads, err) + } + ienc, err := idata.Encode() if err != nil { return nil, err diff --git a/lib/babe/build_integration_test.go b/lib/babe/build_integration_test.go index 3b0da69920..8c8ba94ac5 100644 --- a/lib/babe/build_integration_test.go +++ b/lib/babe/build_integration_test.go @@ -18,7 +18,7 @@ import ( "github.com/ChainSafe/gossamer/pkg/scale" cscale "github.com/centrifuge/go-substrate-rpc-client/v4/scale" - "github.com/centrifuge/go-substrate-rpc-client/v4/signature" + signaturev4 "github.com/centrifuge/go-substrate-rpc-client/v4/signature" ctypes "github.com/centrifuge/go-substrate-rpc-client/v4/types" "github.com/centrifuge/go-substrate-rpc-client/v4/types/codec" "github.com/ethereum/go-ethereum/metrics" @@ -146,6 +146,8 @@ func TestApplyExtrinsic(t *testing.T) { require.NoError(t, err) parentHash := babeService.blockState.GenesisHash() + parentHeader, err := babeService.blockState.GetHeader(parentHash) + require.NoError(t, err) rt, err := babeService.blockState.GetRuntime(nil) require.NoError(t, err) @@ -171,7 +173,7 @@ func TestApplyExtrinsic(t *testing.T) { err = rt.InitializeBlock(header) require.NoError(t, err) - _, err = buildBlockInherents(slot, rt) + _, err = buildBlockInherents(slot, rt, parentHeader) require.NoError(t, err) header1, err := rt.FinalizeBlock() @@ -189,7 +191,7 @@ func TestApplyExtrinsic(t *testing.T) { err = rt.InitializeBlock(header2) require.NoError(t, err) - _, err = buildBlockInherents(slot, rt) + _, err = buildBlockInherents(slot, rt, parentHeader) require.NoError(t, err) res, err := rt.ApplyExtrinsic(extBytes) @@ -251,7 +253,7 @@ func TestBuildAndApplyExtrinsic(t *testing.T) { } // Sign the transaction using Alice's default account - err = ext.Sign(signature.TestKeyringPairAlice, o) + err = ext.Sign(signaturev4.TestKeyringPairAlice, o) require.NoError(t, err) extEnc := bytes.Buffer{} diff --git a/lib/babe/errors.go b/lib/babe/errors.go index 32cf9378cb..1017bed595 100644 --- a/lib/babe/errors.go +++ b/lib/babe/errors.go @@ -126,19 +126,19 @@ func (e UnmarshalError) Error() string { // Other Some error occurred type Other string -// Index Returns VDT index +// Index returns VDT index func (Other) Index() uint { return 0 } // CannotLookup Failed to lookup some data type CannotLookup struct{} -// Index Returns VDT index +// Index returns VDT index func (CannotLookup) Index() uint { return 1 } // BadOrigin A bad origin type BadOrigin struct{} -// Index Returns VDT index +// Index returns VDT index func (BadOrigin) Index() uint { return 2 } // Module A custom error in a module @@ -148,7 +148,7 @@ type Module struct { Message *string } -// Index Returns VDT index +// Index returns VDT index func (Module) Index() uint { return 3 } func (err Module) string() string { @@ -158,79 +158,79 @@ func (err Module) string() string { // ValidityCannotLookup Could not lookup some information that is required to validate the transaction type ValidityCannotLookup struct{} -// Index Returns VDT index +// Index returns VDT index func (ValidityCannotLookup) Index() uint { return 0 } // NoUnsignedValidator No validator found for the given unsigned transaction type NoUnsignedValidator struct{} -// Index Returns VDT index +// Index returns VDT index func (NoUnsignedValidator) Index() uint { return 1 } // UnknownCustom Any other custom unknown validity that is not covered type UnknownCustom uint8 -// Index Returns VDT index +// Index returns VDT index func (UnknownCustom) Index() uint { return 2 } // Call The call of the transaction is not expected type Call struct{} -// Index Returns VDT index +// Index returns VDT index func (Call) Index() uint { return 0 } // Payment General error to do with the inability to pay some fees (e.g. account balance too low) type Payment struct{} -// Index Returns VDT index +// Index returns VDT index func (Payment) Index() uint { return 1 } // Future General error to do with the transaction not yet being valid (e.g. nonce too high) type Future struct{} -// Index Returns VDT index +// Index returns VDT index func (Future) Index() uint { return 2 } // Stale General error to do with the transaction being outdated (e.g. nonce too low) type Stale struct{} -// Index Returns VDT index +// Index returns VDT index func (Stale) Index() uint { return 3 } // BadProof General error to do with the transaction’s proofs (e.g. signature) type BadProof struct{} -// Index Returns VDT index +// Index returns VDT index func (BadProof) Index() uint { return 4 } // AncientBirthBlock The transaction birth block is ancient type AncientBirthBlock struct{} -// Index Returns VDT index +// Index returns VDT index func (AncientBirthBlock) Index() uint { return 5 } // ExhaustsResources The transaction would exhaust the resources of current block type ExhaustsResources struct{} -// Index Returns VDT index +// Index returns VDT index func (ExhaustsResources) Index() uint { return 6 } // InvalidCustom Any other custom invalid validity that is not covered type InvalidCustom uint8 -// Index Returns VDT index +// Index returns VDT index func (InvalidCustom) Index() uint { return 7 } // BadMandatory An extrinsic with a Mandatory dispatch resulted in Error type BadMandatory struct{} -// Index Returns VDT index +// Index returns VDT index func (BadMandatory) Index() uint { return 8 } // MandatoryDispatch A transaction with a mandatory dispatch type MandatoryDispatch struct{} -// Index Returns VDT index +// Index returns VDT index func (MandatoryDispatch) Index() uint { return 9 } func determineErrType(vdt scale.VaryingDataType) error { diff --git a/lib/babe/parachain_inherents.go b/lib/babe/parachain_inherents.go new file mode 100644 index 0000000000..afdf8c518d --- /dev/null +++ b/lib/babe/parachain_inherents.go @@ -0,0 +1,345 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package babe + +import ( + "fmt" + + "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/pkg/scale" +) + +// signature could be one of Ed25519 signature, Sr25519 signature or ECDSA/SECP256k1 signature. +type signature [64]byte + +// validityAttestation is an implicit or explicit attestation to the validity of a parachain +// candidate. +type validityAttestation scale.VaryingDataType + +// Set will set a VaryingDataTypeValue using the underlying VaryingDataType +func (va *validityAttestation) Set(val scale.VaryingDataTypeValue) (err error) { + // cast to VaryingDataType to use VaryingDataType.Set method + vdt := scale.VaryingDataType(*va) + err = vdt.Set(val) + if err != nil { + return fmt.Errorf("setting value to varying data type: %w", err) + } + // store original ParentVDT with VaryingDataType that has been set + *va = validityAttestation(vdt) + return nil +} + +// Value returns the value from the underlying VaryingDataType +func (va *validityAttestation) Value() (scale.VaryingDataTypeValue, error) { + vdt := scale.VaryingDataType(*va) + return vdt.Value() +} + +// implicit is for implicit attestation. +type implicit validatorSignature //skipcq + +// Index returns VDT index +func (implicit) Index() uint { //skipcq + return 1 +} + +// explicit is for explicit attestation. +type explicit validatorSignature //skipcq + +// Index returns VDT index +func (explicit) Index() uint { //skipcq + return 2 +} + +// newValidityAttestation creates a ValidityAttestation varying data type. +func newValidityAttestation() validityAttestation { //skipcq + vdt, err := scale.NewVaryingDataType(implicit{}, explicit{}) + if err != nil { + panic(err) + } + + return validityAttestation(vdt) +} + +// disputeStatement is a statement about a candidate, to be used within the dispute +// resolution process. Statements are either in favour of the candidate's validity +// or against it. +type disputeStatement scale.VaryingDataType + +// Set will set a VaryingDataTypeValue using the underlying VaryingDataType +func (d *disputeStatement) Set(val scale.VaryingDataTypeValue) (err error) { + // cast to VaryingDataType to use VaryingDataType.Set method + vdt := scale.VaryingDataType(*d) + err = vdt.Set(val) + if err != nil { + return fmt.Errorf("setting value to varying data type: %w", err) + } + // store original ParentVDT with VaryingDataType that has been set + *d = disputeStatement(vdt) + return nil +} + +// Value will return value from underying VaryingDataType +func (d *disputeStatement) Value() (scale.VaryingDataTypeValue, error) { + vdt := scale.VaryingDataType(*d) + return vdt.Value() +} + +// validDisputeStatementKind is a kind of statements of validity on a candidate. +type validDisputeStatementKind scale.VaryingDataType //skipcq + +// Index returns VDT index +func (validDisputeStatementKind) Index() uint { //skipcq + return 0 +} + +// Set will set a VaryingDataTypeValue using the underlying VaryingDataType +func (v *validDisputeStatementKind) Set(val scale.VaryingDataTypeValue) (err error) { //skipcq + // cast to VaryingDataType to use VaryingDataType.Set method + vdt := scale.VaryingDataType(*v) + err = vdt.Set(val) + if err != nil { + return fmt.Errorf("setting value to varying data type: %w", err) + } + // store original ParentVDT with VaryingDataType that has been set + *v = validDisputeStatementKind(vdt) + return nil +} + +// Value will return value from underying VaryingDataType +func (v *validDisputeStatementKind) Value() (scale.VaryingDataTypeValue, error) { //skipcq + vdt := scale.VaryingDataType(*v) + return vdt.Value() +} + +// ExplicitValidDisputeStatementKind is an explicit statement issued as part of a dispute. +type explicitValidDisputeStatementKind struct{} //skipcq + +// Index returns VDT index +func (explicitValidDisputeStatementKind) Index() uint { //skipcq + return 0 +} + +// backingSeconded is a seconded statement on a candidate from the backing phase. +type backingSeconded common.Hash //skipcq + +// Index returns VDT index +func (backingSeconded) Index() uint { //skipcq + return 1 +} + +// backingValid is a valid statement on a candidate from the backing phase. +type backingValid common.Hash //skipcq + +// Index returns VDT index +func (backingValid) Index() uint { //skipcq + return 2 +} + +// approvalChecking is an approval vote from the approval checking phase. +type approvalChecking struct{} //skipcq + +// Index returns VDT index +func (approvalChecking) Index() uint { //skipcq + return 3 +} + +// invalidDisputeStatementKind is a kind of statements of invalidity on a candidate. +type invalidDisputeStatementKind scale.VaryingDataType //skipcq + +// Index returns VDT index +func (invalidDisputeStatementKind) Index() uint { //skipcq + return 1 +} + +// Set will set a VaryingDataTypeValue using the underlying VaryingDataType +func (in *invalidDisputeStatementKind) Set(val scale.VaryingDataTypeValue) (err error) { //skipcq + // cast to VaryingDataType to use VaryingDataType.Set method + vdt := scale.VaryingDataType(*in) + err = vdt.Set(val) + if err != nil { + return fmt.Errorf("setting value to varying data type: %w", err) + } + // store original ParentVDT with VaryingDataType that has been set + *in = invalidDisputeStatementKind(vdt) + return nil +} + +// Value will return value from underying VaryingDataType +func (in *invalidDisputeStatementKind) Value() (scale.VaryingDataTypeValue, error) { //skipcq + vdt := scale.VaryingDataType(*in) + return vdt.Value() +} + +// explicitInvalidDisputeStatementKind is an explicit statement issued as part of a dispute. +type explicitInvalidDisputeStatementKind struct{} //skipcq + +// Index returns VDT index +func (explicitInvalidDisputeStatementKind) Index() uint { //skipcq + return 0 +} + +// newDisputeStatement create a new DisputeStatement varying data type. +func newDisputeStatement() disputeStatement { //skipcq + idsKind, err := scale.NewVaryingDataType(explicitInvalidDisputeStatementKind{}) + if err != nil { + panic(err) + } + + vdsKind, err := scale.NewVaryingDataType( + explicitValidDisputeStatementKind{}, backingSeconded{}, backingValid{}, approvalChecking{}) + if err != nil { + panic(err) + } + + vdt, err := scale.NewVaryingDataType( + validDisputeStatementKind(vdsKind), invalidDisputeStatementKind(idsKind)) + if err != nil { + panic(err) + } + + return disputeStatement(vdt) +} + +// collatorID is the collator's relay-chain account ID +type collatorID []byte + +// collatorSignature is the signature on a candidate's block data signed by a collator. +type collatorSignature signature + +// validationCodeHash is the blake2-256 hash of the validation code bytes. +type validationCodeHash common.Hash + +// candidateDescriptor is a unique descriptor of the candidate receipt. +type candidateDescriptor struct { + // The ID of the para this is a candidate for. + ParaID uint32 `scale:"1"` + + // RelayParent is the hash of the relay-chain block this should be executed in + // the context of. + // NOTE: the fact that the hash includes this value means that code depends + // on this for deduplication. Removing this field is likely to break things. + RelayParent common.Hash `scale:"2"` + + // Collator is the collator's relay-chain account ID + Collator collatorID `scale:"3"` + + // PersistedValidationDataHash is the blake2-256 hash of the persisted validation data. This is extra data derived from + // relay-chain state which may vary based on bitfields included before the candidate. + // Thus it cannot be derived entirely from the relay-parent. + PersistedValidationDataHash common.Hash `scale:"4"` + + // PovHash is the hash of the `pov-block`. + PovHash common.Hash `scale:"5"` + // ErasureRoot is the root of a block's erasure encoding Merkle tree. + ErasureRoot common.Hash `scale:"6"` + + // Signature on blake2-256 of components of this receipt: + // The parachain index, the relay parent, the validation data hash, and the `pov_hash`. + Signature collatorSignature `scale:"7"` + + // ParaHead is the hash of the para header that is being generated by this candidate. + ParaHead common.Hash `scale:"8"` + // ValidationCodeHash is the blake2-256 hash of the validation code bytes. + ValidationCodeHash validationCodeHash `scale:"9"` +} + +// upwardMessage is a message from a parachain to its Relay Chain. +type upwardMessage []byte + +// outboundHrmpMessage is an HRMP message seen from the perspective of a sender. +type outboundHrmpMessage struct { + Recipient uint32 `scale:"1"` + Data []byte `scale:"2"` +} + +// validationCode is Parachain validation code. +type validationCode []byte + +// headData is Parachain head data included in the chain. +type headData []byte + +// candidateCommitments are Commitments made in a `CandidateReceipt`. Many of these are outputs of validation. +type candidateCommitments struct { + // Messages destined to be interpreted by the Relay chain itself. + UpwardMessages []upwardMessage `scale:"1"` + // Horizontal messages sent by the parachain. + HorizontalMessages []outboundHrmpMessage `scale:"2"` + // New validation code. + NewValidationCode *validationCode `scale:"3"` + // The head-data produced as a result of execution. + HeadData headData `scale:"4"` + // The number of messages processed from the DMQ. + ProcessedDownwardMessages uint32 `scale:"5"` + // The mark which specifies the block number up to which all inbound HRMP messages are processed. + HrmpWatermark uint32 `scale:"6"` +} + +// committedCandidateReceipt is a candidate-receipt with commitments directly included. +type committedCandidateReceipt struct { + Descriptor candidateDescriptor `scale:"1"` + Commitments candidateCommitments `scale:"2"` +} + +// uncheckedSignedAvailabilityBitfield is a set of unchecked signed availability bitfields. +// Should be sorted by validator index, ascending. +type uncheckedSignedAvailabilityBitfield struct { + // The payload is part of the signed data. The rest is the signing context, + // which is known both at signing and at validation. + Payload []byte `scale:"1"` + // The index of the validator signing this statement. + ValidatorIndex uint32 `scale:"2"` + // The signature by the validator of the signed payload. + Signature signature `scale:"3"` +} + +// backedCandidate is a backed (or backable, depending on context) candidate. +type backedCandidate struct { + // The candidate referred to. + Candidate committedCandidateReceipt `scale:"1"` + // The validity votes themselves, expressed as signatures. + ValidityVotes []validityAttestation `scale:"2"` + // The indices of the validators within the group, expressed as a bitfield. + ValidatorIndices []byte `scale:"3"` +} + +// multiDisputeStatementSet is a set of dispute statements. +type multiDisputeStatementSet []disputeStatementSet + +// validatorIndex is the index of the validator. +type validatorIndex uint32 + +// validatorSignature is the signature with which parachain validators sign blocks. +type validatorSignature signature + +// statement about the candidate. +// Used as translation of `Vec<(DisputeStatement, ValidatorIndex, ValidatorSignature)>` from rust to go +type statement struct { + ValidatorIndex validatorIndex + ValidatorSignature validatorSignature + DisputeStatement disputeStatement +} + +// disputeStatementSet is a set of statements about a specific candidate. +type disputeStatementSet struct { + // The candidate referenced by this set. + CandidateHash common.Hash `scale:"1"` + // The session index of the candidate. + Session uint32 `scale:"2"` + // Statements about the candidate. + Statements []statement `scale:"3"` +} + +// ParachainInherentData is parachains inherent-data passed into the runtime by a block author. +type ParachainInherentData struct { + // Signed bitfields by validators about availability. + Bitfields []uncheckedSignedAvailabilityBitfield `scale:"1"` + // Backed candidates for inclusion in the block. + BackedCandidates []backedCandidate `scale:"2"` + // Sets of dispute votes for inclusion, + Disputes multiDisputeStatementSet `scale:"3"` + // The parent block header. Used for checking state proofs. + ParentHeader types.Header `scale:"4"` +} diff --git a/lib/babe/parachain_inherents_test.go b/lib/babe/parachain_inherents_test.go new file mode 100644 index 0000000000..75d651d9f5 --- /dev/null +++ b/lib/babe/parachain_inherents_test.go @@ -0,0 +1,301 @@ +// Copyright 2022 ChainSafe Systems (ON) +// SPDX-License-Identifier: LGPL-3.0-only + +package babe + +import ( + "testing" + + "github.com/ChainSafe/gossamer/dot/types" + "github.com/ChainSafe/gossamer/lib/common" + "github.com/ChainSafe/gossamer/pkg/scale" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestValidDisputeStatementKind(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + enumValue scale.VaryingDataTypeValue + encodingValue []byte + }{ + { + name: "ExplicitValidDisputeStatementKind", + enumValue: explicitValidDisputeStatementKind{}, + encodingValue: []byte{0x0}, + }, + { + name: "BackingSeconded", + enumValue: backingSeconded(common.Hash{1}), + encodingValue: []byte{0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, //nolint:lll + }, + { + name: "BackingValid", + enumValue: backingValid(common.Hash{1}), + encodingValue: []byte{0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, //nolint:lll + + }, + { + name: "ApprovalChecking", + enumValue: approvalChecking{}, + encodingValue: []byte{0x3}, + }, + } + + for _, c := range testCases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + vdsKind, err := scale.NewVaryingDataType( + explicitValidDisputeStatementKind{}, backingSeconded{}, backingValid{}, approvalChecking{}) + require.NoError(t, err) + + err = vdsKind.Set(c.enumValue) + require.NoError(t, err) + + bytes, err := scale.Marshal(vdsKind) + require.NoError(t, err) + + require.Equal(t, c.encodingValue, bytes) + }) + } +} + +func TestInvalidDisputeStatementKind(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + enumValue scale.VaryingDataTypeValue + encodingValue []byte + }{ + { + name: "explicitInvalidDisputeStatementKind", + enumValue: explicitInvalidDisputeStatementKind{}, + encodingValue: []byte{0x0}, + }, + } + + for _, c := range testCases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + invalidDisputeStatementKind, err := scale.NewVaryingDataType( + explicitInvalidDisputeStatementKind{}) + require.NoError(t, err) + + err = invalidDisputeStatementKind.Set(c.enumValue) + require.NoError(t, err) + + bytes, err := scale.Marshal(invalidDisputeStatementKind) + require.NoError(t, err) + + require.Equal(t, c.encodingValue, bytes) + }) + } +} + +func TestDisputeStatement(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + vdtBuilder func(t *testing.T) disputeStatement + encodingValue []byte + }{ + { + name: "Valid Explicit", + vdtBuilder: func(t *testing.T) disputeStatement { + vdsKind, err := scale.NewVaryingDataType( + explicitValidDisputeStatementKind{}, backingSeconded{}, backingValid{}, approvalChecking{}) + require.NoError(t, err) + + err = vdsKind.Set(explicitValidDisputeStatementKind{}) + require.NoError(t, err) + + ds := newDisputeStatement() + err = ds.Set(validDisputeStatementKind(vdsKind)) + require.NoError(t, err) + + return ds + }, + + encodingValue: []byte{0x0, 0x0}, + }, + { + name: "Valid ApprovalChecking", + vdtBuilder: func(t *testing.T) disputeStatement { + vdsKind, err := scale.NewVaryingDataType( + explicitValidDisputeStatementKind{}, backingSeconded{}, backingValid{}, approvalChecking{}, + ) + require.NoError(t, err) + + err = vdsKind.Set(approvalChecking{}) + require.NoError(t, err) + + ds := newDisputeStatement() + err = ds.Set(validDisputeStatementKind(vdsKind)) + require.NoError(t, err) + + return ds + }, + encodingValue: []byte{0x0, 0x3}, + }, + { + name: "Valid BackingSeconded", + vdtBuilder: func(t *testing.T) disputeStatement { + vdsKind, err := scale.NewVaryingDataType( + explicitValidDisputeStatementKind{}, backingSeconded{}, backingValid{}, approvalChecking{}, + ) + require.NoError(t, err) + + err = vdsKind.Set(backingSeconded(common.Hash{})) + require.NoError(t, err) + + ds := newDisputeStatement() + err = ds.Set(validDisputeStatementKind(vdsKind)) + require.NoError(t, err) + + return ds + }, + encodingValue: []byte{0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, //nolint:lll + + }, + { + name: "Invalid Explicit", + vdtBuilder: func(t *testing.T) disputeStatement { + idsKind, err := scale.NewVaryingDataType( + explicitInvalidDisputeStatementKind{}, + ) + require.NoError(t, err) + + err = idsKind.Set(explicitInvalidDisputeStatementKind{}) + require.NoError(t, err) + + disputeStatement := newDisputeStatement() + err = disputeStatement.Set(invalidDisputeStatementKind(idsKind)) + require.NoError(t, err) + + return disputeStatement + }, + encodingValue: []byte{0x1, 0x0}, + }, + } + + for _, c := range testCases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + disputeStatement := c.vdtBuilder(t) + + bytes, err := scale.Marshal(disputeStatement) + require.NoError(t, err) + + require.Equal(t, c.encodingValue, bytes) + + newDst := newDisputeStatement() + err = scale.Unmarshal(bytes, &newDst) + require.NoError(t, err) + + assert.Equal(t, disputeStatement, newDst) + }) + } +} + +func TestValidityAttestation(t *testing.T) { + t.Parallel() + + testCases := []struct { + name string + enumValue scale.VaryingDataTypeValue + encodingValue []byte + }{ + { + name: "Implicit", + enumValue: implicit(validatorSignature{}), + encodingValue: []byte{0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, //nolint:lll + }, + { + name: "Explicit", + enumValue: explicit(validatorSignature{}), + encodingValue: []byte{0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, //nolint:lll + }, + } + + for _, c := range testCases { + c := c + t.Run(c.name, func(t *testing.T) { + t.Parallel() + + validityAttestation := newValidityAttestation() + err := validityAttestation.Set(c.enumValue) + require.NoError(t, err) + + bytes, err := scale.Marshal(validityAttestation) + require.NoError(t, err) + + require.Equal(t, c.encodingValue, bytes) + + newDst := newValidityAttestation() + err = scale.Unmarshal(bytes, &newDst) + require.NoError(t, err) + + assert.Equal(t, validityAttestation, newDst) + }) + } +} + +func TestParachainInherents(t *testing.T) { + t.Parallel() + + expectedParaInherentsbytes := []byte{0, 0, 0, 197, 243, 254, 225, 31, 117, 21, 218, 179, 213, 92, 6, 247, 164, 230, 25, 47, 166, 140, 117, 142, 159, 195, 202, 67, 196, 238, 26, 44, 18, 33, 92, 65, 31, 219, 225, 47, 12, 107, 88, 153, 146, 55, 21, 226, 186, 110, 48, 167, 187, 67, 183, 228, 232, 118, 136, 30, 254, 11, 87, 48, 112, 7, 97, 31, 82, 146, 110, 96, 87, 152, 68, 98, 162, 227, 222, 78, 14, 244, 194, 120, 154, 112, 97, 222, 144, 174, 101, 220, 44, 111, 126, 54, 34, 155, 220, 253, 124, 0} //nolint:lll + expectedInherentsBytes := []byte{4, 112, 97, 114, 97, 99, 104, 110, 48, 153, 1, 0, 0, 0, 197, 243, 254, 225, 31, 117, 21, 218, 179, 213, 92, 6, 247, 164, 230, 25, 47, 166, 140, 117, 142, 159, 195, 202, 67, 196, 238, 26, 44, 18, 33, 92, 65, 31, 219, 225, 47, 12, 107, 88, 153, 146, 55, 21, 226, 186, 110, 48, 167, 187, 67, 183, 228, 232, 118, 136, 30, 254, 11, 87, 48, 112, 7, 97, 31, 82, 146, 110, 96, 87, 152, 68, 98, 162, 227, 222, 78, 14, 244, 194, 120, 154, 112, 97, 222, 144, 174, 101, 220, 44, 111, 126, 54, 34, 155, 220, 253, 124, 0} //nolint:lll + + // corresponding rust struct + // ---------------------------------------- + // let para_int: polkadot_primitives::v2::InherentData = polkadot_primitives::v2::InherentData { + // bitfields: Vec::new(), + // backed_candidates: Vec::new(), + // disputes: Vec::new(), + // parent_header: polkadot_core_primitives::Header{ + // parent_hash: BlakeTwo256::hash(b"1000"), + // digest: Default::default(), + // number: 2000, + // state_root: BlakeTwo256::hash(b"3000"), + // extrinsics_root: BlakeTwo256::hash(b"4000"), + // }, + // }; + // ---------------------------------------- + // way to get inherents encoding from rust + // ---------------------------------------- + // let mut inherents: sp_inherents::InherentData = sp_inherents::InherentData::new(); + // inherents.put_data(*b"parachn0", ¶_int).unwrap(); + // println!("{:?}", inherents.encode()); + + parachainInherent := ParachainInherentData{ + ParentHeader: types.Header{ + ParentHash: common.MustBlake2bHash([]byte("1000")), + Number: uint(2000), + StateRoot: common.MustBlake2bHash([]byte("3000")), + ExtrinsicsRoot: common.MustBlake2bHash([]byte("4000")), + }, + } + + actualParaInherentBytes, err := scale.Marshal(parachainInherent) + require.NoError(t, err) + + assert.Equal(t, expectedParaInherentsbytes, actualParaInherentBytes) + + idata := types.NewInherentData() + err = idata.SetInherent(types.Parachn0, parachainInherent) + require.NoError(t, err) + + actualInherentsBytes, err := idata.Encode() + require.NoError(t, err) + require.Equal(t, expectedInherentsBytes, actualInherentsBytes) +} diff --git a/lib/grandpa/message.go b/lib/grandpa/message.go index 3a14a3bfe5..939bd386d8 100644 --- a/lib/grandpa/message.go +++ b/lib/grandpa/message.go @@ -56,7 +56,7 @@ type VoteMessage struct { Message SignedMessage } -// Index Returns VDT index +// Index returns VDT index func (VoteMessage) Index() uint { return 0 } // ToConsensusMessage converts the VoteMessage into a network-level consensus message @@ -80,7 +80,7 @@ func (v *VoteMessage) ToConsensusMessage() (*ConsensusMessage, error) { // VersionedNeighbourPacket represents the enum of neighbour messages type VersionedNeighbourPacket scale.VaryingDataType -// Index Returns VDT index +// Index returns VDT index func (VersionedNeighbourPacket) Index() uint { return 2 } func newVersionedNeighbourPacket() VersionedNeighbourPacket { @@ -115,7 +115,7 @@ type NeighbourPacketV1 struct { Number uint32 } -// Index Returns VDT index +// Index returns VDT index func (NeighbourPacketV1) Index() uint { return 1 } // ToConsensusMessage converts the NeighbourMessage into a network-level consensus message @@ -172,7 +172,7 @@ func (s *Service) newCommitMessage(header *types.Header, round uint64) (*CommitM }, nil } -// Index Returns VDT index +// Index returns VDT index func (CommitMessage) Index() uint { return 1 } // ToConsensusMessage converts the CommitMessage into a network-level consensus message @@ -238,7 +238,7 @@ func newCatchUpRequest(round, setID uint64) *CatchUpRequest { } } -// Index Returns VDT index +// Index returns VDT index func (CatchUpRequest) Index() uint { return 3 } // ToConsensusMessage converts the catchUpRequest into a network-level consensus message @@ -295,7 +295,7 @@ func (s *Service) newCatchUpResponse(round, setID uint64) (*CatchUpResponse, err }, nil } -// Index Returns VDT index +// Index returns VDT index func (CatchUpResponse) Index() uint { return 4 } // ToConsensusMessage converts the catchUpResponse into a network-level consensus message diff --git a/lib/runtime/constants.go b/lib/runtime/constants.go index ff71f286fd..0b9bdcdc3d 100644 --- a/lib/runtime/constants.go +++ b/lib/runtime/constants.go @@ -25,6 +25,11 @@ const ( POLKADOT_RUNTIME_FP_v0917 = "polkadot_runtime-v917.compact.wasm" POLKADOT_RUNTIME_URL_v0917 = "https://github.com/paritytech/polkadot/blob/c583355a599200d64e9202d05f47860d824b4dcf/target/release/wbuild/polkadot-runtime/polkadot_runtime.compact.wasm?raw=true" //nolint:lll + // v0.9.25 polkadot runtime + POLKADOT_RUNTIME_v0925 = "polkadot_runtime-v9250" + POLKADOT_RUNTIME_FP_v0925 = "polkadot_runtime-v9250.compact.compressed.wasm" + POLKADOT_RUNTIME_URL_v0925 = "https://github.com/paritytech/polkadot/releases/download/v0.9.25/polkadot_runtime-v9250.compact.compressed.wasm?raw=true" //nolint:lll + // v0.8 polkadot runtime POLKADOT_RUNTIME = "polkadot_runtime" POLKADOT_RUNTIME_FP = "polkadot_runtime.compact.wasm" diff --git a/lib/runtime/test_helpers.go b/lib/runtime/test_helpers.go index 540a5314f3..2cf23a6c7c 100644 --- a/lib/runtime/test_helpers.go +++ b/lib/runtime/test_helpers.go @@ -72,6 +72,9 @@ func GetRuntime(ctx context.Context, runtime string) ( case NODE_RUNTIME_v098: runtimeFilename = NODE_RUNTIME_FP_v098 url = NODE_RUNTIME_URL_v098 + case POLKADOT_RUNTIME_v0925: + runtimeFilename = POLKADOT_RUNTIME_FP_v0925 + url = POLKADOT_RUNTIME_URL_v0925 case POLKADOT_RUNTIME_v0917: runtimeFilename = POLKADOT_RUNTIME_FP_v0917 url = POLKADOT_RUNTIME_URL_v0917 @@ -252,11 +255,11 @@ func InitializeRuntimeToTest(t *testing.T, instance Instance, parentHash common. err := instance.InitializeBlock(header) require.NoError(t, err) - idata := types.NewInherentsData() - err = idata.SetInt64Inherent(types.Timstap0, 1) + idata := types.NewInherentData() + err = idata.SetInherent(types.Timstap0, uint64(1)) require.NoError(t, err) - err = idata.SetInt64Inherent(types.Babeslot, 1) + err = idata.SetInherent(types.Babeslot, uint64(1)) require.NoError(t, err) ienc, err := idata.Encode() diff --git a/lib/runtime/wasmer/imports.go b/lib/runtime/wasmer/imports.go index daad753bab..5c88fa5a4b 100644 --- a/lib/runtime/wasmer/imports.go +++ b/lib/runtime/wasmer/imports.go @@ -861,7 +861,7 @@ func ext_trie_blake2_256_ordered_root_version_1(context unsafe.Pointer, dataSpan return 0 } - for i, val := range values { + for i, value := range values { key, err := scale.Marshal(big.NewInt(int64(i))) if err != nil { logger.Errorf("failed scale encoding value index %d: %s", i, err) @@ -869,9 +869,9 @@ func ext_trie_blake2_256_ordered_root_version_1(context unsafe.Pointer, dataSpan } logger.Tracef( "put key=0x%x and value=0x%x", - key, val) + key, value) - t.Put(key, val) + t.Put(key, value) } // allocate memory for value and copy value to memory diff --git a/tests/stress/grandpa_test.go b/tests/stress/grandpa_test.go index 62ec17aa93..aa302260a9 100644 --- a/tests/stress/grandpa_test.go +++ b/tests/stress/grandpa_test.go @@ -35,10 +35,12 @@ func TestStress_Grandpa_OneAuthority(t *testing.T) { compareChainHeadsWithRetry(ctx, nodes, getChainHeadTimeout) const getFinalizedHeadTimeout = time.Second - prev, _ := compareFinalizedHeads(ctx, t, nodes, getFinalizedHeadTimeout) + prev, err := compareFinalizedHeads(ctx, t, nodes, getFinalizedHeadTimeout) + require.NoError(t, err) time.Sleep(time.Second * 10) - curr, _ := compareFinalizedHeads(ctx, t, nodes, getFinalizedHeadTimeout) + curr, err := compareFinalizedHeads(ctx, t, nodes, getFinalizedHeadTimeout) + require.NoError(t, err) require.NotEqual(t, prev, curr) }