Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(dot/sync): fix Timestamp slot must match 'CurrentSlot' while using westend spec file #3040

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d06db1c
wip: dealing with `bitfields` error
EclesioMeloJunior Jan 11, 2023
7b1e9e0
wip
EclesioMeloJunior Jan 12, 2023
fadcf55
Merge branch 'development' into eclesio/fix-apply-extrinsic-using-wes…
EclesioMeloJunior Jan 12, 2023
17b8c6f
chore: fix `TestChainProcessor_HandleBlockResponse_ValidChain`
EclesioMeloJunior Jan 12, 2023
4a21a7b
chore: fixed `TestChainProcessor_HandleBlockResponse_MissingBlocks`
EclesioMeloJunior Jan 12, 2023
a0b1073
chore: fix `TestChainProcessor_HandleBlockResponse_BlockData`
EclesioMeloJunior Jan 12, 2023
f1ba2e8
chore: fix `TestChainProcessor_ExecuteBlock`
EclesioMeloJunior Jan 12, 2023
b819e4a
chore: rollback westend-dev config.toml
EclesioMeloJunior Jan 12, 2023
c7fba51
chore: rollback parachain modifications + test_helpers
EclesioMeloJunior Jan 12, 2023
9c03b11
chore: remove unneeded deltas
EclesioMeloJunior Jan 12, 2023
8ed3349
Merge branch 'development' into eclesio/fix-apply-extrinsic-using-wes…
EclesioMeloJunior Jan 12, 2023
c166b5c
chore: create function to replace loop inner body + improve var names
EclesioMeloJunior Jan 12, 2023
886c762
Merge branch 'eclesio/fix-apply-extrinsic-using-westend-runtime' of g…
EclesioMeloJunior Jan 12, 2023
4df99fe
Merge branch 'development' into eclesio/fix-apply-extrinsic-using-wes…
EclesioMeloJunior Jan 12, 2023
73e4a05
Merge branch 'development' into eclesio/fix-apply-extrinsic-using-wes…
EclesioMeloJunior Jan 13, 2023
9df48f9
Merge branch 'development' into eclesio/fix-apply-extrinsic-using-wes…
EclesioMeloJunior Jan 16, 2023
da79e21
chore: address comments
EclesioMeloJunior Jan 16, 2023
37ce143
remove unneeded comment
EclesioMeloJunior Jan 17, 2023
8f0064d
remove unneeded comment
EclesioMeloJunior Jan 17, 2023
231bc7d
Merge branch 'development' into eclesio/fix-apply-extrinsic-using-wes…
EclesioMeloJunior Jan 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 132 additions & 45 deletions dot/sync/chain_processor_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,125 @@ import (
"github.com/ChainSafe/gossamer/dot/network"
"github.com/ChainSafe/gossamer/dot/state"
"github.com/ChainSafe/gossamer/dot/types"
"github.com/ChainSafe/gossamer/lib/babe"
"github.com/ChainSafe/gossamer/lib/common"
"github.com/ChainSafe/gossamer/lib/common/variadic"
"github.com/ChainSafe/gossamer/lib/transaction"
"github.com/ChainSafe/gossamer/pkg/scale"

"github.com/stretchr/testify/require"
)

// TODO: add test against latest gssmr runtime
// See https://github.com/ChainSafe/gossamer/issues/2703
func TestChainProcessor_HandleBlockResponse_ValidChain(t *testing.T) {
syncer := newTestSyncer(t)
responder := newTestSyncer(t)
func buildBlockWithSlotAndTimestamp(t *testing.T, instance state.Runtime,
parent *types.Header, currentSlot, timestamp uint64) *types.Block {
t.Helper()

// get responder to build valid chain
parent, err := responder.blockState.(*state.BlockState).BestBlockHeader()
digest := types.NewDigest()
prd, err := types.NewBabeSecondaryPlainPreDigest(0, currentSlot).ToPreRuntimeDigest()
require.NoError(t, err)
err = digest.Add(*prd)
require.NoError(t, err)
header := &types.Header{
ParentHash: parent.Hash(),
StateRoot: common.Hash{},
ExtrinsicsRoot: common.Hash{},
Number: parent.Number + 1,
Digest: digest,
}

bestBlockHash := responder.blockState.(*state.BlockState).BestBlockHash()
rt, err := responder.blockState.GetRuntime(bestBlockHash)
err = instance.InitializeBlock(header)
require.NoError(t, err)

inherentData := types.NewInherentData()
err = inherentData.SetInherent(types.Timstap0, timestamp)
require.NoError(t, err)

err = inherentData.SetInherent(types.Babeslot, currentSlot)
require.NoError(t, err)

parachainInherent := babe.ParachainInherentData{
ParentHeader: *parent,
}

err = inherentData.SetInherent(types.Parachn0, parachainInherent)
require.NoError(t, err)

err = inherentData.SetInherent(types.Newheads, []byte{0})
require.NoError(t, err)

encodedInherentData, err := inherentData.Encode()
require.NoError(t, err)

// Call BlockBuilder_inherent_extrinsics which returns the inherents as encoded extrinsics
encodedInherentExtrinsics, err := instance.InherentExtrinsics(encodedInherentData)
require.NoError(t, err)

var inherentExtrinsics [][]byte
err = scale.Unmarshal(encodedInherentExtrinsics, &inherentExtrinsics)
require.NoError(t, err)

for _, inherent := range inherentExtrinsics {
encodedInherent, err := scale.Marshal(inherent)
require.NoError(t, err)

applyExtrinsicResult, err := instance.ApplyExtrinsic(encodedInherent)
require.NoError(t, err)
require.Equal(t, applyExtrinsicResult, []byte{0, 0})
}

finalisedHeader, err := instance.FinalizeBlock()
require.NoError(t, err)

body := types.Body(types.BytesArrayToExtrinsics(inherentExtrinsics))

finalisedHeader.Number = header.Number
finalisedHeader.Hash()

return &types.Block{
Header: *finalisedHeader,
Body: body,
}
}

func buildAndAddBlocksToState(t *testing.T, runtime state.Runtime, blockState *state.BlockState, amount uint) {
t.Helper()

parent, err := blockState.BestBlockHeader()
require.NoError(t, err)

babeConfig, err := runtime.BabeConfiguration()
require.NoError(t, err)

for i := 0; i < maxResponseSize*2; i++ {
block := BuildBlock(t, rt, parent, nil)
err = responder.blockState.(*state.BlockState).AddBlock(block)
timestamp := uint64(time.Now().Unix())
slotDuration := babeConfig.SlotDuration

for i := uint(0); i < amount; i++ {
// calculate the exact slot for each produced block
currentSlot := timestamp / slotDuration

block := buildBlockWithSlotAndTimestamp(t, runtime, parent, currentSlot, timestamp)
err = blockState.AddBlock(block)
require.NoError(t, err)
parent = &block.Header

// increase the timestamp by the slot duration
// so we will get a different slot for the next block
timestamp += slotDuration
}

}

func TestChainProcessor_HandleBlockResponse_ValidChain(t *testing.T) {
syncer := newTestSyncer(t)
responder := newTestSyncer(t)

bestBlockHash := responder.blockState.(*state.BlockState).BestBlockHash()
runtimeInstance, err := responder.blockState.GetRuntime(bestBlockHash)
require.NoError(t, err)

buildAndAddBlocksToState(t, runtimeInstance,
responder.blockState.(*state.BlockState), maxResponseSize*2)

// syncer makes request for chain
startNum := 1
start, err := variadic.NewUint32OrHash(startNum)
Expand Down Expand Up @@ -81,39 +173,22 @@ func TestChainProcessor_HandleBlockResponse_ValidChain(t *testing.T) {
}
}

// TODO: add test against latest gssmr runtime
// See https://github.com/ChainSafe/gossamer/issues/2703
func TestChainProcessor_HandleBlockResponse_MissingBlocks(t *testing.T) {
syncer := newTestSyncer(t)

parent, err := syncer.blockState.(*state.BlockState).BestBlockHeader()
require.NoError(t, err)

bestBlockHash := syncer.blockState.(*state.BlockState).BestBlockHash()
rt, err := syncer.blockState.GetRuntime(bestBlockHash)
syncerRuntime, err := syncer.blockState.GetRuntime(bestBlockHash)
require.NoError(t, err)

for i := 0; i < 4; i++ {
block := BuildBlock(t, rt, parent, nil)
err = syncer.blockState.(*state.BlockState).AddBlock(block)
require.NoError(t, err)
parent = &block.Header
}
const syncerAmountOfBlocks = 4
buildAndAddBlocksToState(t, syncerRuntime, syncer.blockState.(*state.BlockState), syncerAmountOfBlocks)

responder := newTestSyncer(t)

parent, err = responder.blockState.(*state.BlockState).BestBlockHeader()
require.NoError(t, err)

rt, err = syncer.blockState.GetRuntime(bestBlockHash)
responderRuntime, err := responder.blockState.GetRuntime(bestBlockHash)
require.NoError(t, err)

for i := 0; i < 16; i++ {
block := BuildBlock(t, rt, parent, nil)
err = responder.blockState.(*state.BlockState).AddBlock(block)
require.NoError(t, err)
parent = &block.Header
}
const responderAmountOfBlocks = 16
buildAndAddBlocksToState(t, responderRuntime, responder.blockState.(*state.BlockState), responderAmountOfBlocks)

startNum := 15
start, err := variadic.NewUint32OrHash(startNum)
Expand Down Expand Up @@ -153,18 +228,24 @@ func TestChainProcessor_handleBody_ShouldRemoveIncludedExtrinsics(t *testing.T)
require.Nil(t, inQueue, "queue should be empty")
}

// TODO: add test against latest gssmr runtime
// See https://github.com/ChainSafe/gossamer/issues/2703
func TestChainProcessor_HandleBlockResponse_BlockData(t *testing.T) {
syncer := newTestSyncer(t)

parent, err := syncer.blockState.(*state.BlockState).BestBlockHeader()
require.NoError(t, err)

rt, err := syncer.blockState.GetRuntime(parent.Hash())
runtimeInstance, err := syncer.blockState.GetRuntime(parent.Hash())
require.NoError(t, err)

babeConfig, err := runtimeInstance.BabeConfiguration()
require.NoError(t, err)

block := BuildBlock(t, rt, parent, nil)
timestamp := uint64(time.Now().Unix())
slotDuration := babeConfig.SlotDuration

// calculate the exact slot for each produced block
currentSlot := timestamp / slotDuration
block := buildBlockWithSlotAndTimestamp(t, runtimeInstance, parent, currentSlot, timestamp)

bd := []*types.BlockData{{
Hash: block.Header.Hash(),
Expand All @@ -184,26 +265,32 @@ func TestChainProcessor_HandleBlockResponse_BlockData(t *testing.T) {
}
}

// TODO: add test against latest gssmr runtime
// See https://github.com/ChainSafe/gossamer/issues/2703
func TestChainProcessor_ExecuteBlock(t *testing.T) {
syncer := newTestSyncer(t)

parent, err := syncer.blockState.(*state.BlockState).BestBlockHeader()
require.NoError(t, err)

bestBlockHash := syncer.blockState.(*state.BlockState).BestBlockHash()
rt, err := syncer.blockState.GetRuntime(bestBlockHash)
runtimeInstance, err := syncer.blockState.GetRuntime(bestBlockHash)
require.NoError(t, err)

babeConfig, err := runtimeInstance.BabeConfiguration()
require.NoError(t, err)

block := BuildBlock(t, rt, parent, nil)
timestamp := uint64(time.Now().Unix())
slotDuration := babeConfig.SlotDuration

// calculate the exact slot for each produced block
currentSlot := timestamp / slotDuration
block := buildBlockWithSlotAndTimestamp(t, runtimeInstance, parent, currentSlot, timestamp)

// reset parentState
parentState, err := syncer.chainProcessor.(*chainProcessor).storageState.TrieState(&parent.StateRoot)
require.NoError(t, err)
rt.SetContextStorage(parentState)
runtimeInstance.SetContextStorage(parentState)

_, err = rt.ExecuteBlock(block)
_, err = runtimeInstance.ExecuteBlock(block)
require.NoError(t, err)
}

Expand Down
2 changes: 1 addition & 1 deletion dot/sync/syncer_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func newTestGenesisWithTrieAndHeader(t *testing.T) (
gen genesis.Genesis, genesisTrie trie.Trie, genesisHeader types.Header) {
t.Helper()

genesisPath := utils.GetGssmrV3SubstrateGenesisRawPathTest(t)
genesisPath := utils.GetWestendDevRawGenesisPath(t)
genesisPtr, err := genesis.NewGenesisFromJSONRaw(genesisPath)
require.NoError(t, err)
gen = *genesisPtr
Expand Down