From 1d2337572b2aaf79175de9f5be9c3bdbefd1f1a5 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 29 Nov 2023 16:53:14 +0100 Subject: [PATCH 001/111] nits --- vms/proposervm/proposer/mock_windower.go | 15 ------- vms/proposervm/proposer/windower.go | 56 +++++++++++------------- 2 files changed, 25 insertions(+), 46 deletions(-) diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index 3e7375326429..e2eafd76b8eb 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -53,18 +53,3 @@ func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3, arg4 interface mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delay", reflect.TypeOf((*MockWindower)(nil).Delay), arg0, arg1, arg2, arg3, arg4) } - -// Proposers mocks base method. -func (m *MockWindower) Proposers(arg0 context.Context, arg1, arg2 uint64, arg3 int) ([]ids.NodeID, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Proposers", arg0, arg1, arg2, arg3) - ret0, _ := ret[0].([]ids.NodeID) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Proposers indicates an expected call of Proposers. -func (mr *MockWindowerMockRecorder) Proposers(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Proposers", reflect.TypeOf((*MockWindower)(nil).Proposers), arg0, arg1, arg2, arg3) -} diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 8cb7bc43b24d..34bc1709184e 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -29,16 +29,6 @@ const ( var _ Windower = (*windower)(nil) type Windower interface { - // Proposers returns the proposer list for building a block at [chainHeight] - // when the validator set is defined at [pChainHeight]. The list is returned - // in order. The minimum delay of a validator is the index they appear times - // [WindowDuration]. - Proposers( - ctx context.Context, - chainHeight, - pChainHeight uint64, - maxWindows int, - ) ([]ids.NodeID, error) // Delay returns the amount of time that [validatorID] must wait before // building a block at [chainHeight] when the validator set is defined at // [pChainHeight]. @@ -70,7 +60,31 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { } } -func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { +func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { + if validatorID == ids.EmptyNodeID { + return time.Duration(maxWindows) * WindowDuration, nil + } + + proposers, err := w.proposers(ctx, chainHeight, pChainHeight, maxWindows) + if err != nil { + return 0, err + } + + delay := time.Duration(0) + for _, nodeID := range proposers { + if nodeID == validatorID { + return delay, nil + } + delay += WindowDuration + } + return delay, nil +} + +// proposers returns the proposer list for building a block at [chainHeight] +// when the validator set is defined at [pChainHeight]. The list is returned +// in order. The minimum delay of a validator is the index they appear times +// [WindowDuration]. +func (w *windower) proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { // get the validator set by the p-chain height validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) if err != nil { @@ -126,23 +140,3 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint } return nodeIDs, nil } - -func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { - if validatorID == ids.EmptyNodeID { - return time.Duration(maxWindows) * WindowDuration, nil - } - - proposers, err := w.Proposers(ctx, chainHeight, pChainHeight, maxWindows) - if err != nil { - return 0, err - } - - delay := time.Duration(0) - for _, nodeID := range proposers { - if nodeID == validatorID { - return delay, nil - } - delay += WindowDuration - } - return delay, nil -} From 48aceae64a494de83bee868e390653e52a756d1c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 29 Nov 2023 17:43:48 +0100 Subject: [PATCH 002/111] extended windower --- vms/proposervm/proposer/mock_windower.go | 15 ++++ vms/proposervm/proposer/windower.go | 98 ++++++++++++++++++------ 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index e2eafd76b8eb..6396c4092cd2 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -53,3 +53,18 @@ func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3, arg4 interface mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delay", reflect.TypeOf((*MockWindower)(nil).Delay), arg0, arg1, arg2, arg3, arg4) } + +// ExpectedProposer mocks base method. +func (m *MockWindower) ExpectedProposer(arg0 context.Context, arg1, arg2 uint64, arg3, arg4 time.Time) (ids.NodeID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ExpectedProposer", arg0, arg1, arg2, arg3, arg4) + ret0, _ := ret[0].(ids.NodeID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ExpectedProposer indicates an expected call of ExpectedProposer. +func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExpectedProposer", reflect.TypeOf((*MockWindower)(nil).ExpectedProposer), arg0, arg1, arg2, arg3, arg4) +} diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 34bc1709184e..3ebbc04a2998 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -39,6 +39,14 @@ type Windower interface { validatorID ids.NodeID, maxWindows int, ) (time.Duration, error) + + ExpectedProposer( + ctx context.Context, + chainHeight, + pChainHeight uint64, + blockTime, + parentBlockTime time.Time, + ) (ids.NodeID, error) } // windower interfaces with P-Chain and it is responsible for calculating the @@ -80,37 +88,49 @@ func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, return delay, nil } +func (w *windower) ExpectedProposer( + ctx context.Context, + chainHeight, + pChainHeight uint64, + blockTime, + parentBlockTime time.Time, +) (ids.NodeID, error) { + validators, _, err := w.sortedValidators(ctx, pChainHeight) + if err != nil { + return ids.EmptyNodeID, err + } + + // convert the slice of validators to a slice of weights + validatorWeights := make([]uint64, len(validators)) + for i, v := range validators { + validatorWeights[i] = v.weight + } + + if err := w.sampler.Initialize(validatorWeights); err != nil { + return ids.EmptyNodeID, err + } + + numToSample := 1 + seed := chainHeight ^ w.chainSource ^ uint64((blockTime.Sub(parentBlockTime) / WindowDuration)) + w.sampler.Seed(int64(seed)) + + indices, err := w.sampler.Sample(numToSample) + if err != nil { + return ids.EmptyNodeID, err + } + return validators[indices[0]].id, nil +} + // proposers returns the proposer list for building a block at [chainHeight] // when the validator set is defined at [pChainHeight]. The list is returned // in order. The minimum delay of a validator is the index they appear times // [WindowDuration]. func (w *windower) proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { - // get the validator set by the p-chain height - validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) + validators, totalWeight, err := w.sortedValidators(ctx, pChainHeight) if err != nil { return nil, err } - // convert the map of validators to a slice - validators := make([]validatorData, 0, len(validatorsMap)) - weight := uint64(0) - for k, v := range validatorsMap { - validators = append(validators, validatorData{ - id: k, - weight: v.Weight, - }) - newWeight, err := math.Add64(weight, v.Weight) - if err != nil { - return nil, err - } - weight = newWeight - } - - // canonically sort validators - // Note: validators are sorted by ID, sorting by weight would not create a - // canonically sorted list - utils.Sort(validators) - // convert the slice of validators to a slice of weights validatorWeights := make([]uint64, len(validators)) for i, v := range validators { @@ -122,8 +142,8 @@ func (w *windower) proposers(ctx context.Context, chainHeight, pChainHeight uint } numToSample := maxWindows - if weight < uint64(numToSample) { - numToSample = int(weight) + if totalWeight < uint64(numToSample) { + numToSample = int(totalWeight) } seed := chainHeight ^ w.chainSource @@ -140,3 +160,33 @@ func (w *windower) proposers(ctx context.Context, chainHeight, pChainHeight uint } return nodeIDs, nil } + +func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, uint64, error) { + // get the validator set by the p-chain height + validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) + if err != nil { + return nil, 0, err + } + + // convert the map of validators to a slice + validators := make([]validatorData, 0, len(validatorsMap)) + totalWeight := uint64(0) + for k, v := range validatorsMap { + validators = append(validators, validatorData{ + id: k, + weight: v.Weight, + }) + newWeight, err := math.Add64(totalWeight, v.Weight) + if err != nil { + return nil, 0, err + } + totalWeight = newWeight + } + + // canonically sort validators + // Note: validators are sorted by ID, sorting by weight would not create a + // canonically sorted list + utils.Sort(validators) + + return validators, totalWeight, nil +} From 78e124095dedaa545185e04e54a7747015c63a1d Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 29 Nov 2023 17:47:23 +0100 Subject: [PATCH 003/111] nit --- vms/proposervm/proposer/windower_test.go | 38 ++++++++++++++++-------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 2a141a361ea2..e64f872c742d 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -18,9 +18,12 @@ import ( func TestWindowerNoValidators(t *testing.T) { require := require.New(t) - subnetID := ids.GenerateTestID() - chainID := ids.GenerateTestID() - nodeID := ids.GenerateTestNodeID() + var ( + subnetID = ids.GenerateTestID() + chainID = ids.GenerateTestID() + nodeID = ids.GenerateTestNodeID() + ) + vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { @@ -38,10 +41,13 @@ func TestWindowerNoValidators(t *testing.T) { func TestWindowerRepeatedValidator(t *testing.T) { require := require.New(t) - subnetID := ids.GenerateTestID() - chainID := ids.GenerateTestID() - validatorID := ids.GenerateTestNodeID() - nonValidatorID := ids.GenerateTestNodeID() + var ( + subnetID = ids.GenerateTestID() + chainID = ids.GenerateTestID() + validatorID = ids.GenerateTestNodeID() + nonValidatorID = ids.GenerateTestNodeID() + ) + vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { @@ -68,8 +74,11 @@ func TestWindowerRepeatedValidator(t *testing.T) { func TestWindowerChangeByHeight(t *testing.T) { require := require.New(t) - subnetID := ids.ID{0, 1} - chainID := ids.ID{0, 2} + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + ) + validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) @@ -126,11 +135,16 @@ func TestWindowerChangeByChain(t *testing.T) { subnetID := ids.ID{0, 1} - rand.Seed(0) + source := rand.NewSource(int64(0)) + rng := rand.New(source) // #nosec G404 + chainID0 := ids.ID{} - _, _ = rand.Read(chainID0[:]) // #nosec G404 + _, err := rng.Read(chainID0[:]) + require.NoError(err) + chainID1 := ids.ID{} - _, _ = rand.Read(chainID1[:]) // #nosec G404 + _, err = rng.Read(chainID1[:]) + require.NoError(err) validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { From b3ffd155a9a200eb37df524c98ad0fcd6bc1caef Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 29 Nov 2023 18:02:38 +0100 Subject: [PATCH 004/111] nits --- vms/proposervm/proposer/windower.go | 10 ++++++++-- vms/proposervm/proposer/windower_test.go | 12 +++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 3ebbc04a2998..c61329beec98 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -5,6 +5,8 @@ package proposer import ( "context" + "errors" + "fmt" "time" "github.com/ava-labs/avalanchego/ids" @@ -26,7 +28,11 @@ const ( MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes ) -var _ Windower = (*windower)(nil) +var ( + _ Windower = (*windower)(nil) + + ErrNoProposersAvailable = errors.New("no proposers available") +) type Windower interface { // Delay returns the amount of time that [validatorID] must wait before @@ -116,7 +122,7 @@ func (w *windower) ExpectedProposer( indices, err := w.sampler.Sample(numToSample) if err != nil { - return ids.EmptyNodeID, err + return ids.EmptyNodeID, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) } return validators[indices[0]].id, nil } diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index e64f872c742d..d7aff648ee12 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -33,9 +33,19 @@ func TestWindowerNoValidators(t *testing.T) { w := New(vdrState, subnetID, chainID) - delay, err := w.Delay(context.Background(), 1, 0, nodeID, MaxVerifyWindows) + var ( + chainHeight = uint64(1) + pChainHeight = uint64(0) + blockTime = time.Now().Truncate(time.Second) + parentBlockTime = time.Now().Truncate(time.Second).Add(time.Second) + ) + delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) require.Zero(delay) + + expectedProposer, err := w.ExpectedProposer(context.Background(), chainHeight, pChainHeight, blockTime, parentBlockTime) + require.ErrorIs(err, ErrNoProposersAvailable) + require.Equal(ids.EmptyNodeID, expectedProposer) } func TestWindowerRepeatedValidator(t *testing.T) { From 64e0cc5ed89929859ba5c2cdcb99a242432c323e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 29 Nov 2023 18:37:07 +0100 Subject: [PATCH 005/111] adding UTs --- vms/proposervm/proposer/windower_test.go | 180 ++++++++++++++++++++++- 1 file changed, 176 insertions(+), 4 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index d7aff648ee12..5c05cf397d85 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -36,8 +36,8 @@ func TestWindowerNoValidators(t *testing.T) { var ( chainHeight = uint64(1) pChainHeight = uint64(0) - blockTime = time.Now().Truncate(time.Second) - parentBlockTime = time.Now().Truncate(time.Second).Add(time.Second) + parentBlockTime = time.Now().Truncate(time.Second) + blockTime = parentBlockTime.Add(time.Second) ) delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) @@ -81,7 +81,7 @@ func TestWindowerRepeatedValidator(t *testing.T) { require.Equal(MaxVerifyDelay, nonValidatorDelay) } -func TestWindowerChangeByHeight(t *testing.T) { +func TestDelayChangeByHeight(t *testing.T) { require := require.New(t) var ( @@ -140,7 +140,7 @@ func TestWindowerChangeByHeight(t *testing.T) { } } -func TestWindowerChangeByChain(t *testing.T) { +func TestDelayChangeByChain(t *testing.T) { require := require.New(t) subnetID := ids.ID{0, 1} @@ -207,3 +207,175 @@ func TestWindowerChangeByChain(t *testing.T) { require.Equal(expectedDelay, validatorDelay) } } + +func TestExpectedProposerChangeByHeight(t *testing.T) { + require := require.New(t) + + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + + validatorsCount = 10 + ) + + validatorIDs := make([]ids.NodeID, validatorsCount) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + + w := New(vdrState, subnetID, chainID) + + var ( + dummyCtx = context.Background() + chainHeight = uint64(1) + pChainHeight = uint64(0) + parentBlockTime = time.Now().Truncate(time.Second) + blockTime = parentBlockTime.Add(time.Second) + ) + + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[6], proposerID) + + chainHeight = 2 + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[4], proposerID) +} + +func TestExpectedProposerChangeByChain(t *testing.T) { + require := require.New(t) + + var ( + subnetID = ids.ID{0, 1} + validatorsCount = 10 + ) + + source := rand.NewSource(int64(0)) + rng := rand.New(source) // #nosec G404 + + chainID0 := ids.ID{} + _, err := rng.Read(chainID0[:]) + require.NoError(err) + + chainID1 := ids.ID{} + _, err = rng.Read(chainID1[:]) + require.NoError(err) + + validatorIDs := make([]ids.NodeID, validatorsCount) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + + w0 := New(vdrState, subnetID, chainID0) + w1 := New(vdrState, subnetID, chainID1) + + var ( + dummyCtx = context.Background() + chainHeight = uint64(1) + pChainHeight = uint64(0) + parentBlockTime = time.Now().Truncate(time.Second) + blockTime = parentBlockTime.Add(time.Second) + ) + + proposerID, err := w0.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[5], proposerID) + + proposerID, err = w1.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[3], proposerID) +} + +func TestExpectedProposerChangeBySlot(t *testing.T) { + require := require.New(t) + + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + + validatorsCount = 10 + ) + + validatorIDs := make([]ids.NodeID, validatorsCount) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + + w := New(vdrState, subnetID, chainID) + + var ( + dummyCtx = context.Background() + chainHeight = uint64(1) + pChainHeight = uint64(0) + parentBlockTime = time.Now().Truncate(time.Second) + blockTime = parentBlockTime.Add(time.Second) + ) + + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[6], proposerID) + + { + // proposerID won't change within the same slot + blockTime = parentBlockTime.Add(WindowDuration).Add(-1 * time.Second) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[6], proposerID) + } + + { + // proposerID changes with new slot + blockTime = parentBlockTime.Add(WindowDuration) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[4], proposerID) + } + + { + // proposerID changes with new slot + blockTime = parentBlockTime.Add(2 * WindowDuration) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[9], proposerID) + } +} From 392e99183a72b84c219cbf43e897918240f8b696 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 29 Nov 2023 19:38:01 +0100 Subject: [PATCH 006/111] introduced proposervm config --- chains/manager.go | 28 ++-- vms/proposervm/batched_vm_test.go | 14 +- vms/proposervm/block.go | 4 +- vms/proposervm/block_test.go | 8 +- vms/proposervm/config.go | 21 +++ vms/proposervm/height_indexed_vm.go | 10 +- vms/proposervm/post_fork_block_test.go | 40 +++--- vms/proposervm/post_fork_option_test.go | 14 +- vms/proposervm/pre_fork_block.go | 10 +- vms/proposervm/pre_fork_block_test.go | 10 +- vms/proposervm/state_syncable_vm_test.go | 38 ++--- vms/proposervm/vm.go | 33 +---- vms/proposervm/vm_regression_test.go | 15 +- vms/proposervm/vm_test.go | 170 +++++++++++++---------- 14 files changed, 226 insertions(+), 189 deletions(-) create mode 100644 vms/proposervm/config.go diff --git a/chains/manager.go b/chains/manager.go index b4f28b1290be..bfa0ae4aa7e7 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -768,13 +768,15 @@ func (m *manager) createAvalancheChain( // Note: vmWrappingProposerVM is the VM that the Snowman engines should be // using. var vmWrappingProposerVM block.ChainVM = proposervm.New( + proposervm.Config{ + ActivationTime: m.ApricotPhase4Time, + MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + MinBlkDelay: minBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: m.stakingSigner, + StakingCertLeaf: m.stakingCert, + }, vmWrappedInsideProposerVM, - m.ApricotPhase4Time, - m.ApricotPhase4MinPChainHeight, - minBlockDelay, - numHistoricalBlocks, - m.stakingSigner, - m.stakingCert, ) if m.MeterVMEnabled { @@ -1110,13 +1112,15 @@ func (m *manager) createSnowmanChain( } vm = proposervm.New( + proposervm.Config{ + ActivationTime: m.ApricotPhase4Time, + MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + MinBlkDelay: minBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: m.stakingSigner, + StakingCertLeaf: m.stakingCert, + }, vm, - m.ApricotPhase4Time, - m.ApricotPhase4MinPChainHeight, - minBlockDelay, - numHistoricalBlocks, - m.stakingSigner, - m.stakingCert, ) if m.MeterVMEnabled { diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 684d91ceb3df..25601dc63e09 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1019,13 +1019,15 @@ func initTestRemoteProposerVM( } proVM := New( + Config{ + ActivationTime: proBlkStartTime, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - proBlkStartTime, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 489d325f8f70..86e73d5adc20 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -261,10 +261,10 @@ func (p *postForkCommonComponents) buildChild( parentID, newTimestamp, pChainHeight, - p.vm.stakingCertLeaf, + p.vm.StakingCertLeaf, innerBlock.Bytes(), p.vm.ctx.ChainID, - p.vm.stakingLeafSigner, + p.vm.StakingLeafSigner, ) } if err != nil { diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 04ac66ecf34e..5cca837a7a84 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -60,15 +60,17 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) vm := &VM{ + Config: Config{ + StakingCertLeaf: &staking.Certificate{}, + StakingLeafSigner: pk, + }, ChainVM: innerVM, blockBuilderVM: innerBlockBuilderVM, ctx: &snow.Context{ ValidatorState: vdrState, Log: logging.NoLog{}, }, - Windower: windower, - stakingCertLeaf: &staking.Certificate{}, - stakingLeafSigner: pk, + Windower: windower, } blk := &postForkCommonComponents{ diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go new file mode 100644 index 000000000000..5de2314879a1 --- /dev/null +++ b/vms/proposervm/config.go @@ -0,0 +1,21 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package proposervm + +import ( + "crypto" + "time" + + "github.com/ava-labs/avalanchego/staking" +) + +type Config struct { + ActivationTime time.Time + DurangoTime time.Time + MinimumPChainHeight uint64 + MinBlkDelay time.Duration + NumHistoricalBlocks uint64 + StakingLeafSigner crypto.Signer + StakingCertLeaf *staking.Certificate +} diff --git a/vms/proposervm/height_indexed_vm.go b/vms/proposervm/height_indexed_vm.go index 99b911c5be64..6c8d6967ee14 100644 --- a/vms/proposervm/height_indexed_vm.go +++ b/vms/proposervm/height_indexed_vm.go @@ -136,7 +136,7 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { zap.Uint64("height", height), ) - if vm.numHistoricalBlocks == 0 { + if vm.NumHistoricalBlocks == 0 { return nil } @@ -145,13 +145,13 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { // is why <= is used rather than <. This prevents the user from only storing // the last accepted block, which can never be safe due to the non-atomic // commits between the proposervm database and the innerVM's database. - if blocksSinceFork <= vm.numHistoricalBlocks { + if blocksSinceFork <= vm.NumHistoricalBlocks { return nil } // Note: heightToDelete is >= forkHeight, so it is guaranteed not to // underflow. - heightToDelete := height - vm.numHistoricalBlocks - 1 + heightToDelete := height - vm.NumHistoricalBlocks - 1 blockToDelete, err := vm.State.GetBlockIDAtHeight(heightToDelete) if err == database.ErrNotFound { // Block may have already been deleted. This can happen due to a @@ -180,7 +180,7 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { // TODO: Support async deletion of old blocks. func (vm *VM) pruneOldBlocks() error { - if vm.numHistoricalBlocks == 0 { + if vm.NumHistoricalBlocks == 0 { return nil } @@ -194,7 +194,7 @@ func (vm *VM) pruneOldBlocks() error { // // Note: vm.lastAcceptedHeight is guaranteed to be >= height, so the // subtraction can never underflow. - for vm.lastAcceptedHeight-height > vm.numHistoricalBlocks { + for vm.lastAcceptedHeight-height > vm.NumHistoricalBlocks { blockToDelete, err := vm.State.GetBlockIDAtHeight(height) if err != nil { return err diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 659bdd1e5fd3..25dfd4f63e8f 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -70,10 +70,10 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { ids.Empty, // refer unknown parent time.Time{}, 0, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerOracleBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk = postForkBlock{ @@ -155,10 +155,10 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { ids.Empty, // refer unknown parent childCoreBlk.Timestamp(), pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -260,10 +260,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), childCoreBlk.Timestamp(), pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -287,10 +287,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), beforeWinStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -305,10 +305,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), atWindowStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -322,10 +322,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), afterWindowStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -350,10 +350,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), afterSubWinEnd, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -431,10 +431,10 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { prntProBlk.ID(), childCoreBlk.Timestamp(), prntBlkPChainHeight-1, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -611,10 +611,10 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) parentBlk.ID(), childCoreBlk.Timestamp(), prntBlkPChainHeight-1, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -986,10 +986,10 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { postForkOracleBlk.ID(), postForkOracleBlk.Timestamp().Add(proposer.WindowDuration), postForkOracleBlk.PChainHeight(), - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, oracleCoreBlk.opts[0].Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 8e93e2aad05f..7457186a8fe1 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -659,13 +659,15 @@ func TestOptionTimestampValidity(t *testing.T) { // Restart the node. ctx := proVM.ctx proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) coreVM.InitializeF = func( diff --git a/vms/proposervm/pre_fork_block.go b/vms/proposervm/pre_fork_block.go index ed665e473910..8e952d9d7758 100644 --- a/vms/proposervm/pre_fork_block.go +++ b/vms/proposervm/pre_fork_block.go @@ -97,7 +97,7 @@ func (b *preForkBlock) getInnerBlk() snowman.Block { func (b *preForkBlock) verifyPreForkChild(ctx context.Context, child *preForkBlock) error { parentTimestamp := b.Timestamp() - if !parentTimestamp.Before(b.vm.activationTime) { + if !parentTimestamp.Before(b.vm.ActivationTime) { if err := verifyIsOracleBlock(ctx, b.Block); err != nil { return err } @@ -135,7 +135,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB currentPChainHeight, ) } - if childPChainHeight < b.vm.minimumPChainHeight { + if childPChainHeight < b.vm.MinimumPChainHeight { return errPChainHeightTooLow } @@ -150,7 +150,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB // if the *preForkBlock is the last *preForkBlock before activation takes effect // (its timestamp is at or after the activation time) parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.activationTime) { + if parentTimestamp.Before(b.vm.ActivationTime) { return errProposersNotActivated } @@ -181,7 +181,7 @@ func (*preForkBlock) verifyPostForkOption(context.Context, *postForkOption) erro func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.activationTime) { + if parentTimestamp.Before(b.vm.ActivationTime) { // The chain hasn't forked yet innerBlock, err := b.vm.ChainVM.BuildBlock(ctx) if err != nil { @@ -210,7 +210,7 @@ func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { // The child's P-Chain height is proposed as the optimal P-Chain height that // is at least the minimum height - pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.minimumPChainHeight) + pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.MinimumPChainHeight) if err != nil { b.vm.ctx.Log.Error("unexpected build block failure", zap.String("reason", "failed to calculate optimal P-chain height"), diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 1366482a0d9b..4308f9ba05f1 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -342,10 +342,10 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { coreGenBlk.ID(), coreBlk.Timestamp(), 0, // pChainHeight - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, coreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) postForkChild := &postForkBlock{ @@ -740,10 +740,10 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { firstBlock.ID(), // refer unknown parent firstBlock.Timestamp(), 0, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, coreBlk.opts[0].Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) @@ -798,7 +798,7 @@ func TestPreForkBlock_BuildBlockWithContext(t *testing.T) { // Should call BuildBlock since proposervm is not activated innerBlk.EXPECT().Timestamp().Return(time.Time{}) - vm.activationTime = mockable.MaxTime + vm.ActivationTime = mockable.MaxTime gotChild, err = blk.buildChild(context.Background()) require.NoError(err) diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 826f8b877987..b91ab91457a7 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -69,13 +69,15 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { // create the VM vm := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) ctx := snow.DefaultContextTest() @@ -186,10 +188,10 @@ func TestStateSyncGetOngoingSyncStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -271,10 +273,10 @@ func TestStateSyncGetLastStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -359,10 +361,10 @@ func TestStateSyncGetStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -432,10 +434,10 @@ func TestParseStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -487,10 +489,10 @@ func TestStateSummaryAccept(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) @@ -567,10 +569,10 @@ func TestStateSummaryAcceptOlderBlock(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index a7bb897932d3..01afda96abb1 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -5,7 +5,6 @@ package proposervm import ( "context" - "crypto" "errors" "fmt" "time" @@ -26,7 +25,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/math" @@ -86,19 +84,11 @@ func cachedBlockSize(_ ids.ID, blk snowman.Block) int { type VM struct { block.ChainVM + Config blockBuilderVM block.BuildBlockWithContextChainVM batchedVM block.BatchedChainVM ssVM block.StateSyncableVM - activationTime time.Time - minimumPChainHeight uint64 - minBlkDelay time.Duration - numHistoricalBlocks uint64 - // block signer - stakingLeafSigner crypto.Signer - // block certificate - stakingCertLeaf *staking.Certificate - state.State hIndexer indexer.HeightIndexer @@ -137,29 +127,18 @@ type VM struct { // New performs best when [minBlkDelay] is whole seconds. This is because block // timestamps are only specific to the second. func New( + config Config, vm block.ChainVM, - activationTime time.Time, - minimumPChainHeight uint64, - minBlkDelay time.Duration, - numHistoricalBlocks uint64, - stakingLeafSigner crypto.Signer, - stakingCertLeaf *staking.Certificate, ) *VM { blockBuilderVM, _ := vm.(block.BuildBlockWithContextChainVM) batchedVM, _ := vm.(block.BatchedChainVM) ssVM, _ := vm.(block.StateSyncableVM) return &VM{ ChainVM: vm, + Config: config, blockBuilderVM: blockBuilderVM, batchedVM: batchedVM, ssVM: ssVM, - - activationTime: activationTime, - minimumPChainHeight: minimumPChainHeight, - minBlkDelay: minBlkDelay, - numHistoricalBlocks: numHistoricalBlocks, - stakingLeafSigner: stakingLeafSigner, - stakingCertLeaf: stakingCertLeaf, } } @@ -373,8 +352,8 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { // validators can specify. This delay may be an issue for high performance, // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. - if minDelay < vm.minBlkDelay { - minDelay = vm.minBlkDelay + if minDelay < vm.MinBlkDelay { + minDelay = vm.MinBlkDelay } preferredTime := blk.Timestamp() @@ -418,7 +397,7 @@ func (vm *VM) repair(ctx context.Context) error { return err } - if vm.numHistoricalBlocks != 0 { + if vm.NumHistoricalBlocks != 0 { vm.ctx.Log.Fatal("block height index must be valid when pruning historical blocks") return errHeightIndexInvalidWhilePruning } diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index 0a27c43e112a..792090a1f5cf 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -45,14 +45,17 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) + defer func() { // avoids leaking goroutines require.NoError(proVM.Shutdown(context.Background())) diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index fb8672d8b2f4..83b89a32236f 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -133,13 +133,15 @@ func initTestProposerVM( } proVM := New( + Config{ + ActivationTime: proBlkStartTime, + MinimumPChainHeight: minPChainHeight, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - proBlkStartTime, - minPChainHeight, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -526,10 +528,10 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk := postForkBlock{ @@ -570,10 +572,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk1 := postForkBlock{ @@ -589,10 +591,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 200, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk2 := postForkBlock{ @@ -879,13 +881,15 @@ func TestExpiredBuildBlock(t *testing.T) { } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -1223,13 +1227,15 @@ func TestInnerVMRollback(t *testing.T) { db := memdb.New() proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -1310,13 +1316,15 @@ func TestInnerVMRollback(t *testing.T) { } proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -1802,13 +1810,15 @@ func TestRejectedHeightNotIndexed(t *testing.T) { } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -2009,13 +2019,15 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -2172,13 +2184,15 @@ func TestVMInnerBlkCache(t *testing.T) { // Create a VM innerVM := mocks.NewMockChainVM(ctrl) vm := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, // fork is active - 0, // minimum P-Chain height - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) innerVM.EXPECT().Initialize( @@ -2229,10 +2243,10 @@ func TestVMInnerBlkCache(t *testing.T) { ids.GenerateTestID(), // parent time.Time{}, // timestamp 1, // pChainHeight, - vm.stakingCertLeaf, // cert + vm.StakingCertLeaf, // cert blkNearTipInnerBytes, // inner blk bytes vm.ctx.ChainID, // chain ID - vm.stakingLeafSigner, // key + vm.StakingLeafSigner, // key ) require.NoError(err) @@ -2401,13 +2415,15 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { // Create a VM innerVM := mocks.NewMockChainVM(ctrl) vm := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, // fork is active - 0, // minimum P-Chain height - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) // make sure that DBs are compressed correctly @@ -2612,13 +2628,15 @@ func TestHistoricalBlockDeletion(t *testing.T) { db := prefixdb.New([]byte{}, memdb.New()) proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -2710,13 +2728,15 @@ func TestHistoricalBlockDeletion(t *testing.T) { numHistoricalBlocks := uint64(2) proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - numHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -2752,13 +2772,15 @@ func TestHistoricalBlockDeletion(t *testing.T) { newNumHistoricalBlocks := numHistoricalBlocks + 2 proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: newNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - newNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( From 96ddd5cef7efe4ca74054713ba374a9d0c9fb172 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 30 Nov 2023 10:30:43 +0100 Subject: [PATCH 007/111] fixed UTs --- chains/manager.go | 1 + vms/proposervm/batched_vm_test.go | 14 ++- vms/proposervm/block_test.go | 13 ++- vms/proposervm/post_fork_block_test.go | 67 +++++++++-- vms/proposervm/post_fork_option_test.go | 37 +++++- vms/proposervm/pre_fork_block_test.go | 60 +++++++--- vms/proposervm/state_syncable_vm_test.go | 7 +- vms/proposervm/vm_byzantine_test.go | 39 +++++-- vms/proposervm/vm_test.go | 136 +++++++++++++++++++---- 9 files changed, 302 insertions(+), 72 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index bfa0ae4aa7e7..13d80da37e43 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -770,6 +770,7 @@ func (m *manager) createAvalancheChain( var vmWrappingProposerVM block.ChainVM = proposervm.New( proposervm.Config{ ActivationTime: m.ApricotPhase4Time, + DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 25601dc63e09..a7838dec56c0 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -29,7 +29,11 @@ import ( func TestCoreVMNotRemote(t *testing.T) { // if coreVM is not remote VM, a specific error is returned require := require.New(t) - _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -54,7 +58,7 @@ func TestCoreVMNotRemote(t *testing.T) { func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -200,7 +204,7 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -558,7 +562,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -679,7 +683,7 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 5cca837a7a84..2bdc4e104c0d 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -93,7 +94,11 @@ func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() @@ -226,7 +231,11 @@ func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 25dfd4f63e8f..a2c5307787d8 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -38,7 +39,11 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { require.Equal(snowman.ErrNotOracle, err) // setup - _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -94,7 +99,11 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -192,7 +201,11 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -364,7 +377,11 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -502,7 +519,11 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -684,7 +705,11 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify a block once (in this test by building it). // Show that other verify call would not call coreBlk.Verify() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -747,7 +772,11 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -810,7 +839,11 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -858,7 +891,11 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -891,7 +928,11 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1006,7 +1047,11 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 5) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 5) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 7457186a8fe1..b5fdb3326248 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -37,7 +38,11 @@ func (tob TestOptionsBlock) Options(context.Context) ([2]snowman.Block, error) { func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -153,7 +158,11 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -255,7 +264,11 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -365,7 +378,11 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -467,7 +484,11 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -553,7 +574,11 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { func TestOptionTimestampValidity(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoForkTime, 0) coreOracleBlkID := ids.GenerateTestID() coreOracleBlk := &TestOptionsBlock{ diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 4308f9ba05f1..82c179661b88 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -51,7 +51,11 @@ func TestOracle_PreForkBlkImplementsInterface(t *testing.T) { func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -139,8 +143,11 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -233,8 +240,11 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -306,8 +316,11 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -437,8 +450,11 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(-1 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(-1 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(activationTime) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -479,7 +495,11 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -537,7 +557,11 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -568,8 +592,11 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -659,8 +686,11 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index b91ab91457a7..0c9a4c20c5a3 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/summary" statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" @@ -601,7 +602,11 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { require := require.New(t) // Note: by default proVM is built such that heightIndex will be considered complete - coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index dcfebf847cf3..ab19274073b8 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -33,8 +34,11 @@ import ( func TestInvalidByzantineProposerParent(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) // enable ProBlks - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -103,7 +107,11 @@ func TestInvalidByzantineProposerParent(t *testing.T) { func TestInvalidByzantineProposerOracleParent(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -211,8 +219,11 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { func TestInvalidByzantineProposerPreForkParent(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) // enable ProBlks - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -300,7 +311,11 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -399,7 +414,11 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { func TestBlockVerify_InvalidPostForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -586,7 +605,11 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { func TestGetBlock_MutatedSignature(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 83b89a32236f..11bf8a325b27 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -74,6 +74,7 @@ func init() { func initTestProposerVM( t *testing.T, proBlkStartTime time.Time, + durangoTime time.Time, minPChainHeight uint64, ) ( *fullVM, @@ -135,6 +136,7 @@ func initTestProposerVM( proVM := New( Config{ ActivationTime: proBlkStartTime, + DurangoTime: durangoTime, MinimumPChainHeight: minPChainHeight, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -219,7 +221,11 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -252,7 +258,11 @@ func TestBuildBlockIsIdempotent(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -287,7 +297,11 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -321,7 +335,11 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -416,7 +434,11 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -512,7 +534,11 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { require := require.New(t) - coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -551,7 +577,11 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { require := require.New(t) - coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -622,7 +652,11 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -690,7 +724,11 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { func TestPreFork_Initialize(t *testing.T) { require := require.New(t) - _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -709,7 +747,11 @@ func TestPreFork_Initialize(t *testing.T) { func TestPreFork_BuildBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -748,7 +790,11 @@ func TestPreFork_ParseBlock(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, _, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -783,7 +829,11 @@ func TestPreFork_ParseBlock(t *testing.T) { func TestPreFork_SetPreference(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -883,6 +933,7 @@ func TestExpiredBuildBlock(t *testing.T) { proVM := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1056,7 +1107,11 @@ func (b *wrappedBlock) Verify(ctx context.Context) error { func TestInnerBlockDeduplication(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // disable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1229,6 +1284,7 @@ func TestInnerVMRollback(t *testing.T) { proVM := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1318,6 +1374,7 @@ func TestInnerVMRollback(t *testing.T) { proVM = New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1356,7 +1413,11 @@ func TestInnerVMRollback(t *testing.T) { func TestBuildBlockDuringWindow(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1459,8 +1520,11 @@ func TestBuildBlockDuringWindow(t *testing.T) { func TestTwoForks_OneIsAccepted(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1555,8 +1619,11 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { func TestTooFarAdvanced(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1646,7 +1713,11 @@ func TestTooFarAdvanced(t *testing.T) { func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1721,7 +1792,11 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1812,6 +1887,7 @@ func TestRejectedHeightNotIndexed(t *testing.T) { proVM := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2021,6 +2097,7 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { proVM := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2186,6 +2263,7 @@ func TestVMInnerBlkCache(t *testing.T) { vm := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2286,8 +2364,11 @@ func TestVMInnerBlkCache(t *testing.T) { func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2362,8 +2443,11 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2417,6 +2501,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { vm := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2630,6 +2715,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2730,6 +2816,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM = New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, @@ -2774,6 +2861,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM = New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: newNumHistoricalBlocks, From ea743bf21951d55a1097f88155d663bb7b26714b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 30 Nov 2023 11:04:20 +0100 Subject: [PATCH 008/111] nit --- vms/proposervm/block.go | 72 +++++++++++++++++++++++++--------------- vms/proposervm/config.go | 8 +++-- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 86e73d5adc20..86196eaf6f6a 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -124,36 +124,11 @@ func (p *postForkCommonComponents) Verify( // If the node is currently syncing - we don't assume that the P-chain has // been synced up to this point yet. if p.vm.consensusState == snow.NormalOp { - childID := child.ID() - currentPChainHeight, err := p.vm.ctx.ValidatorState.GetCurrentHeight(ctx) - if err != nil { - p.vm.ctx.Log.Error("block verification failed", - zap.String("reason", "failed to get current P-Chain height"), - zap.Stringer("blkID", childID), - zap.Error(err), - ) - return err - } - if childPChainHeight > currentPChainHeight { - return fmt.Errorf("%w: %d > %d", - errPChainHeightNotReached, - childPChainHeight, - currentPChainHeight, - ) - } - - childHeight := child.Height() - proposerID := child.Proposer() - minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + delay, minDelay, err := p.verifyBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) if err != nil { return err } - delay := childTimestamp.Sub(parentTimestamp) - if delay < minDelay { - return errProposerWindowNotStarted - } - // Verify the signature of the node shouldHaveProposer := delay < proposer.MaxVerifyDelay if err := child.SignedBlock.Verify(shouldHaveProposer, p.vm.ctx.ChainID); err != nil { @@ -161,7 +136,7 @@ func (p *postForkCommonComponents) Verify( } p.vm.ctx.Log.Debug("verified post-fork block", - zap.Stringer("blkID", childID), + zap.Stringer("blkID", child.ID()), zap.Time("parentTimestamp", parentTimestamp), zap.Duration("minDelay", minDelay), zap.Time("blockTimestamp", childTimestamp), @@ -334,3 +309,46 @@ func verifyIsNotOracleBlock(ctx context.Context, b snowman.Block) error { return err } } + +func (p *postForkCommonComponents) verifyBlockDelay( + ctx context.Context, + parentTimestamp time.Time, + parentPChainHeight uint64, + blk *postForkBlock, +) (time.Duration, time.Duration, error) { + var ( + blkID = blk.ID() + blkPChainHeight = blk.PChainHeight() + blkTimestamp = blk.Timestamp() + ) + currentPChainHeight, err := p.vm.ctx.ValidatorState.GetCurrentHeight(ctx) + if err != nil { + p.vm.ctx.Log.Error("block verification failed", + zap.String("reason", "failed to get current P-Chain height"), + zap.Stringer("blkID", blkID), + zap.Error(err), + ) + return 0, 0, err + } + if blkPChainHeight > currentPChainHeight { + return 0, 0, fmt.Errorf("%w: %d > %d", + errPChainHeightNotReached, + blkPChainHeight, + currentPChainHeight, + ) + } + + childHeight := blk.Height() + proposerID := blk.Proposer() + minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + if err != nil { + return 0, 0, err + } + + delay := blkTimestamp.Sub(parentTimestamp) + if delay < minDelay { + return 0, 0, errProposerWindowNotStarted + } + + return delay, minDelay, nil +} diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 5de2314879a1..05d0f9f42cf8 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -16,6 +16,10 @@ type Config struct { MinimumPChainHeight uint64 MinBlkDelay time.Duration NumHistoricalBlocks uint64 - StakingLeafSigner crypto.Signer - StakingCertLeaf *staking.Certificate + + // block signer + StakingLeafSigner crypto.Signer + + // block certificate + StakingCertLeaf *staking.Certificate } From 863169367792ff498c02c2257b4c71ee99461ec6 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 30 Nov 2023 11:39:43 +0100 Subject: [PATCH 009/111] introduced post durango verification --- vms/proposervm/batched_vm_test.go | 1 + vms/proposervm/block.go | 90 ++++++++++++++++-------- vms/proposervm/block_test.go | 1 + vms/proposervm/config.go | 4 ++ vms/proposervm/post_fork_option_test.go | 1 + vms/proposervm/state_syncable_vm_test.go | 1 + vms/proposervm/vm_regression_test.go | 2 + 7 files changed, 70 insertions(+), 30 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index a7838dec56c0..920b8f43b38a 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1025,6 +1025,7 @@ func initTestRemoteProposerVM( proVM := New( Config{ ActivationTime: proBlkStartTime, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 86196eaf6f6a..2b72f78c6316 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -35,6 +35,7 @@ var ( errPChainHeightNotReached = errors.New("block P-chain height larger than current P-chain height") errTimeTooAdvanced = errors.New("time is too far advanced") errProposerWindowNotStarted = errors.New("proposer window hasn't started") + errUnexpectedProposer = errors.New("unexpected proposer for current window") errProposersNotActivated = errors.New("proposers haven't been activated yet") errPChainHeightTooLow = errors.New("block P-chain height is too low") ) @@ -124,13 +125,39 @@ func (p *postForkCommonComponents) Verify( // If the node is currently syncing - we don't assume that the P-chain has // been synced up to this point yet. if p.vm.consensusState == snow.NormalOp { - delay, minDelay, err := p.verifyBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) + currentPChainHeight, err := p.vm.ctx.ValidatorState.GetCurrentHeight(ctx) if err != nil { + p.vm.ctx.Log.Error("block verification failed", + zap.String("reason", "failed to get current P-Chain height"), + zap.Stringer("blkID", child.ID()), + zap.Error(err), + ) return err } + if childPChainHeight > currentPChainHeight { + return fmt.Errorf("%w: %d > %d", + errPChainHeightNotReached, + childPChainHeight, + currentPChainHeight, + ) + } + + shouldHaveProposer := true // post Durango this is always the case + if p.vm.IsDurangoActivated(parentTimestamp) { + err := p.verifyPostDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) + if err != nil { + return err + } + } else { + delay, err := p.verifyPreDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) + if err != nil { + return err + } + + shouldHaveProposer = delay < proposer.MaxVerifyDelay + } // Verify the signature of the node - shouldHaveProposer := delay < proposer.MaxVerifyDelay if err := child.SignedBlock.Verify(shouldHaveProposer, p.vm.ctx.ChainID); err != nil { return err } @@ -138,7 +165,6 @@ func (p *postForkCommonComponents) Verify( p.vm.ctx.Log.Debug("verified post-fork block", zap.Stringer("blkID", child.ID()), zap.Time("parentTimestamp", parentTimestamp), - zap.Duration("minDelay", minDelay), zap.Time("blockTimestamp", childTimestamp), ) } @@ -310,45 +336,49 @@ func verifyIsNotOracleBlock(ctx context.Context, b snowman.Block) error { } } -func (p *postForkCommonComponents) verifyBlockDelay( +func (p *postForkCommonComponents) verifyPreDurangoBlockDelay( ctx context.Context, parentTimestamp time.Time, parentPChainHeight uint64, blk *postForkBlock, -) (time.Duration, time.Duration, error) { +) (time.Duration, error) { var ( - blkID = blk.ID() - blkPChainHeight = blk.PChainHeight() - blkTimestamp = blk.Timestamp() + blkTimestamp = blk.Timestamp() + childHeight = blk.Height() + proposerID = blk.Proposer() ) - currentPChainHeight, err := p.vm.ctx.ValidatorState.GetCurrentHeight(ctx) - if err != nil { - p.vm.ctx.Log.Error("block verification failed", - zap.String("reason", "failed to get current P-Chain height"), - zap.Stringer("blkID", blkID), - zap.Error(err), - ) - return 0, 0, err - } - if blkPChainHeight > currentPChainHeight { - return 0, 0, fmt.Errorf("%w: %d > %d", - errPChainHeightNotReached, - blkPChainHeight, - currentPChainHeight, - ) - } - - childHeight := blk.Height() - proposerID := blk.Proposer() minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) if err != nil { - return 0, 0, err + return 0, err } delay := blkTimestamp.Sub(parentTimestamp) if delay < minDelay { - return 0, 0, errProposerWindowNotStarted + return 0, errProposerWindowNotStarted + } + + return delay, nil +} + +func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( + ctx context.Context, + parentTimestamp time.Time, + parentPChainHeight uint64, + blk *postForkBlock, +) error { + var ( + blkTimestamp = blk.Timestamp() + blkHeight = blk.Height() + proposerID = blk.Proposer() + ) + + expectedProposerID, err := p.vm.Windower.ExpectedProposer(ctx, blkHeight, parentPChainHeight, blkTimestamp, parentTimestamp) + if err != nil { + return err + } + if expectedProposerID != proposerID { + return errUnexpectedProposer } - return delay, minDelay, nil + return nil } diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 2bdc4e104c0d..b3fd8d0d5dbc 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -62,6 +62,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.NoError(err) vm := &VM{ Config: Config{ + DurangoTime: mockable.MaxTime, StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 05d0f9f42cf8..6b2b7a64d20b 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -23,3 +23,7 @@ type Config struct { // block certificate StakingCertLeaf *staking.Certificate } + +func (c *Config) IsDurangoActivated(timestamp time.Time) bool { + return !timestamp.Before(c.DurangoTime) +} diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index b5fdb3326248..83ba84528e30 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -686,6 +686,7 @@ func TestOptionTimestampValidity(t *testing.T) { proVM = New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 0c9a4c20c5a3..afb85f375a49 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -72,6 +72,7 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { vm := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index 792090a1f5cf..ee17d4e5d983 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/utils/timer/mockable" ) func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *testing.T) { @@ -47,6 +48,7 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test proVM := New( Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, From 86153c057253db53551a7d66b77e3465270656a3 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 30 Nov 2023 13:24:05 +0100 Subject: [PATCH 010/111] minor refactoring --- vms/proposervm/block.go | 86 ++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 2b72f78c6316..9c2ac8a3c38a 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -203,37 +203,15 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - delay := newTimestamp.Sub(parentTimestamp) - if delay < proposer.MaxBuildDelay { - parentHeight := p.innerBlk.Height() - proposerID := p.vm.ctx.NodeID - minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID, proposer.MaxBuildWindows) - if err != nil { - p.vm.ctx.Log.Error("unexpected build block failure", - zap.String("reason", "failed to calculate required timestamp delay"), - zap.Stringer("parentID", parentID), - zap.Error(err), - ) - return nil, err - } - - if delay < minDelay { - // It's not our turn to propose a block yet. This is likely caused - // by having previously notified the consensus engine to attempt to - // build a block on top of a block that is no longer the preferred - // block. - p.vm.ctx.Log.Debug("build block dropped", - zap.Time("parentTimestamp", parentTimestamp), - zap.Duration("minDelay", minDelay), - zap.Time("blockTimestamp", newTimestamp), - ) - - // In case the inner VM only issued one pendingTxs message, we - // should attempt to re-handle that once it is our turn to build the - // block. - p.vm.notifyInnerBlockReady() - return nil, errProposerWindowNotStarted - } + buildUnsignedBlock, err := p.shouldBuildBlock( + ctx, + parentID, + parentTimestamp, + parentPChainHeight, + newTimestamp, + ) + if err != nil { + return nil, err } var innerBlock snowman.Block @@ -250,7 +228,7 @@ func (p *postForkCommonComponents) buildChild( // Build the child var statelessChild block.SignedBlock - if delay >= proposer.MaxVerifyDelay { + if buildUnsignedBlock { statelessChild, err = block.BuildUnsigned( parentID, newTimestamp, @@ -382,3 +360,47 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( return nil } + +func (p *postForkCommonComponents) shouldBuildBlock( + ctx context.Context, + parentID ids.ID, + parentTimestamp time.Time, + parentPChainHeight uint64, + newTimestamp time.Time, +) (bool, error) { + delay := newTimestamp.Sub(parentTimestamp) + if delay >= proposer.MaxBuildDelay { + return true, nil + } + + parentHeight := p.innerBlk.Height() + proposerID := p.vm.ctx.NodeID + minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID, proposer.MaxBuildWindows) + if err != nil { + p.vm.ctx.Log.Error("unexpected build block failure", + zap.String("reason", "failed to calculate required timestamp delay"), + zap.Stringer("parentID", parentID), + zap.Error(err), + ) + return false, err + } + + if delay < minDelay { + // It's not our turn to propose a block yet. This is likely caused + // by having previously notified the consensus engine to attempt to + // build a block on top of a block that is no longer the preferred + // block. + p.vm.ctx.Log.Debug("build block dropped", + zap.Time("parentTimestamp", parentTimestamp), + zap.Duration("minDelay", minDelay), + zap.Time("blockTimestamp", newTimestamp), + ) + + // In case the inner VM only issued one pendingTxs message, we + // should attempt to re-handle that once it is our turn to build the + // block. + p.vm.notifyInnerBlockReady() + return false, errProposerWindowNotStarted + } + return delay >= proposer.MaxVerifyDelay, nil +} From 4b21cbd4c404ffb620d5da99d03e06f34946c544 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 30 Nov 2023 16:11:23 +0100 Subject: [PATCH 011/111] introduced post durango block build timing logic --- vms/proposervm/block.go | 46 ++++++++++++++++++++++++------ vms/proposervm/block_test.go | 4 ++- vms/proposervm/post_fork_block.go | 1 + vms/proposervm/post_fork_option.go | 1 + 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 9c2ac8a3c38a..893b8a9eec01 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -183,6 +183,7 @@ func (p *postForkCommonComponents) buildChild( ctx context.Context, parentID ids.ID, parentTimestamp time.Time, + parentHeight uint64, parentPChainHeight uint64, ) (Block, error) { // Child's timestamp is the later of now and this block's timestamp @@ -203,13 +204,24 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - buildUnsignedBlock, err := p.shouldBuildBlock( - ctx, - parentID, - parentTimestamp, - parentPChainHeight, - newTimestamp, - ) + buildUnsignedBlock := true + if p.vm.IsDurangoActivated(parentTimestamp) { + err = p.shouldPostDurangoBuildBlock( + ctx, + parentTimestamp, + parentHeight, + parentPChainHeight, + newTimestamp, + ) + } else { + buildUnsignedBlock, err = p.shouldPreDurangoBuildBlock( + ctx, + parentID, + parentTimestamp, + parentPChainHeight, + newTimestamp, + ) + } if err != nil { return nil, err } @@ -361,7 +373,25 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( return nil } -func (p *postForkCommonComponents) shouldBuildBlock( +func (p *postForkCommonComponents) shouldPostDurangoBuildBlock( + ctx context.Context, + parentTimestamp time.Time, + parentHeight uint64, + parentPChainHeight uint64, + newTimestamp time.Time, +) error { + expectedProposerID, err := p.vm.Windower.ExpectedProposer(ctx, parentHeight+1, parentPChainHeight, newTimestamp, parentTimestamp) + if err != nil { + return err + } + if expectedProposerID != p.vm.ctx.NodeID { + return errProposerWindowNotStarted + } + + return nil +} + +func (p *postForkCommonComponents) shouldPreDurangoBuildBlock( ctx context.Context, parentID ids.ID, parentTimestamp time.Time, diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index b3fd8d0d5dbc..478a92c334f5 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -40,10 +40,11 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { pChainHeight := uint64(1337) parentID := ids.GenerateTestID() parentTimestamp := time.Now() + parentHeight := uint64(1234) blkID := ids.GenerateTestID() innerBlk := snowman.NewMockBlock(ctrl) innerBlk.EXPECT().ID().Return(blkID).AnyTimes() - innerBlk.EXPECT().Height().Return(pChainHeight - 1).AnyTimes() + innerBlk.EXPECT().Height().Return(parentHeight + 1).AnyTimes() builtBlk := snowman.NewMockBlock(ctrl) builtBlk.EXPECT().Bytes().Return([]byte{1, 2, 3}).AnyTimes() builtBlk.EXPECT().ID().Return(ids.GenerateTestID()).AnyTimes() @@ -85,6 +86,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { context.Background(), parentID, parentTimestamp, + parentHeight, pChainHeight-1, ) require.NoError(err) diff --git a/vms/proposervm/post_fork_block.go b/vms/proposervm/post_fork_block.go index 28d127d33f70..bea8ead5d851 100644 --- a/vms/proposervm/post_fork_block.go +++ b/vms/proposervm/post_fork_block.go @@ -149,6 +149,7 @@ func (b *postForkBlock) buildChild(ctx context.Context) (Block, error) { ctx, b.ID(), b.Timestamp(), + b.Height(), b.PChainHeight(), ) } diff --git a/vms/proposervm/post_fork_option.go b/vms/proposervm/post_fork_option.go index 047a01c477fd..fa3f86cbcca1 100644 --- a/vms/proposervm/post_fork_option.go +++ b/vms/proposervm/post_fork_option.go @@ -121,6 +121,7 @@ func (b *postForkOption) buildChild(ctx context.Context) (Block, error) { ctx, parentID, b.Timestamp(), + b.Height(), parentPChainHeight, ) } From 4fc372d636225f635880491a17ca15f81f6cc6ed Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 14:44:52 +0100 Subject: [PATCH 012/111] proposervm config + minor refactoring --- chains/manager.go | 28 ++-- vms/proposervm/batched_vm_test.go | 14 +- vms/proposervm/block.go | 128 +++++++++++------ vms/proposervm/block_test.go | 8 +- vms/proposervm/config.go | 24 ++++ vms/proposervm/height_indexed_vm.go | 10 +- vms/proposervm/post_fork_block_test.go | 40 +++--- vms/proposervm/post_fork_option_test.go | 14 +- vms/proposervm/pre_fork_block.go | 10 +- vms/proposervm/pre_fork_block_test.go | 10 +- vms/proposervm/state_syncable_vm_test.go | 38 ++--- vms/proposervm/vm.go | 33 +---- vms/proposervm/vm_regression_test.go | 15 +- vms/proposervm/vm_test.go | 170 +++++++++++++---------- 14 files changed, 310 insertions(+), 232 deletions(-) create mode 100644 vms/proposervm/config.go diff --git a/chains/manager.go b/chains/manager.go index e764a5dfb3ce..8df8b8152a35 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -768,13 +768,15 @@ func (m *manager) createAvalancheChain( // Note: vmWrappingProposerVM is the VM that the Snowman engines should be // using. var vmWrappingProposerVM block.ChainVM = proposervm.New( + proposervm.Config{ + ActivationTime: m.ApricotPhase4Time, + MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + MinBlkDelay: minBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: m.stakingSigner, + StakingCertLeaf: m.stakingCert, + }, vmWrappedInsideProposerVM, - m.ApricotPhase4Time, - m.ApricotPhase4MinPChainHeight, - minBlockDelay, - numHistoricalBlocks, - m.stakingSigner, - m.stakingCert, ) if m.MeterVMEnabled { @@ -1111,13 +1113,15 @@ func (m *manager) createSnowmanChain( } vm = proposervm.New( + proposervm.Config{ + ActivationTime: m.ApricotPhase4Time, + MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, + MinBlkDelay: minBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: m.stakingSigner, + StakingCertLeaf: m.stakingCert, + }, vm, - m.ApricotPhase4Time, - m.ApricotPhase4MinPChainHeight, - minBlockDelay, - numHistoricalBlocks, - m.stakingSigner, - m.stakingCert, ) if m.MeterVMEnabled { diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 684d91ceb3df..25601dc63e09 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1019,13 +1019,15 @@ func initTestRemoteProposerVM( } proVM := New( + Config{ + ActivationTime: proBlkStartTime, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - proBlkStartTime, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 489d325f8f70..62fa78bfbf95 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -124,12 +124,11 @@ func (p *postForkCommonComponents) Verify( // If the node is currently syncing - we don't assume that the P-chain has // been synced up to this point yet. if p.vm.consensusState == snow.NormalOp { - childID := child.ID() currentPChainHeight, err := p.vm.ctx.ValidatorState.GetCurrentHeight(ctx) if err != nil { p.vm.ctx.Log.Error("block verification failed", zap.String("reason", "failed to get current P-Chain height"), - zap.Stringer("blkID", childID), + zap.Stringer("blkID", child.ID()), zap.Error(err), ) return err @@ -142,18 +141,11 @@ func (p *postForkCommonComponents) Verify( ) } - childHeight := child.Height() - proposerID := child.Proposer() - minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + delay, minDelay, err := p.verifyBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) if err != nil { return err } - delay := childTimestamp.Sub(parentTimestamp) - if delay < minDelay { - return errProposerWindowNotStarted - } - // Verify the signature of the node shouldHaveProposer := delay < proposer.MaxVerifyDelay if err := child.SignedBlock.Verify(shouldHaveProposer, p.vm.ctx.ChainID); err != nil { @@ -161,7 +153,7 @@ func (p *postForkCommonComponents) Verify( } p.vm.ctx.Log.Debug("verified post-fork block", - zap.Stringer("blkID", childID), + zap.Stringer("blkID", child.ID()), zap.Time("parentTimestamp", parentTimestamp), zap.Duration("minDelay", minDelay), zap.Time("blockTimestamp", childTimestamp), @@ -202,37 +194,15 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - delay := newTimestamp.Sub(parentTimestamp) - if delay < proposer.MaxBuildDelay { - parentHeight := p.innerBlk.Height() - proposerID := p.vm.ctx.NodeID - minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID, proposer.MaxBuildWindows) - if err != nil { - p.vm.ctx.Log.Error("unexpected build block failure", - zap.String("reason", "failed to calculate required timestamp delay"), - zap.Stringer("parentID", parentID), - zap.Error(err), - ) - return nil, err - } - - if delay < minDelay { - // It's not our turn to propose a block yet. This is likely caused - // by having previously notified the consensus engine to attempt to - // build a block on top of a block that is no longer the preferred - // block. - p.vm.ctx.Log.Debug("build block dropped", - zap.Time("parentTimestamp", parentTimestamp), - zap.Duration("minDelay", minDelay), - zap.Time("blockTimestamp", newTimestamp), - ) - - // In case the inner VM only issued one pendingTxs message, we - // should attempt to re-handle that once it is our turn to build the - // block. - p.vm.notifyInnerBlockReady() - return nil, errProposerWindowNotStarted - } + buildUnsignedBlock, err := p.shouldBuildBlock( + ctx, + parentID, + parentTimestamp, + parentPChainHeight, + newTimestamp, + ) + if err != nil { + return nil, err } var innerBlock snowman.Block @@ -249,7 +219,7 @@ func (p *postForkCommonComponents) buildChild( // Build the child var statelessChild block.SignedBlock - if delay >= proposer.MaxVerifyDelay { + if buildUnsignedBlock { statelessChild, err = block.BuildUnsigned( parentID, newTimestamp, @@ -261,10 +231,10 @@ func (p *postForkCommonComponents) buildChild( parentID, newTimestamp, pChainHeight, - p.vm.stakingCertLeaf, + p.vm.StakingCertLeaf, innerBlock.Bytes(), p.vm.ctx.ChainID, - p.vm.stakingLeafSigner, + p.vm.StakingLeafSigner, ) } if err != nil { @@ -334,3 +304,71 @@ func verifyIsNotOracleBlock(ctx context.Context, b snowman.Block) error { return err } } + +func (p *postForkCommonComponents) verifyBlockDelay( + ctx context.Context, + parentTimestamp time.Time, + parentPChainHeight uint64, + blk *postForkBlock, +) (time.Duration, time.Duration, error) { + var ( + blkTimestamp = blk.Timestamp() + childHeight = blk.Height() + proposerID = blk.Proposer() + ) + minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + if err != nil { + return 0, 0, err + } + + delay := blkTimestamp.Sub(parentTimestamp) + if delay < minDelay { + return 0, 0, errProposerWindowNotStarted + } + + return delay, minDelay, nil +} + +func (p *postForkCommonComponents) shouldBuildBlock( + ctx context.Context, + parentID ids.ID, + parentTimestamp time.Time, + parentPChainHeight uint64, + newTimestamp time.Time, +) (bool, error) { + delay := newTimestamp.Sub(parentTimestamp) + if delay >= proposer.MaxBuildDelay { + return true, nil + } + + parentHeight := p.innerBlk.Height() + proposerID := p.vm.ctx.NodeID + minDelay, err := p.vm.Windower.Delay(ctx, parentHeight+1, parentPChainHeight, proposerID, proposer.MaxBuildWindows) + if err != nil { + p.vm.ctx.Log.Error("unexpected build block failure", + zap.String("reason", "failed to calculate required timestamp delay"), + zap.Stringer("parentID", parentID), + zap.Error(err), + ) + return false, err + } + + if delay < minDelay { + // It's not our turn to propose a block yet. This is likely caused + // by having previously notified the consensus engine to attempt to + // build a block on top of a block that is no longer the preferred + // block. + p.vm.ctx.Log.Debug("build block dropped", + zap.Time("parentTimestamp", parentTimestamp), + zap.Duration("minDelay", minDelay), + zap.Time("blockTimestamp", newTimestamp), + ) + + // In case the inner VM only issued one pendingTxs message, we + // should attempt to re-handle that once it is our turn to build the + // block. + p.vm.notifyInnerBlockReady() + return false, errProposerWindowNotStarted + } + return delay >= proposer.MaxVerifyDelay, nil +} diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 04ac66ecf34e..5cca837a7a84 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -60,15 +60,17 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) vm := &VM{ + Config: Config{ + StakingCertLeaf: &staking.Certificate{}, + StakingLeafSigner: pk, + }, ChainVM: innerVM, blockBuilderVM: innerBlockBuilderVM, ctx: &snow.Context{ ValidatorState: vdrState, Log: logging.NoLog{}, }, - Windower: windower, - stakingCertLeaf: &staking.Certificate{}, - stakingLeafSigner: pk, + Windower: windower, } blk := &postForkCommonComponents{ diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go new file mode 100644 index 000000000000..185ad7b86f30 --- /dev/null +++ b/vms/proposervm/config.go @@ -0,0 +1,24 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package proposervm + +import ( + "crypto" + "time" + + "github.com/ava-labs/avalanchego/staking" +) + +type Config struct { + ActivationTime time.Time + MinimumPChainHeight uint64 + MinBlkDelay time.Duration + NumHistoricalBlocks uint64 + + // block signer + StakingLeafSigner crypto.Signer + + // block certificate + StakingCertLeaf *staking.Certificate +} diff --git a/vms/proposervm/height_indexed_vm.go b/vms/proposervm/height_indexed_vm.go index 99b911c5be64..6c8d6967ee14 100644 --- a/vms/proposervm/height_indexed_vm.go +++ b/vms/proposervm/height_indexed_vm.go @@ -136,7 +136,7 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { zap.Uint64("height", height), ) - if vm.numHistoricalBlocks == 0 { + if vm.NumHistoricalBlocks == 0 { return nil } @@ -145,13 +145,13 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { // is why <= is used rather than <. This prevents the user from only storing // the last accepted block, which can never be safe due to the non-atomic // commits between the proposervm database and the innerVM's database. - if blocksSinceFork <= vm.numHistoricalBlocks { + if blocksSinceFork <= vm.NumHistoricalBlocks { return nil } // Note: heightToDelete is >= forkHeight, so it is guaranteed not to // underflow. - heightToDelete := height - vm.numHistoricalBlocks - 1 + heightToDelete := height - vm.NumHistoricalBlocks - 1 blockToDelete, err := vm.State.GetBlockIDAtHeight(heightToDelete) if err == database.ErrNotFound { // Block may have already been deleted. This can happen due to a @@ -180,7 +180,7 @@ func (vm *VM) storeHeightEntry(height uint64, blkID ids.ID) error { // TODO: Support async deletion of old blocks. func (vm *VM) pruneOldBlocks() error { - if vm.numHistoricalBlocks == 0 { + if vm.NumHistoricalBlocks == 0 { return nil } @@ -194,7 +194,7 @@ func (vm *VM) pruneOldBlocks() error { // // Note: vm.lastAcceptedHeight is guaranteed to be >= height, so the // subtraction can never underflow. - for vm.lastAcceptedHeight-height > vm.numHistoricalBlocks { + for vm.lastAcceptedHeight-height > vm.NumHistoricalBlocks { blockToDelete, err := vm.State.GetBlockIDAtHeight(height) if err != nil { return err diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 659bdd1e5fd3..25dfd4f63e8f 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -70,10 +70,10 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { ids.Empty, // refer unknown parent time.Time{}, 0, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerOracleBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk = postForkBlock{ @@ -155,10 +155,10 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { ids.Empty, // refer unknown parent childCoreBlk.Timestamp(), pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -260,10 +260,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), childCoreBlk.Timestamp(), pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -287,10 +287,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), beforeWinStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -305,10 +305,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), atWindowStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -322,10 +322,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), afterWindowStart, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -350,10 +350,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { prntProBlk.ID(), afterSubWinEnd, pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk.SignedBlock = childSlb @@ -431,10 +431,10 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { prntProBlk.ID(), childCoreBlk.Timestamp(), prntBlkPChainHeight-1, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -611,10 +611,10 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) parentBlk.ID(), childCoreBlk.Timestamp(), prntBlkPChainHeight-1, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) childProBlk := postForkBlock{ @@ -986,10 +986,10 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { postForkOracleBlk.ID(), postForkOracleBlk.Timestamp().Add(proposer.WindowDuration), postForkOracleBlk.PChainHeight(), - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, oracleCoreBlk.opts[0].Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 8e93e2aad05f..7457186a8fe1 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -659,13 +659,15 @@ func TestOptionTimestampValidity(t *testing.T) { // Restart the node. ctx := proVM.ctx proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) coreVM.InitializeF = func( diff --git a/vms/proposervm/pre_fork_block.go b/vms/proposervm/pre_fork_block.go index ed665e473910..8e952d9d7758 100644 --- a/vms/proposervm/pre_fork_block.go +++ b/vms/proposervm/pre_fork_block.go @@ -97,7 +97,7 @@ func (b *preForkBlock) getInnerBlk() snowman.Block { func (b *preForkBlock) verifyPreForkChild(ctx context.Context, child *preForkBlock) error { parentTimestamp := b.Timestamp() - if !parentTimestamp.Before(b.vm.activationTime) { + if !parentTimestamp.Before(b.vm.ActivationTime) { if err := verifyIsOracleBlock(ctx, b.Block); err != nil { return err } @@ -135,7 +135,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB currentPChainHeight, ) } - if childPChainHeight < b.vm.minimumPChainHeight { + if childPChainHeight < b.vm.MinimumPChainHeight { return errPChainHeightTooLow } @@ -150,7 +150,7 @@ func (b *preForkBlock) verifyPostForkChild(ctx context.Context, child *postForkB // if the *preForkBlock is the last *preForkBlock before activation takes effect // (its timestamp is at or after the activation time) parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.activationTime) { + if parentTimestamp.Before(b.vm.ActivationTime) { return errProposersNotActivated } @@ -181,7 +181,7 @@ func (*preForkBlock) verifyPostForkOption(context.Context, *postForkOption) erro func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { parentTimestamp := b.Timestamp() - if parentTimestamp.Before(b.vm.activationTime) { + if parentTimestamp.Before(b.vm.ActivationTime) { // The chain hasn't forked yet innerBlock, err := b.vm.ChainVM.BuildBlock(ctx) if err != nil { @@ -210,7 +210,7 @@ func (b *preForkBlock) buildChild(ctx context.Context) (Block, error) { // The child's P-Chain height is proposed as the optimal P-Chain height that // is at least the minimum height - pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.minimumPChainHeight) + pChainHeight, err := b.vm.optimalPChainHeight(ctx, b.vm.MinimumPChainHeight) if err != nil { b.vm.ctx.Log.Error("unexpected build block failure", zap.String("reason", "failed to calculate optimal P-chain height"), diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 1366482a0d9b..4308f9ba05f1 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -342,10 +342,10 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { coreGenBlk.ID(), coreBlk.Timestamp(), 0, // pChainHeight - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, coreBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) postForkChild := &postForkBlock{ @@ -740,10 +740,10 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { firstBlock.ID(), // refer unknown parent firstBlock.Timestamp(), 0, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, coreBlk.opts[0].Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) @@ -798,7 +798,7 @@ func TestPreForkBlock_BuildBlockWithContext(t *testing.T) { // Should call BuildBlock since proposervm is not activated innerBlk.EXPECT().Timestamp().Return(time.Time{}) - vm.activationTime = mockable.MaxTime + vm.ActivationTime = mockable.MaxTime gotChild, err = blk.buildChild(context.Background()) require.NoError(err) diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 826f8b877987..b91ab91457a7 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -69,13 +69,15 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { // create the VM vm := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) ctx := snow.DefaultContextTest() @@ -186,10 +188,10 @@ func TestStateSyncGetOngoingSyncStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -271,10 +273,10 @@ func TestStateSyncGetLastStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -359,10 +361,10 @@ func TestStateSyncGetStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -432,10 +434,10 @@ func TestParseStateSummary(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ @@ -487,10 +489,10 @@ func TestStateSummaryAccept(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) @@ -567,10 +569,10 @@ func TestStateSummaryAcceptOlderBlock(t *testing.T) { vm.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - vm.stakingCertLeaf, + vm.StakingCertLeaf, innerBlk.Bytes(), vm.ctx.ChainID, - vm.stakingLeafSigner, + vm.StakingLeafSigner, ) require.NoError(err) proBlk := &postForkBlock{ diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index a7bb897932d3..01afda96abb1 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -5,7 +5,6 @@ package proposervm import ( "context" - "crypto" "errors" "fmt" "time" @@ -26,7 +25,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils" "github.com/ava-labs/avalanchego/utils/constants" "github.com/ava-labs/avalanchego/utils/math" @@ -86,19 +84,11 @@ func cachedBlockSize(_ ids.ID, blk snowman.Block) int { type VM struct { block.ChainVM + Config blockBuilderVM block.BuildBlockWithContextChainVM batchedVM block.BatchedChainVM ssVM block.StateSyncableVM - activationTime time.Time - minimumPChainHeight uint64 - minBlkDelay time.Duration - numHistoricalBlocks uint64 - // block signer - stakingLeafSigner crypto.Signer - // block certificate - stakingCertLeaf *staking.Certificate - state.State hIndexer indexer.HeightIndexer @@ -137,29 +127,18 @@ type VM struct { // New performs best when [minBlkDelay] is whole seconds. This is because block // timestamps are only specific to the second. func New( + config Config, vm block.ChainVM, - activationTime time.Time, - minimumPChainHeight uint64, - minBlkDelay time.Duration, - numHistoricalBlocks uint64, - stakingLeafSigner crypto.Signer, - stakingCertLeaf *staking.Certificate, ) *VM { blockBuilderVM, _ := vm.(block.BuildBlockWithContextChainVM) batchedVM, _ := vm.(block.BatchedChainVM) ssVM, _ := vm.(block.StateSyncableVM) return &VM{ ChainVM: vm, + Config: config, blockBuilderVM: blockBuilderVM, batchedVM: batchedVM, ssVM: ssVM, - - activationTime: activationTime, - minimumPChainHeight: minimumPChainHeight, - minBlkDelay: minBlkDelay, - numHistoricalBlocks: numHistoricalBlocks, - stakingLeafSigner: stakingLeafSigner, - stakingCertLeaf: stakingCertLeaf, } } @@ -373,8 +352,8 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { // validators can specify. This delay may be an issue for high performance, // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. - if minDelay < vm.minBlkDelay { - minDelay = vm.minBlkDelay + if minDelay < vm.MinBlkDelay { + minDelay = vm.MinBlkDelay } preferredTime := blk.Timestamp() @@ -418,7 +397,7 @@ func (vm *VM) repair(ctx context.Context) error { return err } - if vm.numHistoricalBlocks != 0 { + if vm.NumHistoricalBlocks != 0 { vm.ctx.Log.Fatal("block height index must be valid when pruning historical blocks") return errHeightIndexInvalidWhilePruning } diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index 0a27c43e112a..792090a1f5cf 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -45,14 +45,17 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) + defer func() { // avoids leaking goroutines require.NoError(proVM.Shutdown(context.Background())) diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index fb8672d8b2f4..83b89a32236f 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -133,13 +133,15 @@ func initTestProposerVM( } proVM := New( + Config{ + ActivationTime: proBlkStartTime, + MinimumPChainHeight: minPChainHeight, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - proBlkStartTime, - minPChainHeight, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -526,10 +528,10 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk := postForkBlock{ @@ -570,10 +572,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 100, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk1 := postForkBlock{ @@ -589,10 +591,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { proVM.preferred, innerBlk.Timestamp(), 200, // pChainHeight, - proVM.stakingCertLeaf, + proVM.StakingCertLeaf, innerBlk.Bytes(), proVM.ctx.ChainID, - proVM.stakingLeafSigner, + proVM.StakingLeafSigner, ) require.NoError(err) proBlk2 := postForkBlock{ @@ -879,13 +881,15 @@ func TestExpiredBuildBlock(t *testing.T) { } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -1223,13 +1227,15 @@ func TestInnerVMRollback(t *testing.T) { db := memdb.New() proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -1310,13 +1316,15 @@ func TestInnerVMRollback(t *testing.T) { } proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -1802,13 +1810,15 @@ func TestRejectedHeightNotIndexed(t *testing.T) { } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -2009,13 +2019,15 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { } proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) valState := &validators.TestState{ @@ -2172,13 +2184,15 @@ func TestVMInnerBlkCache(t *testing.T) { // Create a VM innerVM := mocks.NewMockChainVM(ctrl) vm := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, // fork is active - 0, // minimum P-Chain height - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) innerVM.EXPECT().Initialize( @@ -2229,10 +2243,10 @@ func TestVMInnerBlkCache(t *testing.T) { ids.GenerateTestID(), // parent time.Time{}, // timestamp 1, // pChainHeight, - vm.stakingCertLeaf, // cert + vm.StakingCertLeaf, // cert blkNearTipInnerBytes, // inner blk bytes vm.ctx.ChainID, // chain ID - vm.stakingLeafSigner, // key + vm.StakingLeafSigner, // key ) require.NoError(err) @@ -2401,13 +2415,15 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { // Create a VM innerVM := mocks.NewMockChainVM(ctrl) vm := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, innerVM, - time.Time{}, // fork is active - 0, // minimum P-Chain height - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) // make sure that DBs are compressed correctly @@ -2612,13 +2628,15 @@ func TestHistoricalBlockDeletion(t *testing.T) { db := prefixdb.New([]byte{}, memdb.New()) proVM := New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: DefaultNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - DefaultNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -2710,13 +2728,15 @@ func TestHistoricalBlockDeletion(t *testing.T) { numHistoricalBlocks := uint64(2) proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: numHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - numHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( @@ -2752,13 +2772,15 @@ func TestHistoricalBlockDeletion(t *testing.T) { newNumHistoricalBlocks := numHistoricalBlocks + 2 proVM = New( + Config{ + ActivationTime: time.Time{}, + MinimumPChainHeight: 0, + MinBlkDelay: DefaultMinBlockDelay, + NumHistoricalBlocks: newNumHistoricalBlocks, + StakingLeafSigner: pTestSigner, + StakingCertLeaf: pTestCert, + }, coreVM, - time.Time{}, - 0, - DefaultMinBlockDelay, - newNumHistoricalBlocks, - pTestSigner, - pTestCert, ) require.NoError(proVM.Initialize( From 2af05f83d5c34125e7a781dbe2de1a69d6ce6071 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 15:47:58 +0100 Subject: [PATCH 013/111] added test for expected proposer variance --- vms/proposervm/proposer/windower.go | 7 +++- vms/proposervm/proposer/windower_test.go | 50 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index c61329beec98..171960b87a94 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -116,8 +116,11 @@ func (w *windower) ExpectedProposer( return ids.EmptyNodeID, err } - numToSample := 1 - seed := chainHeight ^ w.chainSource ^ uint64((blockTime.Sub(parentBlockTime) / WindowDuration)) + var ( + numToSample = 1 + slot = blockTime.Sub(parentBlockTime) / WindowDuration + seed = chainHeight ^ w.chainSource ^ uint64(slot) + ) w.sampler.Seed(int64(seed)) indices, err := w.sampler.Sample(numToSample) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 5c05cf397d85..4d95ae874570 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -379,3 +379,53 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { require.Equal(validatorIDs[9], proposerID) } } + +func TestExpectedProposerVariance(t *testing.T) { + require := require.New(t) + + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + + validatorsCount = 10 + ) + + validatorIDs := make([]ids.NodeID, validatorsCount) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + + w := New(vdrState, subnetID, chainID) + + var ( + dummyCtx = context.Background() + pChainHeight = uint64(0) + parentBlockTime = time.Now().Truncate(time.Second) + + chainHeight = uint64(10) + blockTime = parentBlockTime.Add(time.Second) + ) + + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[6], proposerID) + + chainHeight += 1 + blockTime = parentBlockTime.Add(WindowDuration).Add(time.Second) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + require.NoError(err) + require.Equal(validatorIDs[6], proposerID) +} From d226792ca78e2995aba77dcdb6e41c0d68018ff3 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 15:56:19 +0100 Subject: [PATCH 014/111] nit --- vms/proposervm/block.go | 2 +- vms/proposervm/block_test.go | 1 - vms/proposervm/post_fork_block.go | 1 - vms/proposervm/post_fork_option.go | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 893b8a9eec01..f7016f479148 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -183,7 +183,6 @@ func (p *postForkCommonComponents) buildChild( ctx context.Context, parentID ids.ID, parentTimestamp time.Time, - parentHeight uint64, parentPChainHeight uint64, ) (Block, error) { // Child's timestamp is the later of now and this block's timestamp @@ -206,6 +205,7 @@ func (p *postForkCommonComponents) buildChild( buildUnsignedBlock := true if p.vm.IsDurangoActivated(parentTimestamp) { + parentHeight := p.innerBlk.Height() - 1 err = p.shouldPostDurangoBuildBlock( ctx, parentTimestamp, diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 478a92c334f5..4c57378cdfcc 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -86,7 +86,6 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { context.Background(), parentID, parentTimestamp, - parentHeight, pChainHeight-1, ) require.NoError(err) diff --git a/vms/proposervm/post_fork_block.go b/vms/proposervm/post_fork_block.go index bea8ead5d851..28d127d33f70 100644 --- a/vms/proposervm/post_fork_block.go +++ b/vms/proposervm/post_fork_block.go @@ -149,7 +149,6 @@ func (b *postForkBlock) buildChild(ctx context.Context) (Block, error) { ctx, b.ID(), b.Timestamp(), - b.Height(), b.PChainHeight(), ) } diff --git a/vms/proposervm/post_fork_option.go b/vms/proposervm/post_fork_option.go index fa3f86cbcca1..047a01c477fd 100644 --- a/vms/proposervm/post_fork_option.go +++ b/vms/proposervm/post_fork_option.go @@ -121,7 +121,6 @@ func (b *postForkOption) buildChild(ctx context.Context) (Block, error) { ctx, parentID, b.Timestamp(), - b.Height(), parentPChainHeight, ) } From 6edf17da77d14971e0a8381aa634766eb7f9e2f8 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 16:34:39 +0100 Subject: [PATCH 015/111] wip: updating proposerVM UTs to post durango --- vms/proposervm/batched_vm_test.go | 63 +++++++++++++++++++-------- vms/proposervm/pre_fork_block_test.go | 18 ++++---- vms/proposervm/vm_test.go | 48 ++++++++++---------- 3 files changed, 78 insertions(+), 51 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 920b8f43b38a..31155269737d 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -31,7 +31,7 @@ func TestCoreVMNotRemote(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -58,7 +58,11 @@ func TestCoreVMNotRemote(t *testing.T) { func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) + var ( + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -204,7 +208,11 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -356,13 +364,18 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { require := require.New(t) - currentTime := time.Now().Truncate(time.Second) - preForkTime := currentTime.Add(5 * time.Minute) - forkTime := currentTime.Add(10 * time.Minute) - postForkTime := currentTime.Add(15 * time.Minute) + + var ( + currentTime = time.Now().Truncate(time.Second) + preForkTime = currentTime.Add(5 * time.Minute) + forkTime = currentTime.Add(10 * time.Minute) + postForkTime = currentTime.Add(15 * time.Minute) + + durangoTime = mockable.MaxTime + ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -562,7 +575,11 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) + var ( + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -683,7 +700,11 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) + var ( + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -792,13 +813,18 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { require := require.New(t) - currentTime := time.Now().Truncate(time.Second) - preForkTime := currentTime.Add(5 * time.Minute) - forkTime := currentTime.Add(10 * time.Minute) - postForkTime := currentTime.Add(15 * time.Minute) + + var ( + currentTime = time.Now().Truncate(time.Second) + preForkTime = currentTime.Add(5 * time.Minute) + forkTime = currentTime.Add(10 * time.Minute) + postForkTime = currentTime.Add(15 * time.Minute) + + durangoTime = mockable.MaxTime + ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -960,7 +986,8 @@ type TestRemoteProposerVM struct { func initTestRemoteProposerVM( t *testing.T, - proBlkStartTime time.Time, + activationTime, + durangoTime time.Time, ) ( TestRemoteProposerVM, *VM, @@ -1024,8 +1051,8 @@ func initTestRemoteProposerVM( proVM := New( Config{ - ActivationTime: proBlkStartTime, - DurangoTime: mockable.MaxTime, + ActivationTime: activationTime, + DurangoTime: durangoTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 82c179661b88..0418a55355cb 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -53,7 +53,7 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -145,7 +145,7 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -242,7 +242,7 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -318,7 +318,7 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -452,7 +452,7 @@ func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { var ( activationTime = genesisTimestamp.Add(-1 * time.Second) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(activationTime) @@ -497,7 +497,7 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { // setup var ( activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -559,7 +559,7 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -594,7 +594,7 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -688,7 +688,7 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 11bf8a325b27..e094c39de3d7 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -223,7 +223,7 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -260,7 +260,7 @@ func TestBuildBlockIsIdempotent(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -299,7 +299,7 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { // setup var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -536,7 +536,7 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -579,7 +579,7 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -654,7 +654,7 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -725,8 +725,8 @@ func TestPreFork_Initialize(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -749,7 +749,7 @@ func TestPreFork_BuildBlock(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -792,7 +792,7 @@ func TestPreFork_ParseBlock(t *testing.T) { // setup var ( activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -831,7 +831,7 @@ func TestPreFork_SetPreference(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -1109,7 +1109,7 @@ func TestInnerBlockDeduplication(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -1794,7 +1794,7 @@ func TestLaggedPChainHeight(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -1886,8 +1886,8 @@ func TestRejectedHeightNotIndexed(t *testing.T) { proVM := New( Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2096,8 +2096,8 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { proVM := New( Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2262,8 +2262,8 @@ func TestVMInnerBlkCache(t *testing.T) { innerVM := mocks.NewMockChainVM(ctrl) vm := New( Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2366,7 +2366,7 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -2445,7 +2445,7 @@ func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -2500,8 +2500,8 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { innerVM := mocks.NewMockChainVM(ctrl) vm := New( Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2714,7 +2714,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM := New( Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, From 8dde95e0595fa3d5fa93a1a86e4faabe05f0b8df Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 16:42:30 +0100 Subject: [PATCH 016/111] wip: some more updating proposerVM UTs to post durango --- vms/proposervm/block_test.go | 1 + vms/proposervm/state_syncable_vm_test.go | 7 +++---- vms/proposervm/vm_regression_test.go | 5 ++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 4c57378cdfcc..58dd5c3c181f 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -63,6 +63,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.NoError(err) vm := &VM{ Config: Config{ + ActivationTime: time.Unix(0, 0), DurangoTime: mockable.MaxTime, StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index afb85f375a49..d7ccff80a804 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -19,7 +19,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/summary" statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" @@ -71,8 +70,8 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { // create the VM vm := New( Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -605,7 +604,7 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { // Note: by default proVM is built such that heightIndex will be considered complete var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index ee17d4e5d983..3deef6ac9629 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/utils/timer/mockable" ) func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *testing.T) { @@ -47,8 +46,8 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test proVM := New( Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, From 0dc76b73fee6156b044ea4fbf263c11ad906749e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 18:31:07 +0100 Subject: [PATCH 017/111] wip: adding post durango UTs --- vms/proposervm/post_fork_block_test.go | 188 +++++++++++++++++++------ 1 file changed, 148 insertions(+), 40 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index a2c5307787d8..403918fda1f5 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -41,7 +41,7 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { // setup var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -96,7 +96,7 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { } // ProposerBlock.Verify tests section -func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { +func TestBlockVerify_PostForkBlock_PreDurango_ParentChecks(t *testing.T) { require := require.New(t) var ( @@ -113,8 +113,7 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { return pChainHeight, nil } - // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -124,14 +123,14 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { TimestampV: coreGenBlk.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -140,38 +139,25 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - // .. create child block ... childCoreBlk := &snowman.TestBlock{ - ParentV: prntCoreBlk.ID(), + ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, - TimestampV: prntCoreBlk.Timestamp(), + TimestampV: parentCoreBlk.Timestamp(), } - childSlb, err := block.Build( - ids.Empty, // refer unknown parent - childCoreBlk.Timestamp(), - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) childProBlk := postForkBlock{ - SignedBlock: childSlb, postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -179,23 +165,145 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { }, } - // child block referring unknown parent does not verify - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, database.ErrNotFound) + { + // child block referring unknown parent does not verify + childSlb, err := block.Build( + ids.Empty, // refer unknown parent + childCoreBlk.Timestamp(), + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, database.ErrNotFound) + } - // child block referring known parent does verify - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), // refer known parent - prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), - pChainHeight, - childCoreBlk.Bytes(), + { + // child block referring known parent does verify + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + parentBlk.Timestamp().Add(proposer.MaxVerifyDelay), + pChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) + require.NoError(childProBlk.Verify(context.Background())) + } +} + +func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { + require := require.New(t) + + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = time.Unix(0, 0) ) - require.NoError(err) - childProBlk.SignedBlock = childSlb + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + defer func() { + require.NoError(proVM.Shutdown(context.Background())) + }() + + pChainHeight := uint64(100) + valState.GetCurrentHeightF = func(context.Context) (uint64, error) { + return pChainHeight, nil + } + + parentCoreBlk := &snowman.TestBlock{ + TestDecidable: choices.TestDecidable{ + IDV: ids.Empty.Prefix(1111), + StatusV: choices.Processing, + }, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + TimestampV: coreGenBlk.Timestamp(), + } + coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { + return parentCoreBlk, nil + } + coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { + switch blkID { + case coreGenBlk.ID(): + return coreGenBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil + default: + return nil, database.ErrNotFound + } + } + coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { + switch { + case bytes.Equal(b, coreGenBlk.Bytes()): + return coreGenBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil + default: + return nil, errUnknownBlock + } + } + + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) + + childCoreBlk := &snowman.TestBlock{ + ParentV: parentCoreBlk.ID(), + BytesV: []byte{2}, + TimestampV: parentCoreBlk.Timestamp(), + } + childProBlk := postForkBlock{ + postForkCommonComponents: postForkCommonComponents{ + vm: proVM, + innerBlk: childCoreBlk, + status: choices.Processing, + }, + } + + { + // child block referring unknown parent does not verify + childSlb, err := block.Build( + ids.Empty, // refer unknown parent + parentBlk.Timestamp().Add(proposer.WindowDuration), + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, database.ErrNotFound) + } + + { + // child block referring known parent does verify + childSlb, err := block.Build( + parentBlk.ID(), + parentBlk.Timestamp().Add(proposer.WindowDuration), + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + + require.NoError(err) + childProBlk.SignedBlock = childSlb + + proVM.Set(childSlb.Timestamp()) + require.NoError(childProBlk.Verify(context.Background())) + } } func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { From 6f98bf4300f66ac19609c371d171bfc04123ad8c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 18:40:10 +0100 Subject: [PATCH 018/111] UTs cleanup --- vms/proposervm/post_fork_block_test.go | 416 +++++++++++++------------ 1 file changed, 218 insertions(+), 198 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 403918fda1f5..b345a5e9f139 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -157,7 +157,7 @@ func TestBlockVerify_PostForkBlock_PreDurango_ParentChecks(t *testing.T) { BytesV: []byte{2}, TimestampV: parentCoreBlk.Timestamp(), } - childProBlk := postForkBlock{ + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -177,9 +177,9 @@ func TestBlockVerify_PostForkBlock_PreDurango_ParentChecks(t *testing.T) { proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, database.ErrNotFound) } @@ -192,10 +192,10 @@ func TestBlockVerify_PostForkBlock_PreDurango_ParentChecks(t *testing.T) { childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } } @@ -260,7 +260,7 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { BytesV: []byte{2}, TimestampV: parentCoreBlk.Timestamp(), } - childProBlk := postForkBlock{ + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -280,9 +280,9 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, database.ErrNotFound) } @@ -299,10 +299,10 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb proVM.Set(childSlb.Timestamp()) - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } } @@ -323,8 +323,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { return pChainHeight, nil } - // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -334,14 +333,14 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -350,45 +349,30 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - prntTimestamp := prntProBlk.Timestamp() + parentTimestamp := parentBlk.Timestamp() childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: prntCoreBlk.ID(), + ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, } - - // child block timestamp cannot be lower than parent timestamp - childCoreBlk.TimestampV = prntTimestamp.Add(-1 * time.Second) - proVM.Clock.Set(childCoreBlk.TimestampV) - childSlb, err := block.Build( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk := postForkBlock{ - SignedBlock: childSlb, + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -396,90 +380,117 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeNotMonotonic) + { + // child block timestamp cannot be lower than parent timestamp + childTimestamp := parentTimestamp.Add(-1 * time.Second) + proVM.Clock.Set(childCoreBlk.TimestampV) + childSlb, err := block.Build( + parentBlk.ID(), + childTimestamp, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errTimeNotMonotonic) + } - // block cannot arrive before its creator window starts blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), pChainHeight, proVM.ctx.NodeID, proposer.MaxVerifyWindows) require.NoError(err) - beforeWinStart := prntTimestamp.Add(blkWinDelay).Add(-1 * time.Second) - proVM.Clock.Set(beforeWinStart) - childSlb, err = block.Build( - prntProBlk.ID(), - beforeWinStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errProposerWindowNotStarted) - - // block can arrive at its creator window starts - atWindowStart := prntTimestamp.Add(blkWinDelay) - proVM.Clock.Set(atWindowStart) - childSlb, err = block.Build( - prntProBlk.ID(), - atWindowStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb + { + // block cannot arrive before its creator window starts + beforeWinStart := parentTimestamp.Add(blkWinDelay).Add(-1 * time.Second) + proVM.Clock.Set(beforeWinStart) + childSlb, err := block.Build( + parentBlk.ID(), + beforeWinStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errProposerWindowNotStarted) + } - require.NoError(childProBlk.Verify(context.Background())) + { + // block can arrive at its creator window starts + atWindowStart := parentTimestamp.Add(blkWinDelay) + proVM.Clock.Set(atWindowStart) + childSlb, err := block.Build( + parentBlk.ID(), + atWindowStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb - // block can arrive after its creator window starts - afterWindowStart := prntTimestamp.Add(blkWinDelay).Add(5 * time.Second) - proVM.Clock.Set(afterWindowStart) - childSlb, err = block.Build( - prntProBlk.ID(), - afterWindowStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) + } - // block can arrive within submission window - atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) - proVM.Clock.Set(atSubWindowEnd) - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - atSubWindowEnd, - pChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) - - // block timestamp cannot be too much in the future - afterSubWinEnd := proVM.Time().Add(maxSkew).Add(time.Second) - childSlb, err = block.Build( - prntProBlk.ID(), - afterSubWinEnd, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // block can arrive after its creator window starts + afterWindowStart := parentTimestamp.Add(blkWinDelay).Add(5 * time.Second) + proVM.Clock.Set(afterWindowStart) + childSlb, err := block.Build( + parentBlk.ID(), + afterWindowStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block can arrive within submission window + atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) + proVM.Clock.Set(atSubWindowEnd) + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + atSubWindowEnd, + pChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block timestamp cannot be too much in the future + afterSubWinEnd := proVM.Time().Add(maxSkew).Add(time.Second) + childSlb, err := block.Build( + parentBlk.ID(), + afterSubWinEnd, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errTimeTooAdvanced) + } } func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { @@ -499,8 +510,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { return pChainHeight, nil } - // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -510,14 +520,14 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -526,44 +536,31 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - prntBlkPChainHeight := pChainHeight + parentBlkPChainHeight := pChainHeight childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: prntCoreBlk.ID(), + ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, - TimestampV: prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), + TimestampV: parentBlk.Timestamp().Add(proposer.MaxVerifyDelay), } - - // child P-Chain height must not precede parent P-Chain height - childSlb, err := block.Build( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight-1, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk := postForkBlock{ - SignedBlock: childSlb, + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -571,57 +568,80 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // child P-Chain height must not precede parent P-Chain height + childSlb, err := block.Build( + parentBlk.ID(), + childCoreBlk.Timestamp(), + parentBlkPChainHeight-1, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childBlk.SignedBlock = childSlb - // child P-Chain height can be equal to parent P-Chain height - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errTimeTooAdvanced) + } - proVM.Set(childCoreBlk.Timestamp()) - require.NoError(childProBlk.Verify(context.Background())) + { + // child P-Chain height can be equal to parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + childCoreBlk.Timestamp(), + parentBlkPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb - // child P-Chain height may follow parent P-Chain height - pChainHeight = prntBlkPChainHeight * 2 // move ahead pChainHeight - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight+1, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + proVM.Set(childCoreBlk.Timestamp()) + require.NoError(childBlk.Verify(context.Background())) + } + + { + // child P-Chain height may follow parent P-Chain height + pChainHeight = parentBlkPChainHeight * 2 // move ahead pChainHeight + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + childCoreBlk.Timestamp(), + parentBlkPChainHeight+1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) + } - // block P-Chain height can be equal to current P-Chain height currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + { + // block P-Chain height can be equal to current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + childCoreBlk.Timestamp(), + currPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) + } - // block P-Chain height cannot be at higher than current P-Chain height - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight*2, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errPChainHeightNotReached) + { + // block P-Chain height cannot be at higher than current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + childCoreBlk.Timestamp(), + currPChainHeight*2, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotReached) + } } func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) { @@ -746,7 +766,7 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk := postForkBlock{ + childBlk := postForkBlock{ SignedBlock: childSlb, postForkCommonComponents: postForkCommonComponents{ vm: proVM, @@ -755,7 +775,7 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) }, } - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errTimeTooAdvanced) // child P-Chain height can be equal to parent P-Chain height @@ -766,10 +786,10 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb proVM.Set(childCoreBlk.Timestamp()) - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) // child P-Chain height may follow parent P-Chain height pChainHeight = prntBlkPChainHeight * 2 // move ahead pChainHeight @@ -780,8 +800,8 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) // block P-Chain height can be equal to current P-Chain height currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) @@ -792,8 +812,8 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) // block P-Chain height cannot be at higher than current P-Chain height childSlb, err = block.BuildUnsigned( @@ -803,8 +823,8 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + childBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errPChainHeightNotReached) } From c2419b162257261356441eacc4a43ec6961b5456 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 19:16:29 +0100 Subject: [PATCH 019/111] some more UTs updated to durango --- vms/proposervm/post_fork_block_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index b345a5e9f139..5a9dd358f2ec 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -835,7 +835,7 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Show that other verify call would not call coreBlk.Verify() var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -902,7 +902,7 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { // setup var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -969,7 +969,7 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -1021,7 +1021,7 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -1058,7 +1058,7 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -1177,7 +1177,7 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 5) proVM.Set(coreGenBlk.Timestamp()) From 29eefbcc7d42df43634c13933dbf030560cb4adf Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 19:33:34 +0100 Subject: [PATCH 020/111] nit --- vms/proposervm/config.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 185ad7b86f30..96645c9489a8 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -11,14 +11,22 @@ import ( ) type Config struct { - ActivationTime time.Time + // Time at which proposerVM activates its congestion control mechanism + ActivationTime time.Time + + // Minimal P-chain height referenced upon block building MinimumPChainHeight uint64 - MinBlkDelay time.Duration + + // Configurable minimal delay among blocks issued consecutively + MinBlkDelay time.Duration + + // Maximal number of block indexed. + // Zero signals all blocks are indexed. NumHistoricalBlocks uint64 - // block signer + // Block signer StakingLeafSigner crypto.Signer - // block certificate + // Block certificate StakingCertLeaf *staking.Certificate } From 640984abeeb09f3e2714e340c037b55e0cdbd1b9 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 1 Dec 2023 19:48:17 +0100 Subject: [PATCH 021/111] nit --- chains/manager.go | 4 ++-- vms/proposervm/batched_vm_test.go | 2 +- vms/proposervm/post_fork_option_test.go | 2 +- vms/proposervm/state_syncable_vm_test.go | 2 +- vms/proposervm/vm.go | 2 +- vms/proposervm/vm_regression_test.go | 2 +- vms/proposervm/vm_test.go | 22 +++++++++++----------- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 8df8b8152a35..86da6811c41a 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -768,6 +768,7 @@ func (m *manager) createAvalancheChain( // Note: vmWrappingProposerVM is the VM that the Snowman engines should be // using. var vmWrappingProposerVM block.ChainVM = proposervm.New( + vmWrappedInsideProposerVM, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, @@ -776,7 +777,6 @@ func (m *manager) createAvalancheChain( StakingLeafSigner: m.stakingSigner, StakingCertLeaf: m.stakingCert, }, - vmWrappedInsideProposerVM, ) if m.MeterVMEnabled { @@ -1113,6 +1113,7 @@ func (m *manager) createSnowmanChain( } vm = proposervm.New( + vm, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, @@ -1121,7 +1122,6 @@ func (m *manager) createSnowmanChain( StakingLeafSigner: m.stakingSigner, StakingCertLeaf: m.stakingCert, }, - vm, ) if m.MeterVMEnabled { diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 25601dc63e09..c55c5ffc13b4 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -1019,6 +1019,7 @@ func initTestRemoteProposerVM( } proVM := New( + coreVM, Config{ ActivationTime: proBlkStartTime, MinimumPChainHeight: 0, @@ -1027,7 +1028,6 @@ func initTestRemoteProposerVM( StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) valState := &validators.TestState{ diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 7457186a8fe1..e142b391a348 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -659,6 +659,7 @@ func TestOptionTimestampValidity(t *testing.T) { // Restart the node. ctx := proVM.ctx proVM = New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -667,7 +668,6 @@ func TestOptionTimestampValidity(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) coreVM.InitializeF = func( diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index b91ab91457a7..b2295d50017b 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -69,6 +69,7 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { // create the VM vm := New( + innerVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -77,7 +78,6 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - innerVM, ) ctx := snow.DefaultContextTest() diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 01afda96abb1..2f40cb344348 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -127,8 +127,8 @@ type VM struct { // New performs best when [minBlkDelay] is whole seconds. This is because block // timestamps are only specific to the second. func New( - config Config, vm block.ChainVM, + config Config, ) *VM { blockBuilderVM, _ := vm.(block.BuildBlockWithContextChainVM) batchedVM, _ := vm.(block.BatchedChainVM) diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index 792090a1f5cf..fba3f5974332 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -45,6 +45,7 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test } proVM := New( + innerVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -53,7 +54,6 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - innerVM, ) defer func() { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 83b89a32236f..d3e2282f25c0 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -133,6 +133,7 @@ func initTestProposerVM( } proVM := New( + coreVM, Config{ ActivationTime: proBlkStartTime, MinimumPChainHeight: minPChainHeight, @@ -141,7 +142,6 @@ func initTestProposerVM( StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) valState := &validators.TestState{ @@ -881,6 +881,7 @@ func TestExpiredBuildBlock(t *testing.T) { } proVM := New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -889,7 +890,6 @@ func TestExpiredBuildBlock(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) valState := &validators.TestState{ @@ -1227,6 +1227,7 @@ func TestInnerVMRollback(t *testing.T) { db := memdb.New() proVM := New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -1235,7 +1236,6 @@ func TestInnerVMRollback(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) require.NoError(proVM.Initialize( @@ -1316,6 +1316,7 @@ func TestInnerVMRollback(t *testing.T) { } proVM = New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -1324,7 +1325,6 @@ func TestInnerVMRollback(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) require.NoError(proVM.Initialize( @@ -1810,6 +1810,7 @@ func TestRejectedHeightNotIndexed(t *testing.T) { } proVM := New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -1818,7 +1819,6 @@ func TestRejectedHeightNotIndexed(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) valState := &validators.TestState{ @@ -2019,6 +2019,7 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { } proVM := New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -2027,7 +2028,6 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) valState := &validators.TestState{ @@ -2184,6 +2184,7 @@ func TestVMInnerBlkCache(t *testing.T) { // Create a VM innerVM := mocks.NewMockChainVM(ctrl) vm := New( + innerVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -2192,7 +2193,6 @@ func TestVMInnerBlkCache(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - innerVM, ) innerVM.EXPECT().Initialize( @@ -2415,6 +2415,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { // Create a VM innerVM := mocks.NewMockChainVM(ctrl) vm := New( + innerVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -2423,7 +2424,6 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - innerVM, ) // make sure that DBs are compressed correctly @@ -2628,6 +2628,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { db := prefixdb.New([]byte{}, memdb.New()) proVM := New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -2636,7 +2637,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) require.NoError(proVM.Initialize( @@ -2728,6 +2728,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { numHistoricalBlocks := uint64(2) proVM = New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -2736,7 +2737,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) require.NoError(proVM.Initialize( @@ -2772,6 +2772,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { newNumHistoricalBlocks := numHistoricalBlocks + 2 proVM = New( + coreVM, Config{ ActivationTime: time.Time{}, MinimumPChainHeight: 0, @@ -2780,7 +2781,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { StakingLeafSigner: pTestSigner, StakingCertLeaf: pTestCert, }, - coreVM, ) require.NoError(proVM.Initialize( From c8e1b336dc17818b1a6d9fd2fb8fae6f7861da22 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 11:49:28 +0100 Subject: [PATCH 022/111] nits --- vms/proposervm/block.go | 15 +++++++-------- vms/proposervm/vm.go | 4 +--- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 62fa78bfbf95..74bcb7b7e54f 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -141,7 +141,7 @@ func (p *postForkCommonComponents) Verify( ) } - delay, minDelay, err := p.verifyBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) + delay, err := p.verifyBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) if err != nil { return err } @@ -155,7 +155,6 @@ func (p *postForkCommonComponents) Verify( p.vm.ctx.Log.Debug("verified post-fork block", zap.Stringer("blkID", child.ID()), zap.Time("parentTimestamp", parentTimestamp), - zap.Duration("minDelay", minDelay), zap.Time("blockTimestamp", childTimestamp), ) } @@ -194,7 +193,7 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - buildUnsignedBlock, err := p.shouldBuildBlock( + shouldBuildUnsignedBlock, err := p.shouldBuildBlock( ctx, parentID, parentTimestamp, @@ -219,7 +218,7 @@ func (p *postForkCommonComponents) buildChild( // Build the child var statelessChild block.SignedBlock - if buildUnsignedBlock { + if shouldBuildUnsignedBlock { statelessChild, err = block.BuildUnsigned( parentID, newTimestamp, @@ -310,7 +309,7 @@ func (p *postForkCommonComponents) verifyBlockDelay( parentTimestamp time.Time, parentPChainHeight uint64, blk *postForkBlock, -) (time.Duration, time.Duration, error) { +) (time.Duration, error) { var ( blkTimestamp = blk.Timestamp() childHeight = blk.Height() @@ -318,15 +317,15 @@ func (p *postForkCommonComponents) verifyBlockDelay( ) minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) if err != nil { - return 0, 0, err + return 0, err } delay := blkTimestamp.Sub(parentTimestamp) if delay < minDelay { - return 0, 0, errProposerWindowNotStarted + return 0, errProposerWindowNotStarted } - return delay, minDelay, nil + return delay, nil } func (p *postForkCommonComponents) shouldBuildBlock( diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 2f40cb344348..ae9afe6562cd 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -352,9 +352,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { // validators can specify. This delay may be an issue for high performance, // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. - if minDelay < vm.MinBlkDelay { - minDelay = vm.MinBlkDelay - } + minDelay = math.Max(minDelay, vm.MinBlkDelay) preferredTime := blk.Timestamp() nextStartTime := preferredTime.Add(minDelay) From d1c8bb4a13c85ace14e9acc1cd3360b36cef88b6 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 12:52:35 +0100 Subject: [PATCH 023/111] nit --- vms/proposervm/block.go | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 74bcb7b7e54f..ccb75ba2001b 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -337,6 +337,7 @@ func (p *postForkCommonComponents) shouldBuildBlock( ) (bool, error) { delay := newTimestamp.Sub(parentTimestamp) if delay >= proposer.MaxBuildDelay { + // time for any node to build an unsigned block return true, nil } @@ -352,22 +353,25 @@ func (p *postForkCommonComponents) shouldBuildBlock( return false, err } - if delay < minDelay { - // It's not our turn to propose a block yet. This is likely caused - // by having previously notified the consensus engine to attempt to - // build a block on top of a block that is no longer the preferred - // block. - p.vm.ctx.Log.Debug("build block dropped", - zap.Time("parentTimestamp", parentTimestamp), - zap.Duration("minDelay", minDelay), - zap.Time("blockTimestamp", newTimestamp), - ) - - // In case the inner VM only issued one pendingTxs message, we - // should attempt to re-handle that once it is our turn to build the - // block. - p.vm.notifyInnerBlockReady() - return false, errProposerWindowNotStarted + if delay >= minDelay { + // it's time for this node to propose a block. It'll be signed or unsigned + // depending on the delay + return delay >= proposer.MaxVerifyDelay, nil } - return delay >= proposer.MaxVerifyDelay, nil + + // It's not our turn to propose a block yet. This is likely caused + // by having previously notified the consensus engine to attempt to + // build a block on top of a block that is no longer the preferred + // block. + p.vm.ctx.Log.Debug("build block dropped", + zap.Time("parentTimestamp", parentTimestamp), + zap.Duration("minDelay", minDelay), + zap.Time("blockTimestamp", newTimestamp), + ) + + // In case the inner VM only issued one pendingTxs message, we + // should attempt to re-handle that once it is our turn to build the + // block. + p.vm.notifyInnerBlockReady() + return false, errProposerWindowNotStarted } From e8d18d88462f2a10c817878ab32f19ab6503a16a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 21:59:24 +0100 Subject: [PATCH 024/111] fixes + more UTs --- vms/proposervm/batched_vm_test.go | 37 ++++++++++++++++++++++++++----- vms/proposervm/block.go | 20 +++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index d9d536ee47bf..73267e0df265 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -702,14 +702,16 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() - // Build some post-Fork blocks.... + // Build some post-Fork blocks + + // build block 1 coreBlk1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), @@ -726,10 +728,10 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { builtBlk1, err := proRemoteVM.BuildBlock(context.Background()) require.NoError(err) - // prepare build of next block + // build block 2 require.NoError(builtBlk1.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk1.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk1, 0)) coreBlk2 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -739,11 +741,12 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { BytesV: []byte{2}, ParentV: coreBlk1.ID(), HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), + TimestampV: coreBlk1.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil } + builtBlk2, err := proRemoteVM.BuildBlock(context.Background()) require.NoError(err) @@ -820,7 +823,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - durangoTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) // enable ProBlks in next future @@ -1121,3 +1124,25 @@ func initTestRemoteProposerVM( require.NoError(proVM.SetPreference(context.Background(), coreGenBlk.IDV)) return coreVM, proVM, coreGenBlk } + +func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) error { + ctx := context.Background() + vm.Clock.Set(vm.Clock.Time().Truncate(time.Second)) + for { // find the right time to issue next block + proposerID, err := vm.ExpectedProposer( + ctx, + chainTip.Height()+1, + pchainHeight, + vm.Clock.Time(), + chainTip.Timestamp(), + ) + if err != nil { + return err + } + if proposerID == vm.ctx.NodeID { + break + } + vm.Clock.Set(vm.Time().Add(proposer.WindowDuration)) + } + return nil +} diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 2caa3735de63..90e81d112c15 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -203,9 +203,9 @@ func (p *postForkCommonComponents) buildChild( return nil, err } - shouldBuildUnsignedBlock := true + shouldBuildUnsignedBlock := false if p.vm.IsDurangoActivated(parentTimestamp) { - parentHeight := p.innerBlk.Height() - 1 + parentHeight := p.innerBlk.Height() err = p.shouldPostDurangoBuildBlock( ctx, parentTimestamp, @@ -362,7 +362,13 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( proposerID = blk.Proposer() ) - expectedProposerID, err := p.vm.Windower.ExpectedProposer(ctx, blkHeight, parentPChainHeight, blkTimestamp, parentTimestamp) + expectedProposerID, err := p.vm.Windower.ExpectedProposer( + ctx, + blkHeight, + parentPChainHeight, + blkTimestamp, + parentTimestamp, + ) if err != nil { return err } @@ -380,7 +386,13 @@ func (p *postForkCommonComponents) shouldPostDurangoBuildBlock( parentPChainHeight uint64, newTimestamp time.Time, ) error { - expectedProposerID, err := p.vm.Windower.ExpectedProposer(ctx, parentHeight+1, parentPChainHeight, newTimestamp, parentTimestamp) + expectedProposerID, err := p.vm.Windower.ExpectedProposer( + ctx, + parentHeight+1, + parentPChainHeight, + newTimestamp, + parentTimestamp, + ) if err != nil { return err } From 50a40e32164b675bd09e2c1784f975b4ff58269e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 22:05:03 +0100 Subject: [PATCH 025/111] wip: some more UTs update to post durango fork --- vms/proposervm/batched_vm_test.go | 26 ++++++++++++++------------ vms/proposervm/block_test.go | 27 ++++++++++++++++++--------- vms/proposervm/vm_test.go | 28 ++++++++++++---------------- 3 files changed, 44 insertions(+), 37 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 73267e0df265..ce5360d06750 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -210,7 +210,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { @@ -218,6 +218,8 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { }() // Build some post-Fork blocks.... + + // build blk1 coreBlk1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), @@ -234,10 +236,10 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { builtBlk1, err := proRemoteVM.BuildBlock(context.Background()) require.NoError(err) - // prepare build of next block + // build blk2 require.NoError(builtBlk1.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk1.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk1, 0)) coreBlk2 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -247,7 +249,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { BytesV: []byte{2}, ParentV: coreBlk1.ID(), HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), + TimestampV: coreBlk1.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -255,10 +257,10 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { builtBlk2, err := proRemoteVM.BuildBlock(context.Background()) require.NoError(err) - // prepare build of next block + // buid blk3 require.NoError(builtBlk2.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk2.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk1, 0)) coreBlk3 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -371,7 +373,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - durangoTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) // enable ProBlks in next future @@ -448,7 +450,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { BytesV: []byte{3}, ParentV: coreBlk2.ID(), HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -460,7 +462,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { // prepare build of next block require.NoError(builtBlk3.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk3.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk3, builtBlk3.(*postForkBlock).PChainHeight())) coreBlk4 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -753,7 +755,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { // prepare build of next block require.NoError(builtBlk2.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk2.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk2, builtBlk2.(*postForkBlock).PChainHeight())) coreBlk3 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -900,7 +902,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { BytesV: []byte{3}, ParentV: coreBlk2.ID(), HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -912,7 +914,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { // prepare build of next block require.NoError(builtBlk3.Verify(context.Background())) require.NoError(proRemoteVM.SetPreference(context.Background(), builtBlk3.ID())) - proRemoteVM.Set(proRemoteVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proRemoteVM, builtBlk3, builtBlk3.(*postForkBlock).PChainHeight())) coreBlk4 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 58dd5c3c181f..7049e617d9ef 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -37,40 +37,49 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - pChainHeight := uint64(1337) - parentID := ids.GenerateTestID() - parentTimestamp := time.Now() - parentHeight := uint64(1234) - blkID := ids.GenerateTestID() + var ( + nodeID = ids.GenerateTestNodeID() + pChainHeight = uint64(1337) + parentID = ids.GenerateTestID() + parentTimestamp = time.Now().Truncate(time.Second) + parentHeight = uint64(1234) + blkID = ids.GenerateTestID() + ) + innerBlk := snowman.NewMockBlock(ctrl) innerBlk.EXPECT().ID().Return(blkID).AnyTimes() innerBlk.EXPECT().Height().Return(parentHeight + 1).AnyTimes() + builtBlk := snowman.NewMockBlock(ctrl) builtBlk.EXPECT().Bytes().Return([]byte{1, 2, 3}).AnyTimes() builtBlk.EXPECT().ID().Return(ids.GenerateTestID()).AnyTimes() builtBlk.EXPECT().Height().Return(pChainHeight).AnyTimes() + innerVM := mocks.NewMockChainVM(ctrl) innerBlockBuilderVM := mocks.NewMockBuildBlockWithContextChainVM(ctrl) innerBlockBuilderVM.EXPECT().BuildBlockWithContext(gomock.Any(), &block.Context{ PChainHeight: pChainHeight - 1, }).Return(builtBlk, nil).AnyTimes() + vdrState := validators.NewMockState(ctrl) vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() + windower := proposer.NewMockWindower(ctrl) - windower.EXPECT().Delay(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(time.Duration(0), nil).AnyTimes() + windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nodeID, nil).AnyTimes() pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) vm := &VM{ Config: Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, + DurangoTime: time.Unix(0, 0), StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, ChainVM: innerVM, blockBuilderVM: innerBlockBuilderVM, ctx: &snow.Context{ + NodeID: nodeID, ValidatorState: vdrState, Log: logging.NoLog{}, }, @@ -93,7 +102,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.Equal(builtBlk, gotChild.(*postForkBlock).innerBlk) } -func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { +func TestPreDurangoValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() @@ -230,7 +239,7 @@ func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { } } -func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { +func TestPreDurangoNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 53f49461276f..3718f3cee003 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -238,10 +238,9 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -272,10 +271,9 @@ func TestBuildBlockIsIdempotent(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -311,10 +309,9 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -761,10 +758,9 @@ func TestPreFork_BuildBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{3}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil From 07e53abe709a6e7ef5c452c6e6f15d20130c6688 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 22:51:32 +0100 Subject: [PATCH 026/111] wip: some more UTs update to post durango fork --- vms/proposervm/batched_vm_test.go | 23 ----- vms/proposervm/vm_byzantine_test.go | 125 ++++++++++++---------------- vms/proposervm/vm_test.go | 65 +++++++++------ 3 files changed, 93 insertions(+), 120 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index ce5360d06750..042ce1822970 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/timer/mockable" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) func TestCoreVMNotRemote(t *testing.T) { @@ -1126,25 +1125,3 @@ func initTestRemoteProposerVM( require.NoError(proVM.SetPreference(context.Background(), coreGenBlk.IDV)) return coreVM, proVM, coreGenBlk } - -func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) error { - ctx := context.Background() - vm.Clock.Set(vm.Clock.Time().Truncate(time.Second)) - for { // find the right time to issue next block - proposerID, err := vm.ExpectedProposer( - ctx, - chainTip.Height()+1, - pchainHeight, - vm.Clock.Time(), - chainTip.Timestamp(), - ) - if err != nil { - return err - } - if proposerID == vm.ctx.NodeID { - break - } - vm.Clock.Set(vm.Time().Add(proposer.WindowDuration)) - } - return nil -} diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index ab19274073b8..10b37b48d386 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -17,9 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) // Ensure that a byzantine node issuing an invalid PreForkBlock (Y) when the @@ -36,7 +34,7 @@ func TestInvalidByzantineProposerParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -48,10 +46,9 @@ func TestInvalidByzantineProposerParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -71,10 +68,9 @@ func TestInvalidByzantineProposerParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: yBlockBytes, - ParentV: xBlock.ID(), - HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: yBlockBytes, + ParentV: xBlock.ID(), + HeightV: xBlock.Height() + 1, } coreVM.ParseBlockF = func(_ context.Context, blockBytes []byte) (snowman.Block, error) { @@ -109,7 +105,7 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -124,9 +120,8 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { IDV: xBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -134,18 +129,16 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: xBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: xBlockID, }, }, } @@ -221,7 +214,7 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -233,10 +226,9 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -248,10 +240,9 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: yBlockBytes, - ParentV: xBlock.ID(), - HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: yBlockBytes, + ParentV: xBlock.ID(), + HeightV: xBlock.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { @@ -313,7 +304,7 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -327,9 +318,8 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -337,18 +327,16 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), // valid block should reference xBlock - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), // valid block should reference xBlock }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreGenBlk.ID(), // valid block should reference xBlock - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: coreGenBlk.ID(), // valid block should reference xBlock }, }, } @@ -416,7 +404,7 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -432,9 +420,8 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: xBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -442,18 +429,16 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: xBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: xBlockID, }, }, } @@ -468,10 +453,9 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } ySlb, err := block.BuildUnsigned( @@ -548,9 +532,8 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: zBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -558,18 +541,16 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: zBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: zBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: zBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: zBlockID, }, }, } @@ -607,7 +588,7 @@ func TestGetBlock_MutatedSignature(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -632,10 +613,9 @@ func TestGetBlock_MutatedSignature(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreBlk1 := &snowman.TestBlock{ @@ -643,10 +623,9 @@ func TestGetBlock_MutatedSignature(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk0.ID(), - HeightV: coreBlk0.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk0.ID(), + HeightV: coreBlk0.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { @@ -686,7 +665,7 @@ func TestGetBlock_MutatedSignature(t *testing.T) { require.NoError(proVM.SetPreference(context.Background(), builtBlk0.ID())) - // The second propsal block will need to be signed because the timestamp + // The second proposal block will need to be signed because the timestamp // hasn't moved forward // Craft what would be the next block, but with an invalid signature: diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 3718f3cee003..3b35563c40ea 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -215,6 +215,28 @@ func initTestProposerVM( return coreVM, valState, proVM, coreGenBlk, db } +func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) error { + ctx := context.Background() + vm.Clock.Set(vm.Clock.Time().Truncate(time.Second)) + for { // find the right time to issue next block + proposerID, err := vm.ExpectedProposer( + ctx, + chainTip.Height()+1, + pchainHeight, + vm.Clock.Time(), + chainTip.Timestamp(), + ) + if err != nil { + return err + } + if proposerID == vm.ctx.NodeID { + break + } + vm.Clock.Set(vm.Time().Add(proposer.WindowDuration)) + } + return nil +} + // VM.BuildBlock tests section func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { @@ -334,7 +356,7 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -347,10 +369,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -363,10 +384,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -420,7 +440,7 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { return coreBlk3, nil } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proVM, proBlk2, proBlk2.(*postForkBlock).PChainHeight())) builtBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -433,7 +453,7 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -445,10 +465,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -461,10 +480,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -510,16 +528,15 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: wronglyPreferredcoreBlk.ID(), - HeightV: wronglyPreferredcoreBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: wronglyPreferredcoreBlk.ID(), + HeightV: wronglyPreferredcoreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) + require.NoError(waitForProposerWindow(proVM, proBlk2, proBlk2.(*postForkBlock).PChainHeight())) blk, err := proVM.BuildBlock(context.Background()) require.NoError(err) From 46235b9548a3d64b630fae9776e7642aec2f9b86 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 23:22:21 +0100 Subject: [PATCH 027/111] wip: some more UTs updated to post durango fork --- vms/proposervm/post_fork_option_test.go | 130 ++++++++++++------------ 1 file changed, 63 insertions(+), 67 deletions(-) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index caefae4e7499..1c93712ff6b2 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -17,9 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) var _ snowman.OracleBlock = (*TestOptionsBlock)(nil) @@ -40,7 +38,7 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -55,9 +53,9 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -66,18 +64,18 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -138,14 +136,14 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(4444), StatusV: choices.Processing, }, - ParentV: oracleCoreBlk.opts[0].ID(), - BytesV: []byte{4}, - TimestampV: oracleCoreBlk.opts[0].Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: oracleCoreBlk.opts[0].ID(), + BytesV: []byte{4}, + HeightV: oracleCoreBlk.opts[0].Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return childCoreBlk, nil } - proVM.Set(childCoreBlk.Timestamp()) + require.NoError(waitForProposerWindow(proVM, opts[0], postForkOracleBlk.PChainHeight())) proChild, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -160,7 +158,7 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -175,9 +173,9 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } coreOpt0 := &snowman.TestBlock{ @@ -185,18 +183,18 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } coreOpt1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } oracleCoreBlk.opts = [2]snowman.Block{ coreOpt0, @@ -266,7 +264,7 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -281,9 +279,9 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -292,18 +290,18 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -380,7 +378,7 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -395,9 +393,9 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -406,18 +404,18 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -486,7 +484,7 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -500,9 +498,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, optsErr: snowman.ErrNotOracle, } @@ -512,10 +510,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk.ID(), - HeightV: coreBlk.Height() + 1, - TimestampV: coreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk.ID(), + HeightV: coreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { @@ -576,7 +573,7 @@ func TestOptionTimestampValidity(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoForkTime, 0) @@ -587,10 +584,9 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: coreOracleBlkID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -598,18 +594,18 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{2}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{3}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 1, }, }, } @@ -686,8 +682,8 @@ func TestOptionTimestampValidity(t *testing.T) { proVM = New( coreVM, Config{ - ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, From 6d78042d6867da03811d95d0dcfdd8de2ae66eb3 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 3 Dec 2023 23:54:07 +0100 Subject: [PATCH 028/111] wip: some more UTs updated to post durango fork --- vms/proposervm/post_fork_block_test.go | 81 ++++++++++++++++---------- 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 5a9dd358f2ec..df623f6247c1 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -101,7 +101,7 @@ func TestBlockVerify_PostForkBlock_PreDurango_ParentChecks(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime // pre Durango ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -204,7 +204,7 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + durangoForkTime = time.Unix(0, 0) // post Durango ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -221,9 +221,9 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return parentCoreBlk, nil @@ -256,9 +256,9 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) childCoreBlk := &snowman.TestBlock{ - ParentV: parentCoreBlk.ID(), - BytesV: []byte{2}, - TimestampV: parentCoreBlk.Timestamp(), + ParentV: parentCoreBlk.ID(), + BytesV: []byte{2}, + HeightV: parentCoreBlk.Height() + 1, } childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ @@ -268,11 +268,13 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { }, } + require.NoError(waitForProposerWindow(proVM, parentBlk, parentBlk.(*postForkBlock).PChainHeight())) + { // child block referring unknown parent does not verify childSlb, err := block.Build( ids.Empty, // refer unknown parent - parentBlk.Timestamp().Add(proposer.WindowDuration), + proVM.Time(), pChainHeight, proVM.StakingCertLeaf, childCoreBlk.Bytes(), @@ -290,7 +292,7 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { // child block referring known parent does verify childSlb, err := block.Build( parentBlk.ID(), - parentBlk.Timestamp().Add(proposer.WindowDuration), + proVM.Time(), pChainHeight, proVM.StakingCertLeaf, childCoreBlk.Bytes(), @@ -498,7 +500,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + durangoForkTime = time.Unix(0, 0) ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { @@ -509,15 +511,18 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { valState.GetCurrentHeightF = func(context.Context) (uint64, error) { return pChainHeight, nil } + valState.GetMinimumHeightF = func(context.Context) (uint64, error) { + return pChainHeight, nil + } parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return parentCoreBlk, nil @@ -556,9 +561,9 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: parentCoreBlk.ID(), - BytesV: []byte{2}, - TimestampV: parentBlk.Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: parentCoreBlk.ID(), + BytesV: []byte{2}, + HeightV: parentCoreBlk.Height() + 1, } childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ @@ -568,11 +573,13 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { }, } + require.NoError(waitForProposerWindow(proVM, parentBlk, parentBlkPChainHeight)) + { // child P-Chain height must not precede parent P-Chain height childSlb, err := block.Build( parentBlk.ID(), - childCoreBlk.Timestamp(), + proVM.Time(), parentBlkPChainHeight-1, proVM.StakingCertLeaf, childCoreBlk.Bytes(), @@ -583,62 +590,76 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childBlk.SignedBlock = childSlb err = childBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + require.ErrorIs(err, errPChainHeightNotMonotonic) } { // child P-Chain height can be equal to parent P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - childCoreBlk.Timestamp(), + proVM.Time(), parentBlkPChainHeight, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb - proVM.Set(childCoreBlk.Timestamp()) require.NoError(childBlk.Verify(context.Background())) } { // child P-Chain height may follow parent P-Chain height - pChainHeight = parentBlkPChainHeight * 2 // move ahead pChainHeight - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - childCoreBlk.Timestamp(), - parentBlkPChainHeight+1, + proVM.Time(), + parentBlkPChainHeight, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) } currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) { // block P-Chain height can be equal to current P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - childCoreBlk.Timestamp(), + proVM.Time(), currPChainHeight, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) + require.NoError(err) childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) } { // block P-Chain height cannot be at higher than current P-Chain height - childSlb, err := block.BuildUnsigned( + childSlb, err := block.Build( parentBlk.ID(), - childCoreBlk.Timestamp(), + proVM.Time(), currPChainHeight*2, + proVM.StakingCertLeaf, childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, ) require.NoError(err) childBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errPChainHeightNotReached) } From 37fab9d69a19d1066b4c5b76856cb6e3a3ed5599 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 08:26:20 +0100 Subject: [PATCH 029/111] nit --- chains/manager.go | 1 + 1 file changed, 1 insertion(+) diff --git a/chains/manager.go b/chains/manager.go index a3007d4dcdd7..43160e136f7c 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -1117,6 +1117,7 @@ func (m *manager) createSnowmanChain( vm, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, + DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, From a12ae77b11cd4b22b0e9449647343ac200c9ce26 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 08:53:03 +0100 Subject: [PATCH 030/111] proposerVM UTs cleanup --- chains/manager.go | 2 + vms/proposervm/batched_vm_test.go | 211 ++++++++++++----------- vms/proposervm/block_test.go | 30 +++- vms/proposervm/config.go | 7 + vms/proposervm/post_fork_block_test.go | 67 +++++-- vms/proposervm/post_fork_option_test.go | 151 +++++++++------- vms/proposervm/pre_fork_block_test.go | 60 +++++-- vms/proposervm/proposer/windower_test.go | 48 ++++-- vms/proposervm/state_syncable_vm_test.go | 10 +- vms/proposervm/vm_byzantine_test.go | 151 ++++++++-------- vms/proposervm/vm_regression_test.go | 3 +- vms/proposervm/vm_test.go | 209 +++++++++++++++------- 12 files changed, 596 insertions(+), 353 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 86da6811c41a..43160e136f7c 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -771,6 +771,7 @@ func (m *manager) createAvalancheChain( vmWrappedInsideProposerVM, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, + DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, @@ -1116,6 +1117,7 @@ func (m *manager) createSnowmanChain( vm, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, + DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index c55c5ffc13b4..92d0b8b334b3 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -29,7 +29,11 @@ import ( func TestCoreVMNotRemote(t *testing.T) { // if coreVM is not remote VM, a specific error is returned require := require.New(t) - _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -54,7 +58,11 @@ func TestCoreVMNotRemote(t *testing.T) { func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -65,10 +73,9 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -92,10 +99,9 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -119,10 +125,9 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -200,7 +205,11 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -211,10 +220,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -232,10 +240,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -253,10 +260,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -352,13 +358,18 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { require := require.New(t) - currentTime := time.Now().Truncate(time.Second) - preForkTime := currentTime.Add(5 * time.Minute) - forkTime := currentTime.Add(10 * time.Minute) - postForkTime := currentTime.Add(15 * time.Minute) + + var ( + currentTime = time.Now().Truncate(time.Second) + preForkTime = currentTime.Add(5 * time.Minute) + forkTime = currentTime.Add(10 * time.Minute) + postForkTime = currentTime.Add(15 * time.Minute) + + durangoTime = time.Unix(0, 0) + ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -370,10 +381,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: preForkTime, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -398,10 +408,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -428,10 +437,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -450,10 +458,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -558,7 +565,11 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -569,10 +580,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -596,10 +606,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -623,10 +632,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -679,7 +687,11 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) + ) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -690,10 +702,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -711,10 +722,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -732,10 +742,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -788,13 +797,18 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { require := require.New(t) - currentTime := time.Now().Truncate(time.Second) - preForkTime := currentTime.Add(5 * time.Minute) - forkTime := currentTime.Add(10 * time.Minute) - postForkTime := currentTime.Add(15 * time.Minute) + + var ( + currentTime = time.Now().Truncate(time.Second) + preForkTime = currentTime.Add(5 * time.Minute) + forkTime = currentTime.Add(10 * time.Minute) + postForkTime = currentTime.Add(15 * time.Minute) + + durangoTime = time.Unix(0, 0) + ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -806,10 +820,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: preForkTime, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -834,10 +847,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -864,10 +876,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime.Add(proposer.MaxVerifyDelay), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -886,10 +897,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -956,7 +966,8 @@ type TestRemoteProposerVM struct { func initTestRemoteProposerVM( t *testing.T, - proBlkStartTime time.Time, + activationTime, + durangoTime time.Time, ) ( TestRemoteProposerVM, *VM, @@ -969,9 +980,8 @@ func initTestRemoteProposerVM( IDV: ids.GenerateTestID(), StatusV: choices.Accepted, }, - HeightV: 0, - TimestampV: genesisTimestamp, - BytesV: []byte{0}, + HeightV: 0, + BytesV: []byte{0}, } initialState := []byte("genesis state") @@ -1021,7 +1031,8 @@ func initTestRemoteProposerVM( proVM := New( coreVM, Config{ - ActivationTime: proBlkStartTime, + ActivationTime: activationTime, + DurangoTime: durangoTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 5cca837a7a84..9ce9d051ce02 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -25,6 +25,7 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/logging" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -36,24 +37,31 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require := require.New(t) ctrl := gomock.NewController(t) - pChainHeight := uint64(1337) - parentID := ids.GenerateTestID() - parentTimestamp := time.Now() - blkID := ids.GenerateTestID() + var ( + pChainHeight = uint64(1337) + parentID = ids.GenerateTestID() + parentTimestamp = time.Now().Truncate(time.Second) + blkID = ids.GenerateTestID() + ) + innerBlk := snowman.NewMockBlock(ctrl) innerBlk.EXPECT().ID().Return(blkID).AnyTimes() innerBlk.EXPECT().Height().Return(pChainHeight - 1).AnyTimes() + builtBlk := snowman.NewMockBlock(ctrl) builtBlk.EXPECT().Bytes().Return([]byte{1, 2, 3}).AnyTimes() builtBlk.EXPECT().ID().Return(ids.GenerateTestID()).AnyTimes() builtBlk.EXPECT().Height().Return(pChainHeight).AnyTimes() + innerVM := mocks.NewMockChainVM(ctrl) innerBlockBuilderVM := mocks.NewMockBuildBlockWithContextChainVM(ctrl) innerBlockBuilderVM.EXPECT().BuildBlockWithContext(gomock.Any(), &block.Context{ PChainHeight: pChainHeight - 1, }).Return(builtBlk, nil).AnyTimes() + vdrState := validators.NewMockState(ctrl) vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() + windower := proposer.NewMockWindower(ctrl) windower.EXPECT().Delay(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(time.Duration(0), nil).AnyTimes() @@ -61,6 +69,8 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { require.NoError(err) vm := &VM{ Config: Config{ + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, @@ -93,7 +103,11 @@ func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() @@ -226,7 +240,11 @@ func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 96645c9489a8..6e4ed9576925 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -14,6 +14,9 @@ type Config struct { // Time at which proposerVM activates its congestion control mechanism ActivationTime time.Time + // Durango fork activation time + DurangoTime time.Time + // Minimal P-chain height referenced upon block building MinimumPChainHeight uint64 @@ -30,3 +33,7 @@ type Config struct { // Block certificate StakingCertLeaf *staking.Certificate } + +func (c *Config) IsDurangoActivated(timestamp time.Time) bool { + return !timestamp.Before(c.DurangoTime) +} diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 25dfd4f63e8f..a2c5307787d8 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -38,7 +39,11 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { require.Equal(snowman.ErrNotOracle, err) // setup - _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -94,7 +99,11 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -192,7 +201,11 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -364,7 +377,11 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -502,7 +519,11 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -684,7 +705,11 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify a block once (in this test by building it). // Show that other verify call would not call coreBlk.Verify() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -747,7 +772,11 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -810,7 +839,11 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -858,7 +891,11 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -891,7 +928,11 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1006,7 +1047,11 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 5) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 5) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index e142b391a348..4c94c4103629 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -17,8 +17,8 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) var _ snowman.OracleBlock = (*TestOptionsBlock)(nil) @@ -37,7 +37,11 @@ func (tob TestOptionsBlock) Options(context.Context) ([2]snowman.Block, error) { func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -50,9 +54,9 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -61,18 +65,18 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -133,9 +137,9 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(4444), StatusV: choices.Processing, }, - ParentV: oracleCoreBlk.opts[0].ID(), - BytesV: []byte{4}, - TimestampV: oracleCoreBlk.opts[0].Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: oracleCoreBlk.opts[0].ID(), + BytesV: []byte{4}, + HeightV: oracleCoreBlk.opts[0].Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return childCoreBlk, nil @@ -153,7 +157,11 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -166,9 +174,9 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } coreOpt0 := &snowman.TestBlock{ @@ -176,18 +184,18 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } coreOpt1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } oracleCoreBlk.opts = [2]snowman.Block{ coreOpt0, @@ -255,7 +263,11 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -268,9 +280,9 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -279,18 +291,18 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -365,7 +377,11 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -378,9 +394,9 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -389,18 +405,18 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -467,7 +483,11 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -479,9 +499,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, optsErr: snowman.ErrNotOracle, } @@ -491,10 +511,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk.ID(), - HeightV: coreBlk.Height() + 1, - TimestampV: coreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk.ID(), + HeightV: coreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { @@ -553,7 +572,11 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { func TestOptionTimestampValidity(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoForkTime, 0) coreOracleBlkID := ids.GenerateTestID() coreOracleBlk := &TestOptionsBlock{ @@ -562,10 +585,9 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: coreOracleBlkID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -573,18 +595,18 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{2}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), + BytesV: []byte{3}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 1, }, }, } @@ -661,7 +683,8 @@ func TestOptionTimestampValidity(t *testing.T) { proVM = New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 4308f9ba05f1..82c179661b88 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -51,7 +51,11 @@ func TestOracle_PreForkBlkImplementsInterface(t *testing.T) { func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -139,8 +143,11 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -233,8 +240,11 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -306,8 +316,11 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -437,8 +450,11 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(-1 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(-1 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(activationTime) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -479,7 +495,11 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -537,7 +557,11 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -568,8 +592,11 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -659,8 +686,11 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { require := require.New(t) - activationTime := genesisTimestamp.Add(10 * time.Second) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) + var ( + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 2a141a361ea2..51e8beac67c9 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -18,9 +18,12 @@ import ( func TestWindowerNoValidators(t *testing.T) { require := require.New(t) - subnetID := ids.GenerateTestID() - chainID := ids.GenerateTestID() - nodeID := ids.GenerateTestNodeID() + var ( + subnetID = ids.GenerateTestID() + chainID = ids.GenerateTestID() + nodeID = ids.GenerateTestNodeID() + ) + vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { @@ -30,7 +33,11 @@ func TestWindowerNoValidators(t *testing.T) { w := New(vdrState, subnetID, chainID) - delay, err := w.Delay(context.Background(), 1, 0, nodeID, MaxVerifyWindows) + var ( + chainHeight = uint64(1) + pChainHeight = uint64(0) + ) + delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) require.Zero(delay) } @@ -38,10 +45,13 @@ func TestWindowerNoValidators(t *testing.T) { func TestWindowerRepeatedValidator(t *testing.T) { require := require.New(t) - subnetID := ids.GenerateTestID() - chainID := ids.GenerateTestID() - validatorID := ids.GenerateTestNodeID() - nonValidatorID := ids.GenerateTestNodeID() + var ( + subnetID = ids.GenerateTestID() + chainID = ids.GenerateTestID() + validatorID = ids.GenerateTestNodeID() + nonValidatorID = ids.GenerateTestNodeID() + ) + vdrState := &validators.TestState{ T: t, GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { @@ -65,11 +75,14 @@ func TestWindowerRepeatedValidator(t *testing.T) { require.Equal(MaxVerifyDelay, nonValidatorDelay) } -func TestWindowerChangeByHeight(t *testing.T) { +func TestDelayChangeByHeight(t *testing.T) { require := require.New(t) - subnetID := ids.ID{0, 1} - chainID := ids.ID{0, 2} + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + ) + validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) @@ -121,16 +134,21 @@ func TestWindowerChangeByHeight(t *testing.T) { } } -func TestWindowerChangeByChain(t *testing.T) { +func TestDelayChangeByChain(t *testing.T) { require := require.New(t) subnetID := ids.ID{0, 1} - rand.Seed(0) + source := rand.NewSource(int64(0)) + rng := rand.New(source) // #nosec G404 + chainID0 := ids.ID{} - _, _ = rand.Read(chainID0[:]) // #nosec G404 + _, err := rng.Read(chainID0[:]) + require.NoError(err) + chainID1 := ids.ID{} - _, _ = rand.Read(chainID1[:]) // #nosec G404 + _, err = rng.Read(chainID1[:]) + require.NoError(err) validatorIDs := make([]ids.NodeID, MaxVerifyWindows) for i := range validatorIDs { diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index b2295d50017b..ea147eeeac3e 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/summary" statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" @@ -71,7 +72,8 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { vm := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -601,7 +603,11 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { require := require.New(t) // Note: by default proVM is built such that heightIndex will be considered complete - coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index dcfebf847cf3..251207303ca3 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -17,8 +17,8 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/validators" + "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) // Ensure that a byzantine node issuing an invalid PreForkBlock (Y) when the @@ -33,8 +33,11 @@ import ( func TestInvalidByzantineProposerParent(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) // enable ProBlks - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -44,10 +47,9 @@ func TestInvalidByzantineProposerParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -67,10 +69,9 @@ func TestInvalidByzantineProposerParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: yBlockBytes, - ParentV: xBlock.ID(), - HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: yBlockBytes, + ParentV: xBlock.ID(), + HeightV: xBlock.Height() + 1, } coreVM.ParseBlockF = func(_ context.Context, blockBytes []byte) (snowman.Block, error) { @@ -103,7 +104,11 @@ func TestInvalidByzantineProposerParent(t *testing.T) { func TestInvalidByzantineProposerOracleParent(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -116,9 +121,8 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { IDV: xBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -126,18 +130,16 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: xBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: xBlockID, }, }, } @@ -211,8 +213,11 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { func TestInvalidByzantineProposerPreForkParent(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) // enable ProBlks - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -222,10 +227,9 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return xBlock, nil @@ -237,10 +241,9 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: yBlockBytes, - ParentV: xBlock.ID(), - HeightV: xBlock.Height() + 1, - TimestampV: xBlock.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: yBlockBytes, + ParentV: xBlock.ID(), + HeightV: xBlock.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { @@ -300,7 +303,11 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -312,9 +319,8 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -322,18 +328,16 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), // valid block should reference xBlock - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), // valid block should reference xBlock }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreGenBlk.ID(), // valid block should reference xBlock - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: coreGenBlk.ID(), // valid block should reference xBlock }, }, } @@ -399,7 +403,11 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { func TestBlockVerify_InvalidPostForkOption(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -413,9 +421,8 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: xBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -423,18 +430,16 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: xBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: xBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: xBlockID, }, }, } @@ -449,10 +454,9 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } ySlb, err := block.BuildUnsigned( @@ -529,9 +533,8 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: zBlockID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -539,18 +542,16 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: zBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: zBlockID, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: zBlockID, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: zBlockID, }, }, } @@ -586,7 +587,11 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { func TestGetBlock_MutatedSignature(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -609,10 +614,9 @@ func TestGetBlock_MutatedSignature(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreBlk1 := &snowman.TestBlock{ @@ -620,10 +624,9 @@ func TestGetBlock_MutatedSignature(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk0.ID(), - HeightV: coreBlk0.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk0.ID(), + HeightV: coreBlk0.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { @@ -663,7 +666,7 @@ func TestGetBlock_MutatedSignature(t *testing.T) { require.NoError(proVM.SetPreference(context.Background(), builtBlk0.ID())) - // The second propsal block will need to be signed because the timestamp + // The second proposal block will need to be signed because the timestamp // hasn't moved forward // Craft what would be the next block, but with an invalid signature: diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index fba3f5974332..d8b6ea195001 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -47,7 +47,8 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test proVM := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index d3e2282f25c0..4d35ea014ce1 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -74,6 +74,7 @@ func init() { func initTestProposerVM( t *testing.T, proBlkStartTime time.Time, + durangoTime time.Time, minPChainHeight uint64, ) ( *fullVM, @@ -136,6 +137,7 @@ func initTestProposerVM( coreVM, Config{ ActivationTime: proBlkStartTime, + DurangoTime: durangoTime, MinimumPChainHeight: minPChainHeight, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -219,7 +221,11 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -232,10 +238,9 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -252,7 +257,11 @@ func TestBuildBlockIsIdempotent(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -262,10 +271,9 @@ func TestBuildBlockIsIdempotent(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -287,7 +295,11 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -297,10 +309,9 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -321,7 +332,11 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -332,10 +347,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -348,10 +362,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -416,7 +429,11 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -426,10 +443,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -442,10 +458,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -491,10 +506,9 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: wronglyPreferredcoreBlk.ID(), - HeightV: wronglyPreferredcoreBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: wronglyPreferredcoreBlk.ID(), + HeightV: wronglyPreferredcoreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -512,7 +526,11 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { require := require.New(t) - coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -551,7 +569,11 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { require := require.New(t) - coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -622,7 +644,11 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -690,7 +716,11 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { func TestPreFork_Initialize(t *testing.T) { require := require.New(t) - _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -709,7 +739,11 @@ func TestPreFork_Initialize(t *testing.T) { func TestPreFork_BuildBlock(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -719,10 +753,9 @@ func TestPreFork_BuildBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{3}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -748,7 +781,11 @@ func TestPreFork_ParseBlock(t *testing.T) { require := require.New(t) // setup - coreVM, _, proVM, _, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -783,7 +820,11 @@ func TestPreFork_ParseBlock(t *testing.T) { func TestPreFork_SetPreference(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks + var ( + activationTime = mockable.MaxTime + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -884,6 +925,7 @@ func TestExpiredBuildBlock(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1056,7 +1098,11 @@ func (b *wrappedBlock) Verify(ctx context.Context) error { func TestInnerBlockDeduplication(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // disable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1230,6 +1276,7 @@ func TestInnerVMRollback(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1319,6 +1366,7 @@ func TestInnerVMRollback(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1356,7 +1404,11 @@ func TestInnerVMRollback(t *testing.T) { func TestBuildBlockDuringWindow(t *testing.T) { require := require.New(t) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1459,8 +1511,11 @@ func TestBuildBlockDuringWindow(t *testing.T) { func TestTwoForks_OneIsAccepted(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1555,8 +1610,11 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { func TestTooFarAdvanced(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1646,7 +1704,11 @@ func TestTooFarAdvanced(t *testing.T) { func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1721,7 +1783,11 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1812,7 +1878,8 @@ func TestRejectedHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2021,7 +2088,8 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2186,7 +2254,8 @@ func TestVMInnerBlkCache(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2286,8 +2355,11 @@ func TestVMInnerBlkCache(t *testing.T) { func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2362,8 +2434,11 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) - forkTime := time.Unix(0, 0) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) + var ( + activationTime = time.Unix(0, 0) + durangoForkTime = mockable.MaxTime + ) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2417,7 +2492,8 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2630,7 +2706,8 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Time{}, + ActivationTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2731,6 +2808,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, @@ -2775,6 +2853,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: newNumHistoricalBlocks, From 793e2104131f4018d5cf29ea109cbe0655fc10fb Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 08:58:56 +0100 Subject: [PATCH 031/111] leftovers --- vms/proposervm/block_test.go | 2 +- vms/proposervm/post_fork_option_test.go | 2 +- vms/proposervm/state_syncable_vm_test.go | 2 +- vms/proposervm/vm_regression_test.go | 3 ++- vms/proposervm/vm_test.go | 8 ++++---- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 9ce9d051ce02..4cc8908d0330 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -70,7 +70,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { vm := &VM{ Config: Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 4c94c4103629..0e468f53efe0 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -684,7 +684,7 @@ func TestOptionTimestampValidity(t *testing.T) { coreVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index ea147eeeac3e..cecf2af0b46a 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -73,7 +73,7 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { innerVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index d8b6ea195001..528270b11f9c 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -17,6 +17,7 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" + "github.com/ava-labs/avalanchego/utils/timer/mockable" ) func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *testing.T) { @@ -48,7 +49,7 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test innerVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 4d35ea014ce1..2bd12abb23d9 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -1879,7 +1879,7 @@ func TestRejectedHeightNotIndexed(t *testing.T) { coreVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2089,7 +2089,7 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { coreVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2255,7 +2255,7 @@ func TestVMInnerBlkCache(t *testing.T) { innerVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2493,7 +2493,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { innerVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: time.Unix(0, 0), + DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, From 2b4d88f54355f7c2be84b6ccaf445243cba72d9e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 09:06:53 +0100 Subject: [PATCH 032/111] nit --- vms/proposervm/batched_vm_test.go | 14 +-- vms/proposervm/post_fork_block_test.go | 66 ++++++------- vms/proposervm/post_fork_option_test.go | 36 +++---- vms/proposervm/pre_fork_block_test.go | 54 +++++----- vms/proposervm/state_syncable_vm_test.go | 6 +- vms/proposervm/vm_byzantine_test.go | 36 +++---- vms/proposervm/vm_test.go | 120 +++++++++++------------ 7 files changed, 166 insertions(+), 166 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 92d0b8b334b3..dd17427e6af1 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -30,10 +30,10 @@ func TestCoreVMNotRemote(t *testing.T) { // if coreVM is not remote VM, a specific error is returned require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -60,7 +60,7 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { @@ -207,7 +207,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { @@ -567,7 +567,7 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { @@ -689,7 +689,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index a2c5307787d8..8b75b52464c8 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -40,10 +40,10 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { // setup var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -100,10 +100,10 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -202,10 +202,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -378,10 +378,10 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -520,10 +520,10 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -706,10 +706,10 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify a block once (in this test by building it). // Show that other verify call would not call coreBlk.Verify() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -773,10 +773,10 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { // setup var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -840,10 +840,10 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -892,10 +892,10 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -929,10 +929,10 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1048,10 +1048,10 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 5) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 5) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 0e468f53efe0..57eff8e8f3b0 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -38,10 +38,10 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -158,10 +158,10 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -264,10 +264,10 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -378,10 +378,10 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -484,10 +484,10 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -573,10 +573,10 @@ func TestOptionTimestampValidity(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoTime, 0) coreOracleBlkID := ids.GenerateTestID() coreOracleBlk := &TestOptionsBlock{ diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 82c179661b88..885d8ea193eb 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -52,10 +52,10 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -144,10 +144,10 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -241,10 +241,10 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -317,10 +317,10 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -451,10 +451,10 @@ func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(-1 * time.Second) - durangoForkTime = mockable.MaxTime + activationTime = genesisTimestamp.Add(-1 * time.Second) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(activationTime) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -496,10 +496,10 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { // setup var ( - activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -558,10 +558,10 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -593,10 +593,10 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -687,10 +687,10 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = mockable.MaxTime + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index cecf2af0b46a..89d99f9385dc 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -604,10 +604,10 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { // Note: by default proVM is built such that heightIndex will be considered complete var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index 251207303ca3..418f98f501ab 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -34,10 +34,10 @@ func TestInvalidByzantineProposerParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -105,10 +105,10 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -214,10 +214,10 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -304,10 +304,10 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -404,10 +404,10 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -588,10 +588,10 @@ func TestGetBlock_MutatedSignature(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 2bd12abb23d9..53bd7091c1c9 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -222,10 +222,10 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -258,10 +258,10 @@ func TestBuildBlockIsIdempotent(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -296,10 +296,10 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { // setup var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -333,10 +333,10 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -430,10 +430,10 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -527,10 +527,10 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -570,10 +570,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -645,10 +645,10 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -717,10 +717,10 @@ func TestPreFork_Initialize(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) - _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -740,10 +740,10 @@ func TestPreFork_BuildBlock(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -782,10 +782,10 @@ func TestPreFork_ParseBlock(t *testing.T) { // setup var ( - activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -821,10 +821,10 @@ func TestPreFork_SetPreference(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = mockable.MaxTime + activationTime = mockable.MaxTime + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1099,10 +1099,10 @@ func TestInnerBlockDeduplication(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1405,10 +1405,10 @@ func TestBuildBlockDuringWindow(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1512,10 +1512,10 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1611,10 +1611,10 @@ func TestTooFarAdvanced(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1705,10 +1705,10 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1784,10 +1784,10 @@ func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -2356,10 +2356,10 @@ func TestVMInnerBlkCache(t *testing.T) { func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2435,10 +2435,10 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() From d8ac4a24d8f5fcc2363719cf58c7ec150202fd39 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 09:11:06 +0100 Subject: [PATCH 033/111] nit --- vms/proposervm/batched_vm_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index dd17427e6af1..2735f5ad8c2a 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -365,7 +365,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) // enable ProBlks in next future From 5f89fda94689d74ab1dbb00583584463f24b474e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 09:51:59 +0100 Subject: [PATCH 034/111] fixed UTs --- vms/proposervm/batched_vm_test.go | 145 ++++++++++++++---------- vms/proposervm/post_fork_option_test.go | 127 ++++++++++++--------- 2 files changed, 156 insertions(+), 116 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 2735f5ad8c2a..9f4661f939c9 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -73,9 +73,10 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + TimestampV: coreGenBlk.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -99,9 +100,10 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, + TimestampV: coreBlk1.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -125,9 +127,10 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, + TimestampV: coreBlk2.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -220,9 +223,10 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + TimestampV: coreGenBlk.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -240,9 +244,10 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, + TimestampV: coreBlk1.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -260,9 +265,10 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, + TimestampV: coreBlk2.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -381,9 +387,10 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + TimestampV: preForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -408,9 +415,10 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -437,9 +445,10 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -458,9 +467,10 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -580,9 +590,10 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + TimestampV: coreGenBlk.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -606,9 +617,10 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, + TimestampV: coreBlk1.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -632,9 +644,10 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, + TimestampV: coreBlk2.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -702,9 +715,10 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + TimestampV: coreGenBlk.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -722,9 +736,10 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, + TimestampV: coreBlk1.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -742,9 +757,10 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, + TimestampV: coreBlk2.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -820,9 +836,10 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, + TimestampV: preForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -847,9 +864,10 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -876,9 +894,10 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -897,9 +916,10 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, + TimestampV: postForkTime, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -980,8 +1000,9 @@ func initTestRemoteProposerVM( IDV: ids.GenerateTestID(), StatusV: choices.Accepted, }, - HeightV: 0, - BytesV: []byte{0}, + HeightV: 0, + TimestampV: genesisTimestamp, + BytesV: []byte{0}, } initialState := []byte("genesis state") diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 57eff8e8f3b0..9a5bb1e81be6 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -19,6 +19,7 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" + "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) var _ snowman.OracleBlock = (*TestOptionsBlock)(nil) @@ -54,9 +55,10 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + TimestampV: coreGenBlk.Timestamp(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -65,18 +67,20 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -137,9 +141,10 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(4444), StatusV: choices.Processing, }, - ParentV: oracleCoreBlk.opts[0].ID(), - BytesV: []byte{4}, - HeightV: oracleCoreBlk.opts[0].Height() + 1, + ParentV: oracleCoreBlk.opts[0].ID(), + BytesV: []byte{4}, + TimestampV: oracleCoreBlk.opts[0].Timestamp().Add(proposer.MaxVerifyDelay), + HeightV: oracleCoreBlk.opts[0].Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return childCoreBlk, nil @@ -174,9 +179,10 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + TimestampV: coreGenBlk.Timestamp(), + HeightV: coreGenBlk.Height() + 1, }, } coreOpt0 := &snowman.TestBlock{ @@ -184,18 +190,20 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, } coreOpt1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, } oracleCoreBlk.opts = [2]snowman.Block{ coreOpt0, @@ -280,9 +288,10 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + TimestampV: coreGenBlk.Timestamp(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -291,18 +300,20 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -394,9 +405,10 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + TimestampV: coreGenBlk.Timestamp(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -405,18 +417,20 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + TimestampV: oracleCoreBlk.Timestamp(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -499,9 +513,10 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + TimestampV: coreGenBlk.Timestamp(), + HeightV: coreGenBlk.Height() + 1, }, optsErr: snowman.ErrNotOracle, } @@ -511,9 +526,10 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk.ID(), - HeightV: coreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk.ID(), + TimestampV: coreBlk.Timestamp(), + HeightV: coreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { @@ -585,9 +601,10 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: coreOracleBlkID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + TimestampV: coreGenBlk.Timestamp().Add(time.Second), + HeightV: coreGenBlk.Height() + 1, }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -595,18 +612,20 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreOracleBlkID, - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: coreOracleBlkID, + TimestampV: coreGenBlk.Timestamp().Add(time.Second), + HeightV: coreGenBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreOracleBlkID, - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: coreOracleBlkID, + TimestampV: coreGenBlk.Timestamp().Add(time.Second), + HeightV: coreGenBlk.Height() + 1, }, }, } From 20a9a932ba5544011d8816bbb4143159c8bdd41f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 12:49:24 +0100 Subject: [PATCH 035/111] some more cleanup --- vms/proposervm/post_fork_block_test.go | 367 +++++++++++++------------ 1 file changed, 193 insertions(+), 174 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 8b75b52464c8..227bc2ab82a8 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -119,9 +119,9 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return prntCoreBlk, nil @@ -147,7 +147,6 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { } } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) prntProBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -156,22 +155,11 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { // .. create child block ... childCoreBlk := &snowman.TestBlock{ - ParentV: prntCoreBlk.ID(), - BytesV: []byte{2}, - TimestampV: prntCoreBlk.Timestamp(), + ParentV: prntCoreBlk.ID(), + BytesV: []byte{2}, + HeightV: prntCoreBlk.Height() + 1, } - childSlb, err := block.Build( - ids.Empty, // refer unknown parent - childCoreBlk.Timestamp(), - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) childProBlk := postForkBlock{ - SignedBlock: childSlb, postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -179,23 +167,39 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { }, } - // child block referring unknown parent does not verify - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, database.ErrNotFound) + proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) - // child block referring known parent does verify - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), // refer known parent - prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), - pChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(err) + { + // child block referring unknown parent does not verify + childSlb, err := block.Build( + ids.Empty, // refer unknown parent + proVM.Time(), + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, database.ErrNotFound) + } - proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) - require.NoError(childProBlk.Verify(context.Background())) + { + // child block referring known parent does verify + childSlb, err := block.BuildUnsigned( + prntProBlk.ID(), // refer known parent + proVM.Time(), + pChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + require.NoError(childProBlk.Verify(context.Background())) + } } func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { @@ -221,9 +225,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return prntCoreBlk, nil @@ -265,22 +269,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { ParentV: prntCoreBlk.ID(), BytesV: []byte{2}, } - - // child block timestamp cannot be lower than parent timestamp - childCoreBlk.TimestampV = prntTimestamp.Add(-1 * time.Second) - proVM.Clock.Set(childCoreBlk.TimestampV) - childSlb, err := block.Build( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) childProBlk := postForkBlock{ - SignedBlock: childSlb, postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -288,90 +277,122 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeNotMonotonic) + newTime := prntTimestamp.Add(-1 * time.Second) + proVM.Clock.Set(newTime) + + { + // child block timestamp cannot be lower than parent timestamp + childSlb, err := block.Build( + prntProBlk.ID(), + newTime, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, errTimeNotMonotonic) + } - // block cannot arrive before its creator window starts blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), pChainHeight, proVM.ctx.NodeID, proposer.MaxVerifyWindows) require.NoError(err) - beforeWinStart := prntTimestamp.Add(blkWinDelay).Add(-1 * time.Second) - proVM.Clock.Set(beforeWinStart) - childSlb, err = block.Build( - prntProBlk.ID(), - beforeWinStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errProposerWindowNotStarted) - // block can arrive at its creator window starts - atWindowStart := prntTimestamp.Add(blkWinDelay) - proVM.Clock.Set(atWindowStart) - childSlb, err = block.Build( - prntProBlk.ID(), - atWindowStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb + { + // block cannot arrive before its creator window starts + beforeWinStart := prntTimestamp.Add(blkWinDelay).Add(-1 * time.Second) + proVM.Clock.Set(beforeWinStart) + childSlb, err := block.Build( + prntProBlk.ID(), + beforeWinStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, errProposerWindowNotStarted) + } - require.NoError(childProBlk.Verify(context.Background())) + { + // block can arrive at its creator window starts + atWindowStart := prntTimestamp.Add(blkWinDelay) + proVM.Clock.Set(atWindowStart) + childSlb, err := block.Build( + prntProBlk.ID(), + atWindowStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + require.NoError(childProBlk.Verify(context.Background())) + } - // block can arrive after its creator window starts - afterWindowStart := prntTimestamp.Add(blkWinDelay).Add(5 * time.Second) - proVM.Clock.Set(afterWindowStart) - childSlb, err = block.Build( - prntProBlk.ID(), - afterWindowStart, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + { + // block can arrive after its creator window starts + afterWindowStart := prntTimestamp.Add(blkWinDelay).Add(5 * time.Second) + proVM.Clock.Set(afterWindowStart) + childSlb, err := block.Build( + prntProBlk.ID(), + afterWindowStart, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + require.NoError(childProBlk.Verify(context.Background())) + } - // block can arrive within submission window - atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) - proVM.Clock.Set(atSubWindowEnd) - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - atSubWindowEnd, - pChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + { + // block can arrive within submission window + atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) + proVM.Clock.Set(atSubWindowEnd) + childSlb, err := block.BuildUnsigned( + prntProBlk.ID(), + atSubWindowEnd, + pChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + require.NoError(childProBlk.Verify(context.Background())) + } - // block timestamp cannot be too much in the future - afterSubWinEnd := proVM.Time().Add(maxSkew).Add(time.Second) - childSlb, err = block.Build( - prntProBlk.ID(), - afterSubWinEnd, - pChainHeight, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // block timestamp cannot be too much in the future + afterSubWinEnd := proVM.Time().Add(maxSkew).Add(time.Second) + childSlb, err := block.Build( + prntProBlk.ID(), + afterSubWinEnd, + pChainHeight, + proVM.StakingCertLeaf, + childCoreBlk.Bytes(), + proVM.ctx.ChainID, + proVM.StakingLeafSigner, + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, errTimeTooAdvanced) + } } func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { @@ -397,9 +418,9 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return prntCoreBlk, nil @@ -432,21 +453,21 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) prntBlkPChainHeight := pChainHeight + nextTime := prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay) childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: prntCoreBlk.ID(), - BytesV: []byte{2}, - TimestampV: prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: prntCoreBlk.ID(), + BytesV: []byte{2}, } // child P-Chain height must not precede parent P-Chain height childSlb, err := block.Build( prntProBlk.ID(), - childCoreBlk.Timestamp(), + nextTime, prntBlkPChainHeight-1, proVM.StakingCertLeaf, childCoreBlk.Bytes(), @@ -541,9 +562,9 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -552,18 +573,18 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -616,21 +637,22 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) prntBlkPChainHeight := pChainHeight + nextTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: oracleCoreBlk.opts[0].ID(), - BytesV: []byte{2}, - TimestampV: parentBlk.Timestamp().Add(proposer.MaxVerifyDelay), + ParentV: oracleCoreBlk.opts[0].ID(), + BytesV: []byte{2}, + HeightV: oracleCoreBlk.opts[0].Height() + 1, } // child P-Chain height must not precede parent P-Chain height childSlb, err := block.Build( parentBlk.ID(), - childCoreBlk.Timestamp(), + nextTime, prntBlkPChainHeight-1, proVM.StakingCertLeaf, childCoreBlk.Bytes(), @@ -724,9 +746,9 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -791,9 +813,9 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -859,10 +881,9 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -905,10 +926,9 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp().Add(proposer.MaxVerifyDelay), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk, nil @@ -945,9 +965,9 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } coreOpt0 := &snowman.TestBlock{ @@ -955,18 +975,18 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } coreOpt1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } oracleCoreBlk.opts = [2]snowman.Block{ coreOpt0, @@ -1052,7 +1072,6 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 5) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1062,9 +1081,9 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { From 89bd4a299ebee2a45982fff200f8a715fe29a939 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 14:14:58 +0100 Subject: [PATCH 036/111] fixed TestBlockVerify_PostForkBlock_PChainHeightChecks --- vms/proposervm/post_fork_block_test.go | 243 +++++++++++++------------ 1 file changed, 129 insertions(+), 114 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 227bc2ab82a8..7403adadcd61 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -114,7 +114,7 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { } // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -124,14 +124,14 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -140,26 +140,26 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) // .. create child block ... childCoreBlk := &snowman.TestBlock{ - ParentV: prntCoreBlk.ID(), + ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, - HeightV: prntCoreBlk.Height() + 1, + HeightV: parentCoreBlk.Height() + 1, } - childProBlk := postForkBlock{ + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -167,38 +167,36 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { }, } + // set proVM to be able to build unsigned blocks proVM.Set(proVM.Time().Add(proposer.MaxVerifyDelay)) { // child block referring unknown parent does not verify - childSlb, err := block.Build( + childSlb, err := block.BuildUnsigned( ids.Empty, // refer unknown parent proVM.Time(), pChainHeight, - proVM.StakingCertLeaf, childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, database.ErrNotFound) } { // child block referring known parent does verify childSlb, err := block.BuildUnsigned( - prntProBlk.ID(), // refer known parent + parentBlk.ID(), // refer known parent proVM.Time(), pChainHeight, childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } } @@ -220,7 +218,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { } // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -230,14 +228,14 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -246,27 +244,27 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - prntTimestamp := prntProBlk.Timestamp() + parentTimestamp := parentBlk.Timestamp() childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: prntCoreBlk.ID(), + ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, } childProBlk := postForkBlock{ @@ -277,13 +275,13 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { }, } - newTime := prntTimestamp.Add(-1 * time.Second) - proVM.Clock.Set(newTime) - { // child block timestamp cannot be lower than parent timestamp + newTime := parentTimestamp.Add(-1 * time.Second) + proVM.Clock.Set(newTime) + childSlb, err := block.Build( - prntProBlk.ID(), + parentBlk.ID(), newTime, pChainHeight, proVM.StakingCertLeaf, @@ -303,10 +301,11 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { { // block cannot arrive before its creator window starts - beforeWinStart := prntTimestamp.Add(blkWinDelay).Add(-1 * time.Second) + beforeWinStart := parentTimestamp.Add(blkWinDelay).Add(-1 * time.Second) proVM.Clock.Set(beforeWinStart) + childSlb, err := block.Build( - prntProBlk.ID(), + parentBlk.ID(), beforeWinStart, pChainHeight, proVM.StakingCertLeaf, @@ -323,10 +322,11 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { { // block can arrive at its creator window starts - atWindowStart := prntTimestamp.Add(blkWinDelay) + atWindowStart := parentTimestamp.Add(blkWinDelay) proVM.Clock.Set(atWindowStart) + childSlb, err := block.Build( - prntProBlk.ID(), + parentBlk.ID(), atWindowStart, pChainHeight, proVM.StakingCertLeaf, @@ -342,10 +342,11 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { { // block can arrive after its creator window starts - afterWindowStart := prntTimestamp.Add(blkWinDelay).Add(5 * time.Second) + afterWindowStart := parentTimestamp.Add(blkWinDelay).Add(5 * time.Second) proVM.Clock.Set(afterWindowStart) + childSlb, err := block.Build( - prntProBlk.ID(), + parentBlk.ID(), afterWindowStart, pChainHeight, proVM.StakingCertLeaf, @@ -363,8 +364,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { // block can arrive within submission window atSubWindowEnd := proVM.Time().Add(proposer.MaxVerifyDelay) proVM.Clock.Set(atSubWindowEnd) + childSlb, err := block.BuildUnsigned( - prntProBlk.ID(), + parentBlk.ID(), atSubWindowEnd, pChainHeight, childCoreBlk.Bytes(), @@ -378,8 +380,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { { // block timestamp cannot be too much in the future afterSubWinEnd := proVM.Time().Add(maxSkew).Add(time.Second) + childSlb, err := block.Build( - prntProBlk.ID(), + parentBlk.ID(), afterSubWinEnd, pChainHeight, proVM.StakingCertLeaf, @@ -411,9 +414,12 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { valState.GetCurrentHeightF = func(context.Context) (uint64, error) { return pChainHeight, nil } + valState.GetMinimumHeightF = func(context.Context) (uint64, error) { + return pChainHeight / 50, nil + } // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -423,14 +429,14 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -439,44 +445,32 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, errUnknownBlock } } - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) - require.NoError(prntProBlk.Verify(context.Background())) - require.NoError(proVM.SetPreference(context.Background(), prntProBlk.ID())) + require.NoError(parentBlk.Verify(context.Background())) + require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - prntBlkPChainHeight := pChainHeight - nextTime := prntProBlk.Timestamp().Add(proposer.MaxVerifyDelay) + // set VM to be ready to build next block + nextTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) + proVM.Set(nextTime) childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - ParentV: prntCoreBlk.ID(), + ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, } - - // child P-Chain height must not precede parent P-Chain height - childSlb, err := block.Build( - prntProBlk.ID(), - nextTime, - prntBlkPChainHeight-1, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) childProBlk := postForkBlock{ - SignedBlock: childSlb, postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -484,57 +478,78 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // child P-Chain height must not precede parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlk.(*postForkBlock).PChainHeight()-1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb - // child P-Chain height can be equal to parent P-Chain height - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotMonotonic) + } - proVM.Set(childCoreBlk.Timestamp()) - require.NoError(childProBlk.Verify(context.Background())) + { + // child P-Chain height can be equal to parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlk.(*postForkBlock).PChainHeight(), + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb - // child P-Chain height may follow parent P-Chain height - pChainHeight = prntBlkPChainHeight * 2 // move ahead pChainHeight - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight+1, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childProBlk.Verify(context.Background())) + } + + { + // child P-Chain height may follow parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlk.(*postForkBlock).PChainHeight()+1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + require.NoError(childProBlk.Verify(context.Background())) + } - // block P-Chain height can be equal to current P-Chain height currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + { + // block P-Chain height can be equal to current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb - // block P-Chain height cannot be at higher than current P-Chain height - childSlb, err = block.BuildUnsigned( - prntProBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight*2, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errPChainHeightNotReached) + require.NoError(childProBlk.Verify(context.Background())) + } + + { + // block P-Chain height cannot be at higher than current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight*2, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childProBlk.SignedBlock = childSlb + + err = childProBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotReached) + } } func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) { From 5b773dce3bb3d9e7c89e08573d7797521cb1db3e Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 14:33:14 +0100 Subject: [PATCH 037/111] fixed TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks --- vms/proposervm/post_fork_block_test.go | 152 ++++++++++++++----------- 1 file changed, 84 insertions(+), 68 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 7403adadcd61..8204b0ecf776 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -458,10 +458,13 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require.NoError(parentBlk.Verify(context.Background())) require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - // set VM to be ready to build next block + // set VM to be ready to build next block. We set it to generate unsigned blocks + // for simplicity. nextTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) proVM.Set(nextTime) + parentBlkPChainHeight := parentBlk.(*postForkBlock).PChainHeight() + childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(2222), @@ -483,7 +486,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childSlb, err := block.BuildUnsigned( parentBlk.ID(), nextTime, - parentBlk.(*postForkBlock).PChainHeight()-1, + parentBlkPChainHeight-1, childCoreBlk.Bytes(), ) require.NoError(err) @@ -498,7 +501,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childSlb, err := block.BuildUnsigned( parentBlk.ID(), nextTime, - parentBlk.(*postForkBlock).PChainHeight(), + parentBlkPChainHeight, childCoreBlk.Bytes(), ) require.NoError(err) @@ -512,7 +515,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childSlb, err := block.BuildUnsigned( parentBlk.ID(), nextTime, - parentBlk.(*postForkBlock).PChainHeight()+1, + parentBlkPChainHeight+1, childCoreBlk.Bytes(), ) require.NoError(err) @@ -568,7 +571,9 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) valState.GetCurrentHeightF = func(context.Context) (uint64, error) { return pChainHeight, nil } - // proVM.SetStartTime(timer.MaxTime) // switch off scheduler for current test + valState.GetMinimumHeightF = func(context.Context) (uint64, error) { + return pChainHeight / 50, nil + } // create post fork oracle block ... oracleCoreBlk := &TestOptionsBlock{ @@ -651,8 +656,12 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) require.NoError(parentBlk.Verify(context.Background())) require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - prntBlkPChainHeight := pChainHeight + // set VM to be ready to build next block. We set it to generate unsigned blocks + // for simplicity. nextTime := parentBlk.Timestamp().Add(proposer.MaxVerifyDelay) + proVM.Set(nextTime) + + parentBlkPChainHeight := postForkOracleBlk.PChainHeight() // option takes proposal blocks' Pchain height childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -663,20 +672,7 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) BytesV: []byte{2}, HeightV: oracleCoreBlk.opts[0].Height() + 1, } - - // child P-Chain height must not precede parent P-Chain height - childSlb, err := block.Build( - parentBlk.ID(), - nextTime, - prntBlkPChainHeight-1, - proVM.StakingCertLeaf, - childCoreBlk.Bytes(), - proVM.ctx.ChainID, - proVM.StakingLeafSigner, - ) - require.NoError(err) - childProBlk := postForkBlock{ - SignedBlock: childSlb, + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -684,57 +680,77 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) }, } - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errTimeTooAdvanced) + { + // child P-Chain height must not precede parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight-1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotMonotonic) + } + + { + // child P-Chain height can be equal to parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb - // child P-Chain height can be equal to parent P-Chain height - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - - proVM.Set(childCoreBlk.Timestamp()) - require.NoError(childProBlk.Verify(context.Background())) - - // child P-Chain height may follow parent P-Chain height - pChainHeight = prntBlkPChainHeight * 2 // move ahead pChainHeight - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - prntBlkPChainHeight+1, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) + } + + { + // child P-Chain height may follow parent P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + parentBlkPChainHeight+1, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } - // block P-Chain height can be equal to current P-Chain height currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) - - // block P-Chain height cannot be at higher than current P-Chain height - childSlb, err = block.BuildUnsigned( - parentBlk.ID(), - childCoreBlk.Timestamp(), - currPChainHeight*2, - childCoreBlk.Bytes(), - ) - require.NoError(err) - childProBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, errPChainHeightNotReached) + { + // block P-Chain height can be equal to current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + + require.NoError(childBlk.Verify(context.Background())) + } + + { + // block P-Chain height cannot be at higher than current P-Chain height + childSlb, err := block.BuildUnsigned( + parentBlk.ID(), + nextTime, + currPChainHeight*2, + childCoreBlk.Bytes(), + ) + require.NoError(err) + childBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, errPChainHeightNotReached) + } } func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { From 970dff9f795e34faca940aa50e2a3b08cb728a60 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 14:37:29 +0100 Subject: [PATCH 038/111] nit --- vms/proposervm/post_fork_block_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 8204b0ecf776..7c63f2f192f1 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -984,7 +984,6 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() From 04905c60ed6efd1ebe1acedf177edf21f15e6f25 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 14:51:04 +0100 Subject: [PATCH 039/111] cleaned up post fork option tests --- vms/proposervm/post_fork_option_test.go | 142 ++++++++++-------------- 1 file changed, 59 insertions(+), 83 deletions(-) diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index 9a5bb1e81be6..eece7064de2b 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -19,7 +19,6 @@ import ( "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) var _ snowman.OracleBlock = (*TestOptionsBlock)(nil) @@ -43,7 +42,6 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -55,10 +53,9 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -67,20 +64,18 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -141,15 +136,13 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { IDV: ids.Empty.Prefix(4444), StatusV: choices.Processing, }, - ParentV: oracleCoreBlk.opts[0].ID(), - BytesV: []byte{4}, - TimestampV: oracleCoreBlk.opts[0].Timestamp().Add(proposer.MaxVerifyDelay), - HeightV: oracleCoreBlk.opts[0].Height() + 1, + ParentV: oracleCoreBlk.opts[0].ID(), + BytesV: []byte{4}, + HeightV: oracleCoreBlk.opts[0].Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return childCoreBlk, nil } - proVM.Set(childCoreBlk.Timestamp()) proChild, err := proVM.BuildBlock(context.Background()) require.NoError(err) @@ -167,7 +160,6 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -179,10 +171,9 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } coreOpt0 := &snowman.TestBlock{ @@ -190,20 +181,18 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } coreOpt1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, } oracleCoreBlk.opts = [2]snowman.Block{ coreOpt0, @@ -276,7 +265,6 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -288,10 +276,9 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -300,20 +287,18 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -393,7 +378,6 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -405,10 +389,9 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, } oracleCoreBlk.opts = [2]snowman.Block{ @@ -417,20 +400,18 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { IDV: ids.Empty.Prefix(2222), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(3333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: oracleCoreBlk.ID(), - TimestampV: oracleCoreBlk.Timestamp(), - HeightV: oracleCoreBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: oracleCoreBlk.ID(), + HeightV: oracleCoreBlk.Height() + 1, }, } @@ -502,7 +483,6 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -513,10 +493,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp(), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, optsErr: snowman.ErrNotOracle, } @@ -526,10 +505,9 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk.ID(), - TimestampV: coreBlk.Timestamp(), - HeightV: coreBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: coreBlk.ID(), + HeightV: coreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { @@ -601,10 +579,9 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: coreOracleBlkID, StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - TimestampV: coreGenBlk.Timestamp().Add(time.Second), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, }, opts: [2]snowman.Block{ &snowman.TestBlock{ @@ -612,26 +589,26 @@ func TestOptionTimestampValidity(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{2}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 2, }, &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreOracleBlkID, - TimestampV: coreGenBlk.Timestamp().Add(time.Second), - HeightV: coreGenBlk.Height() + 1, + BytesV: []byte{3}, + ParentV: coreOracleBlkID, + HeightV: coreGenBlk.Height() + 2, }, }, } + + oracleBlkTime := proVM.Time().Truncate(time.Second) statelessBlock, err := block.BuildUnsigned( coreGenBlk.ID(), - coreGenBlk.Timestamp(), + oracleBlkTime, 0, coreOracleBlk.Bytes(), ) @@ -691,8 +668,7 @@ func TestOptionTimestampValidity(t *testing.T) { return nil, nil } - expectedTime := coreGenBlk.Timestamp() - require.Equal(expectedTime, option.Timestamp()) + require.Equal(oracleBlkTime, option.Timestamp()) require.NoError(option.Accept(context.Background())) require.NoError(proVM.Shutdown(context.Background())) @@ -787,5 +763,5 @@ func TestOptionTimestampValidity(t *testing.T) { return nil, nil } - require.Equal(expectedTime, statefulOptionBlock.Timestamp()) + require.Equal(oracleBlkTime, statefulOptionBlock.Timestamp()) } From 18ce5ede6c398a910e8680626455d9fd779b992c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 15:06:12 +0100 Subject: [PATCH 040/111] cleaned up state syncable vm tests --- vms/proposervm/state_syncable_vm_test.go | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 89d99f9385dc..002ab3967c2d 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -177,9 +177,9 @@ func TestStateSyncGetOngoingSyncStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -262,9 +262,9 @@ func TestStateSyncGetLastStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -350,9 +350,9 @@ func TestStateSyncGetStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -423,9 +423,9 @@ func TestParseStateSummary(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) @@ -482,9 +482,9 @@ func TestStateSummaryAccept(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } slb, err := statelessblock.Build( @@ -554,9 +554,9 @@ func TestStateSummaryAcceptOlderBlock(t *testing.T) { // store post fork block associated with summary innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: vm.Time(), - HeightV: innerSummary.Height(), + BytesV: []byte{1}, + ParentV: ids.GenerateTestID(), + HeightV: innerSummary.Height(), } innerVM.GetStateSummaryF = func(_ context.Context, h uint64) (block.StateSummary, error) { require.Equal(reqHeight, h) From c9b32a3347c9dd1f93a411986510de98070a6933 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 15:43:36 +0100 Subject: [PATCH 041/111] reduced changes scope --- chains/manager.go | 2 - vms/proposervm/batched_vm_test.go | 42 ++----- vms/proposervm/block_test.go | 14 +-- vms/proposervm/config.go | 7 -- vms/proposervm/post_fork_block_test.go | 67 ++--------- vms/proposervm/post_fork_option_test.go | 38 +----- vms/proposervm/pre_fork_block_test.go | 60 +++------- vms/proposervm/state_syncable_vm_test.go | 8 +- vms/proposervm/vm_byzantine_test.go | 39 ++---- vms/proposervm/vm_regression_test.go | 2 - vms/proposervm/vm_test.go | 146 +++++------------------ 11 files changed, 80 insertions(+), 345 deletions(-) diff --git a/chains/manager.go b/chains/manager.go index 43160e136f7c..86da6811c41a 100644 --- a/chains/manager.go +++ b/chains/manager.go @@ -771,7 +771,6 @@ func (m *manager) createAvalancheChain( vmWrappedInsideProposerVM, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, - DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, @@ -1117,7 +1116,6 @@ func (m *manager) createSnowmanChain( vm, proposervm.Config{ ActivationTime: m.ApricotPhase4Time, - DurangoTime: version.GetDurangoTime(m.NetworkID), MinimumPChainHeight: m.ApricotPhase4MinPChainHeight, MinBlkDelay: minBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 9f4661f939c9..6f31e09fda3b 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -29,11 +29,7 @@ import ( func TestCoreVMNotRemote(t *testing.T) { // if coreVM is not remote VM, a specific error is returned require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -58,11 +54,7 @@ func TestCoreVMNotRemote(t *testing.T) { func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -208,11 +200,7 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -370,12 +358,10 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { preForkTime = currentTime.Add(5 * time.Minute) forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - - durangoTime = mockable.MaxTime ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -575,11 +561,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, mockable.MaxTime) // disable ProBlks defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -700,11 +682,7 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, time.Time{}) // enable ProBlks defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -819,12 +797,10 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { preForkTime = currentTime.Add(5 * time.Minute) forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - - durangoTime = time.Unix(0, 0) ) // enable ProBlks in next future - coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime, durangoTime) + coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, forkTime) defer func() { require.NoError(proRemoteVM.Shutdown(context.Background())) }() @@ -986,8 +962,7 @@ type TestRemoteProposerVM struct { func initTestRemoteProposerVM( t *testing.T, - activationTime, - durangoTime time.Time, + activationTime time.Time, ) ( TestRemoteProposerVM, *VM, @@ -1053,7 +1028,6 @@ func initTestRemoteProposerVM( coreVM, Config{ ActivationTime: activationTime, - DurangoTime: durangoTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 4cc8908d0330..f0bbe75f3dba 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -25,7 +25,6 @@ import ( "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/staking" "github.com/ava-labs/avalanchego/utils/logging" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -70,7 +69,6 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { vm := &VM{ Config: Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, @@ -103,11 +101,7 @@ func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Unix(0, 0), 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() @@ -240,11 +234,7 @@ func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Unix(0, 0), 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() diff --git a/vms/proposervm/config.go b/vms/proposervm/config.go index 6e4ed9576925..96645c9489a8 100644 --- a/vms/proposervm/config.go +++ b/vms/proposervm/config.go @@ -14,9 +14,6 @@ type Config struct { // Time at which proposerVM activates its congestion control mechanism ActivationTime time.Time - // Durango fork activation time - DurangoTime time.Time - // Minimal P-chain height referenced upon block building MinimumPChainHeight uint64 @@ -33,7 +30,3 @@ type Config struct { // Block certificate StakingCertLeaf *staking.Certificate } - -func (c *Config) IsDurangoActivated(timestamp time.Time) bool { - return !timestamp.Before(c.DurangoTime) -} diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 7c63f2f192f1..7e5a47433521 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -16,7 +16,6 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -39,11 +38,7 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { require.Equal(snowman.ErrNotOracle, err) // setup - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + _, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -99,11 +94,7 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -203,11 +194,7 @@ func TestBlockVerify_PostForkBlock_ParentChecks(t *testing.T) { func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -401,11 +388,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -558,11 +541,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -758,11 +737,7 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify a block once (in this test by building it). // Show that other verify call would not call coreBlk.Verify() - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -825,11 +800,7 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -892,11 +863,7 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -943,11 +910,7 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -979,11 +942,7 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1097,11 +1056,7 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 5) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 5) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index eece7064de2b..0de98353e68a 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" ) @@ -37,11 +36,7 @@ func (tob TestOptionsBlock) Options(context.Context) ([2]snowman.Block, error) { func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -155,11 +150,7 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -260,11 +251,7 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -373,11 +360,7 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -478,11 +461,7 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { require := require.New(t) // Verify an option once; then show that another verify call would not call coreBlk.Verify() - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -566,11 +545,7 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { func TestOptionTimestampValidity(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks coreOracleBlkID := ids.GenerateTestID() coreOracleBlk := &TestOptionsBlock{ @@ -679,7 +654,6 @@ func TestOptionTimestampValidity(t *testing.T) { coreVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 885d8ea193eb..4308f9ba05f1 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -51,11 +51,7 @@ func TestOracle_PreForkBlkImplementsInterface(t *testing.T) { func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -143,11 +139,8 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) - var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + activationTime := genesisTimestamp.Add(10 * time.Second) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -240,11 +233,8 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require := require.New(t) - var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + activationTime := genesisTimestamp.Add(10 * time.Second) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -316,11 +306,8 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { require := require.New(t) - var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + activationTime := genesisTimestamp.Add(10 * time.Second) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -450,11 +437,8 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { require := require.New(t) - var ( - activationTime = genesisTimestamp.Add(-1 * time.Second) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + activationTime := genesisTimestamp.Add(-1 * time.Second) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) proVM.Set(activationTime) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -495,11 +479,7 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) // setup - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -557,11 +537,7 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { require := require.New(t) - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -592,11 +568,8 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { require := require.New(t) - var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + activationTime := genesisTimestamp.Add(10 * time.Second) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -686,11 +659,8 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { require := require.New(t) - var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + activationTime := genesisTimestamp.Add(10 * time.Second) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 002ab3967c2d..d277170cbeef 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -19,7 +19,6 @@ import ( "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/summary" statelessblock "github.com/ava-labs/avalanchego/vms/proposervm/block" @@ -73,7 +72,6 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { innerVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -603,11 +601,7 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { require := require.New(t) // Note: by default proVM is built such that heightIndex will be considered complete - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Unix(0, 0), 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index 418f98f501ab..5b6c29ee6a63 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" "github.com/ava-labs/avalanchego/snow/validators" - "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" ) @@ -33,11 +32,8 @@ import ( func TestInvalidByzantineProposerParent(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + forkTime := time.Unix(0, 0) // enable ProBlks + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -104,11 +100,7 @@ func TestInvalidByzantineProposerParent(t *testing.T) { func TestInvalidByzantineProposerOracleParent(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -213,11 +205,8 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { func TestInvalidByzantineProposerPreForkParent(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + forkTime := time.Unix(0, 0) // enable ProBlks + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -303,11 +292,7 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -403,11 +388,7 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { func TestBlockVerify_InvalidPostForkOption(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -587,11 +568,7 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { func TestGetBlock_MutatedSignature(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index 528270b11f9c..36633db0925c 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -17,7 +17,6 @@ import ( "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/engine/common" "github.com/ava-labs/avalanchego/snow/engine/snowman/block" - "github.com/ava-labs/avalanchego/utils/timer/mockable" ) func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *testing.T) { @@ -49,7 +48,6 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test innerVM, Config{ ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 53bd7091c1c9..8b5ccfbadf76 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -74,7 +74,6 @@ func init() { func initTestProposerVM( t *testing.T, proBlkStartTime time.Time, - durangoTime time.Time, minPChainHeight uint64, ) ( *fullVM, @@ -137,7 +136,6 @@ func initTestProposerVM( coreVM, Config{ ActivationTime: proBlkStartTime, - DurangoTime: durangoTime, MinimumPChainHeight: minPChainHeight, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -221,11 +219,7 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -257,11 +251,7 @@ func TestBuildBlockIsIdempotent(t *testing.T) { require := require.New(t) // given the same core block, BuildBlock returns the same proposer block - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -295,11 +285,7 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { require := require.New(t) // setup - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -332,11 +318,7 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -429,11 +411,7 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -526,11 +504,7 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -569,11 +543,7 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -644,11 +614,7 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -716,11 +682,7 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { func TestPreFork_Initialize(t *testing.T) { require := require.New(t) - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -739,11 +701,7 @@ func TestPreFork_Initialize(t *testing.T) { func TestPreFork_BuildBlock(t *testing.T) { require := require.New(t) - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -781,11 +739,7 @@ func TestPreFork_ParseBlock(t *testing.T) { require := require.New(t) // setup - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -820,11 +774,7 @@ func TestPreFork_ParseBlock(t *testing.T) { func TestPreFork_SetPreference(t *testing.T) { require := require.New(t) - var ( - activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, mockable.MaxTime, 0) // disable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -925,7 +875,6 @@ func TestExpiredBuildBlock(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1098,11 +1047,7 @@ func (b *wrappedBlock) Verify(ctx context.Context) error { func TestInnerBlockDeduplication(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // disable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1276,7 +1221,6 @@ func TestInnerVMRollback(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1366,7 +1310,6 @@ func TestInnerVMRollback(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -1404,11 +1347,7 @@ func TestInnerVMRollback(t *testing.T) { func TestBuildBlockDuringWindow(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1511,11 +1450,8 @@ func TestBuildBlockDuringWindow(t *testing.T) { func TestTwoForks_OneIsAccepted(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + forkTime := time.Unix(0, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1610,11 +1546,8 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { func TestTooFarAdvanced(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + forkTime := time.Unix(0, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1704,11 +1637,7 @@ func TestTooFarAdvanced(t *testing.T) { func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1783,11 +1712,7 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -1878,8 +1803,7 @@ func TestRejectedHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, + ActivationTime: time.Time{}, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2088,8 +2012,7 @@ func TestRejectedOptionHeightNotIndexed(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, + ActivationTime: time.Time{}, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2254,8 +2177,7 @@ func TestVMInnerBlkCache(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, + ActivationTime: time.Time{}, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2355,11 +2277,8 @@ func TestVMInnerBlkCache(t *testing.T) { func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + forkTime := time.Unix(0, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2434,11 +2353,8 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) - var ( - activationTime = time.Unix(0, 0) - durangoTime = mockable.MaxTime - ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) + forkTime := time.Unix(0, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, forkTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2492,8 +2408,7 @@ func TestVM_VerifyBlockWithContext(t *testing.T) { vm := New( innerVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, + ActivationTime: time.Time{}, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2706,8 +2621,7 @@ func TestHistoricalBlockDeletion(t *testing.T) { proVM := New( coreVM, Config{ - ActivationTime: time.Unix(0, 0), - DurangoTime: mockable.MaxTime, + ActivationTime: time.Time{}, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -2808,7 +2722,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: numHistoricalBlocks, @@ -2853,7 +2766,6 @@ func TestHistoricalBlockDeletion(t *testing.T) { coreVM, Config{ ActivationTime: time.Time{}, - DurangoTime: mockable.MaxTime, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: newNumHistoricalBlocks, From 13407eb15c8cabe368169c8a77f733d3a82d777b Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 16:06:31 +0100 Subject: [PATCH 042/111] nits --- vms/proposervm/batched_vm_test.go | 97 ++++++++++++---------------- vms/proposervm/vm_regression_test.go | 2 +- 2 files changed, 43 insertions(+), 56 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 6f31e09fda3b..983bddff0e93 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -211,10 +211,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -232,10 +231,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -253,10 +251,9 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -431,10 +428,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -453,10 +449,9 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -572,10 +567,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -599,10 +593,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -626,10 +619,9 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -693,10 +685,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk1, nil @@ -714,10 +705,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk1.ID(), - HeightV: coreBlk1.Height() + 1, - TimestampV: coreBlk1.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk1.ID(), + HeightV: coreBlk1.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk2, nil @@ -735,10 +725,9 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: coreBlk2.Timestamp(), + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -870,10 +859,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: coreBlk2.ID(), - HeightV: coreBlk2.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{3}, + ParentV: coreBlk2.ID(), + HeightV: coreBlk2.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -892,10 +880,9 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{4}, - ParentV: coreBlk3.ID(), - HeightV: coreBlk3.Height() + 1, - TimestampV: postForkTime, + BytesV: []byte{4}, + ParentV: coreBlk3.ID(), + HeightV: coreBlk3.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk4, nil @@ -975,9 +962,9 @@ func initTestRemoteProposerVM( IDV: ids.GenerateTestID(), StatusV: choices.Accepted, }, - HeightV: 0, - TimestampV: genesisTimestamp, - BytesV: []byte{0}, + HeightV: 0, + + BytesV: []byte{0}, } initialState := []byte("genesis state") diff --git a/vms/proposervm/vm_regression_test.go b/vms/proposervm/vm_regression_test.go index 36633db0925c..fba3f5974332 100644 --- a/vms/proposervm/vm_regression_test.go +++ b/vms/proposervm/vm_regression_test.go @@ -47,7 +47,7 @@ func TestProposerVMInitializeShouldFailIfInnerVMCantVerifyItsHeightIndex(t *test proVM := New( innerVM, Config{ - ActivationTime: time.Unix(0, 0), + ActivationTime: time.Time{}, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, From 542e9c6dc41ddaca156e104bab6c318ad619be6f Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 16:17:33 +0100 Subject: [PATCH 043/111] nits --- vms/proposervm/block_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index f0bbe75f3dba..fa7d4b082d15 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -101,7 +101,7 @@ func TestValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Unix(0, 0), 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(ctx)) }() @@ -234,7 +234,7 @@ func TestNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require := require.New(t) ctx := context.Background() - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Unix(0, 0), 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(ctx)) }() From fbdb0758c71e01f27addb8946732ecbf99267080 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 4 Dec 2023 16:27:53 +0100 Subject: [PATCH 044/111] nits --- vms/proposervm/state_syncable_vm_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index d277170cbeef..31695ec9876e 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -71,7 +71,7 @@ func helperBuildStateSyncTestObjects(t *testing.T) (*fullVM, *VM) { vm := New( innerVM, Config{ - ActivationTime: time.Unix(0, 0), + ActivationTime: time.Time{}, MinimumPChainHeight: 0, MinBlkDelay: DefaultMinBlockDelay, NumHistoricalBlocks: DefaultNumHistoricalBlocks, @@ -601,7 +601,7 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { require := require.New(t) // Note: by default proVM is built such that heightIndex will be considered complete - coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Unix(0, 0), 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, time.Time{}, 0) // enable ProBlks defer func() { require.NoError(proVM.Shutdown(context.Background())) }() From 0e923394c0374aebc9d291c7c2c4e4032a6dd2d6 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 5 Dec 2023 09:31:04 +0100 Subject: [PATCH 045/111] some more cleanup --- vms/proposervm/vm_test.go | 94 ++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 51 deletions(-) diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 8b5ccfbadf76..b716a6fa3c3d 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -210,6 +210,8 @@ func initTestProposerVM( require.NoError(proVM.SetState(context.Background(), snow.NormalOp)) require.NoError(proVM.SetPreference(context.Background(), coreGenBlk.IDV)) + proVM.Set(coreGenBlk.Timestamp()) + return coreVM, valState, proVM, coreGenBlk, db } @@ -391,10 +393,9 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { IDV: ids.Empty.Prefix(333), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: prefcoreBlk.ID(), - HeightV: prefcoreBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{3}, + ParentV: prefcoreBlk.ID(), + HeightV: prefcoreBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return coreBlk3, nil @@ -510,15 +511,14 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { }() innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - TimestampV: proVM.Time(), + BytesV: []byte{1}, } coreVM.ParseBlockF = func(context.Context, []byte) (snowman.Block, error) { return nil, errMarshallingFailed } slb, err := statelessblock.Build( proVM.preferred, - innerBlk.Timestamp(), + proVM.Time(), 100, // pChainHeight, proVM.StakingCertLeaf, innerBlk.Bytes(), @@ -550,19 +550,20 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { // create two Proposer blocks at the same height innerBlk := &snowman.TestBlock{ - BytesV: []byte{1}, - ParentV: gencoreBlk.ID(), - HeightV: gencoreBlk.Height() + 1, - TimestampV: proVM.Time(), + BytesV: []byte{1}, + ParentV: gencoreBlk.ID(), + HeightV: gencoreBlk.Height() + 1, } coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { require.Equal(innerBlk.Bytes(), b) return innerBlk, nil } + blkTimestamp := proVM.Time() + slb1, err := statelessblock.Build( proVM.preferred, - innerBlk.Timestamp(), + blkTimestamp, 100, // pChainHeight, proVM.StakingCertLeaf, innerBlk.Bytes(), @@ -581,7 +582,7 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { slb2, err := statelessblock.Build( proVM.preferred, - innerBlk.Timestamp(), + blkTimestamp, 200, // pChainHeight, proVM.StakingCertLeaf, innerBlk.Bytes(), @@ -621,10 +622,9 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { // one block is built from this proVM localcoreBlk := &snowman.TestBlock{ - BytesV: []byte{111}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: genesisTimestamp, + BytesV: []byte{111}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return localcoreBlk, nil @@ -636,10 +636,9 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { // another block with same parent comes from network and is parsed netcoreBlk := &snowman.TestBlock{ - BytesV: []byte{222}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: genesisTimestamp, + BytesV: []byte{222}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreVM.ParseBlockF = func(_ context.Context, b []byte) (snowman.Block, error) { switch { @@ -660,7 +659,7 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { netSlb, err := statelessblock.BuildUnsigned( proVM.preferred, - netcoreBlk.Timestamp(), + proVM.Time(), pChainHeight, netcoreBlk.Bytes(), ) @@ -962,14 +961,13 @@ func TestExpiredBuildBlock(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } statelessBlock, err := statelessblock.BuildUnsigned( coreGenBlk.ID(), - coreBlk.Timestamp(), + proVM.Time(), 0, coreBlk.Bytes(), ) @@ -1366,24 +1364,22 @@ func TestBuildBlockDuringWindow(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: coreGenBlk.ID(), - HeightV: coreGenBlk.Height() + 1, - TimestampV: coreGenBlk.Timestamp(), + BytesV: []byte{1}, + ParentV: coreGenBlk.ID(), + HeightV: coreGenBlk.Height() + 1, } coreBlk1 := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: coreBlk0.ID(), - HeightV: coreBlk0.Height() + 1, - TimestampV: coreBlk0.Timestamp(), + BytesV: []byte{2}, + ParentV: coreBlk0.ID(), + HeightV: coreBlk0.Height() + 1, } statelessBlock0, err := statelessblock.BuildUnsigned( coreGenBlk.ID(), - coreBlk0.Timestamp(), + proVM.Time(), 0, coreBlk0.Bytes(), ) @@ -1462,10 +1458,9 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{1}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp(), + BytesV: []byte{1}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { @@ -1482,15 +1477,14 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{2}, - ParentV: gBlock.ID(), - HeightV: gBlock.Height() + 1, - TimestampV: gBlock.Timestamp(), + BytesV: []byte{2}, + ParentV: gBlock.ID(), + HeightV: gBlock.Height() + 1, } ySlb, err := statelessblock.BuildUnsigned( gBlock.ID(), - gBlock.Timestamp(), + proVM.Time(), defaultPChainHeight, yBlock.Bytes(), ) @@ -1513,16 +1507,16 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { IDV: ids.GenerateTestID(), StatusV: choices.Processing, }, - BytesV: []byte{3}, - ParentV: yBlock.ID(), - HeightV: yBlock.Height() + 1, - TimestampV: yBlock.Timestamp(), + BytesV: []byte{3}, + ParentV: yBlock.ID(), + HeightV: yBlock.Height() + 1, } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { return zBlock, nil } require.NoError(proVM.SetPreference(context.Background(), bBlock.ID())) + proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) cBlock, err := proVM.BuildBlock(context.Background()) require.NoError(err) coreVM.BuildBlockF = nil @@ -1638,7 +1632,6 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1713,7 +1706,6 @@ func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, time.Time{}, 0) - proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() From c3668874a769c3f81c487420beba9e1fa3b02eec Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 5 Dec 2023 09:52:43 +0100 Subject: [PATCH 046/111] nit --- vms/proposervm/pre_fork_block_test.go | 38 ++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 4308f9ba05f1..35efbbaeaaa4 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -23,7 +23,6 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/block" - "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) func TestOracle_PreForkBlkImplementsInterface(t *testing.T) { @@ -242,7 +241,7 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require.True(coreGenBlk.Timestamp().Before(activationTime)) // create parent block ... - prntCoreBlk := &snowman.TestBlock{ + parentCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ IDV: ids.Empty.Prefix(1111), StatusV: choices.Processing, @@ -252,14 +251,14 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { TimestampV: coreGenBlk.Timestamp(), } coreVM.BuildBlockF = func(context.Context) (snowman.Block, error) { - return prntCoreBlk, nil + return parentCoreBlk, nil } coreVM.GetBlockF = func(_ context.Context, blkID ids.ID) (snowman.Block, error) { switch blkID { case coreGenBlk.ID(): return coreGenBlk, nil - case prntCoreBlk.ID(): - return prntCoreBlk, nil + case parentCoreBlk.ID(): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } @@ -268,15 +267,14 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { switch { case bytes.Equal(b, coreGenBlk.Bytes()): return coreGenBlk, nil - case bytes.Equal(b, prntCoreBlk.Bytes()): - return prntCoreBlk, nil + case bytes.Equal(b, parentCoreBlk.Bytes()): + return parentCoreBlk, nil default: return nil, database.ErrNotFound } } - proVM.Set(proVM.Time().Add(proposer.MaxBuildDelay)) - prntProBlk, err := proVM.BuildBlock(context.Background()) + parentBlk, err := proVM.BuildBlock(context.Background()) require.NoError(err) // .. create child block ... @@ -286,21 +284,25 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { StatusV: choices.Processing, }, BytesV: []byte{2}, - TimestampV: prntCoreBlk.Timestamp().Add(proposer.MaxVerifyDelay), + TimestampV: parentCoreBlk.Timestamp(), } - childProBlk := preForkBlock{ + childBlk := preForkBlock{ Block: childCoreBlk, vm: proVM, } - // child block referring unknown parent does not verify - childCoreBlk.ParentV = ids.Empty - err = childProBlk.Verify(context.Background()) - require.ErrorIs(err, database.ErrNotFound) + { + // child block referring unknown parent does not verify + childCoreBlk.ParentV = ids.Empty + err = childBlk.Verify(context.Background()) + require.ErrorIs(err, database.ErrNotFound) + } - // child block referring known parent does verify - childCoreBlk.ParentV = prntProBlk.ID() - require.NoError(childProBlk.Verify(context.Background())) + { + // child block referring known parent does verify + childCoreBlk.ParentV = parentBlk.ID() + require.NoError(childBlk.Verify(context.Background())) + } } func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { From 41ca1a0e57ed624496e20eb6667298f4978da0bf Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 5 Dec 2023 10:45:59 +0100 Subject: [PATCH 047/111] nit --- vms/proposervm/batched_vm_test.go | 6 ++-- vms/proposervm/post_fork_block_test.go | 48 +++++++++++++------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 983bddff0e93..b95a321f9ddf 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -962,9 +962,9 @@ func initTestRemoteProposerVM( IDV: ids.GenerateTestID(), StatusV: choices.Accepted, }, - HeightV: 0, - - BytesV: []byte{0}, + HeightV: 0, + TimestampV: genesisTimestamp, + BytesV: []byte{0}, } initialState := []byte("genesis state") diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 7e5a47433521..bcac87fc9116 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -254,7 +254,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, } - childProBlk := postForkBlock{ + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -277,9 +277,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errTimeNotMonotonic) } @@ -301,9 +301,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errProposerWindowNotStarted) } @@ -322,9 +322,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } { @@ -342,9 +342,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } { @@ -359,9 +359,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } { @@ -378,9 +378,9 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { proVM.StakingLeafSigner, ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errTimeTooAdvanced) } } @@ -456,7 +456,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { ParentV: parentCoreBlk.ID(), BytesV: []byte{2}, } - childProBlk := postForkBlock{ + childBlk := postForkBlock{ postForkCommonComponents: postForkCommonComponents{ vm: proVM, innerBlk: childCoreBlk, @@ -473,9 +473,9 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errPChainHeightNotMonotonic) } @@ -488,9 +488,9 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } { @@ -502,9 +502,9 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } currPChainHeight, _ := proVM.ctx.ValidatorState.GetCurrentHeight(context.Background()) @@ -517,9 +517,9 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - require.NoError(childProBlk.Verify(context.Background())) + require.NoError(childBlk.Verify(context.Background())) } { @@ -531,9 +531,9 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { childCoreBlk.Bytes(), ) require.NoError(err) - childProBlk.SignedBlock = childSlb + childBlk.SignedBlock = childSlb - err = childProBlk.Verify(context.Background()) + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errPChainHeightNotReached) } } From 005e9c8d5ed6ca51cbed46521ade50ea81fc99de Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 5 Dec 2023 14:22:41 +0100 Subject: [PATCH 048/111] fixed windowing seed --- vms/proposervm/post_fork_block_test.go | 5 +++ vms/proposervm/proposer/windower.go | 7 ++-- vms/proposervm/proposer/windower_test.go | 52 +----------------------- 3 files changed, 10 insertions(+), 54 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 79083380bc16..c95badc79760 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -374,6 +374,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { StatusV: choices.Processing, }, ParentV: parentCoreBlk.ID(), + HeightV: parentBlk.Height() + 1, BytesV: []byte{2}, } childBlk := postForkBlock{ @@ -465,6 +466,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { ) require.NoError(err) childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) } @@ -481,6 +483,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { ) require.NoError(err) childBlk.SignedBlock = childSlb + require.NoError(childBlk.Verify(context.Background())) } @@ -499,6 +502,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { ) require.NoError(err) childBlk.SignedBlock = childSlb + err = childBlk.Verify(context.Background()) require.ErrorIs(err, errTimeTooAdvanced) } @@ -575,6 +579,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { StatusV: choices.Processing, }, ParentV: parentCoreBlk.ID(), + HeightV: parentBlk.Height() + 1, BytesV: []byte{2}, } childBlk := postForkBlock{ diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 171960b87a94..61d94e673c27 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "math/bits" "time" "github.com/ava-labs/avalanchego/ids" @@ -118,10 +119,10 @@ func (w *windower) ExpectedProposer( var ( numToSample = 1 - slot = blockTime.Sub(parentBlockTime) / WindowDuration - seed = chainHeight ^ w.chainSource ^ uint64(slot) + slot = uint32(blockTime.Sub(parentBlockTime) / WindowDuration) + seed = int64(chainHeight ^ w.chainSource ^ uint64(bits.Reverse32(slot))) ) - w.sampler.Seed(int64(seed)) + w.sampler.Seed(seed) indices, err := w.sampler.Sample(numToSample) if err != nil { diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 4d95ae874570..f3835a2582b8 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -368,7 +368,7 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { blockTime = parentBlockTime.Add(WindowDuration) proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) require.NoError(err) - require.Equal(validatorIDs[4], proposerID) + require.Equal(validatorIDs[6], proposerID) } { @@ -379,53 +379,3 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { require.Equal(validatorIDs[9], proposerID) } } - -func TestExpectedProposerVariance(t *testing.T) { - require := require.New(t) - - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - - validatorsCount = 10 - ) - - validatorIDs := make([]ids.NodeID, validatorsCount) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) - - var ( - dummyCtx = context.Background() - pChainHeight = uint64(0) - parentBlockTime = time.Now().Truncate(time.Second) - - chainHeight = uint64(10) - blockTime = parentBlockTime.Add(time.Second) - ) - - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) - require.NoError(err) - require.Equal(validatorIDs[6], proposerID) - - chainHeight += 1 - blockTime = parentBlockTime.Add(WindowDuration).Add(time.Second) - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) - require.NoError(err) - require.Equal(validatorIDs[6], proposerID) -} From 6409beddddb31db1e41af0183e358ad466dac3f8 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 5 Dec 2023 15:44:06 +0100 Subject: [PATCH 049/111] fixed test --- vms/proposervm/post_fork_block_test.go | 28 ++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index bcac87fc9116..c0b3850b243f 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -16,6 +16,7 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowman" + "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/vms/proposervm/block" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" ) @@ -199,6 +200,25 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require.NoError(proVM.Shutdown(context.Background())) }() + // reduce validator state to allow proVM.ctx.NodeID to be easily selected as proposer + valState.GetValidatorSetF = func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + var ( + thisNode = proVM.ctx.NodeID + nodeID1 = ids.BuildTestNodeID([]byte{1}) + ) + return map[ids.NodeID]*validators.GetValidatorOutput{ + thisNode: { + NodeID: thisNode, + Weight: 5, + }, + nodeID1: { + NodeID: nodeID1, + Weight: 100, + }, + }, nil + } + proVM.ctx.ValidatorState = valState + pChainHeight := uint64(100) valState.GetCurrentHeightF = func(context.Context) (uint64, error) { return pChainHeight, nil @@ -244,7 +264,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require.NoError(parentBlk.Verify(context.Background())) require.NoError(proVM.SetPreference(context.Background(), parentBlk.ID())) - parentTimestamp := parentBlk.Timestamp() + var ( + parentTimestamp = parentBlk.Timestamp() + parentPChainHeight = parentBlk.(*postForkBlock).PChainHeight() + ) childCoreBlk := &snowman.TestBlock{ TestDecidable: choices.TestDecidable{ @@ -252,6 +275,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { StatusV: choices.Processing, }, ParentV: parentCoreBlk.ID(), + HeightV: parentCoreBlk.Height() + 1, BytesV: []byte{2}, } childBlk := postForkBlock{ @@ -283,7 +307,7 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require.ErrorIs(err, errTimeNotMonotonic) } - blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), pChainHeight, proVM.ctx.NodeID, proposer.MaxVerifyWindows) + blkWinDelay, err := proVM.Delay(context.Background(), childCoreBlk.Height(), parentPChainHeight, proVM.ctx.NodeID, proposer.MaxVerifyWindows) require.NoError(err) { From 75595dccd6d2b8343e8316f43de3096f0844021a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Wed, 6 Dec 2023 15:28:24 -0500 Subject: [PATCH 050/111] mega nits --- vms/proposervm/block_test.go | 8 ++++---- vms/proposervm/proposer/windower_test.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index fa7d4b082d15..35bd959a6679 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -37,10 +37,10 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { ctrl := gomock.NewController(t) var ( - pChainHeight = uint64(1337) - parentID = ids.GenerateTestID() - parentTimestamp = time.Now().Truncate(time.Second) - blkID = ids.GenerateTestID() + pChainHeight uint64 = 1337 + parentID = ids.GenerateTestID() + parentTimestamp = time.Now().Truncate(time.Second) + blkID = ids.GenerateTestID() ) innerBlk := snowman.NewMockBlock(ctrl) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 51e8beac67c9..854c7b737213 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -34,8 +34,8 @@ func TestWindowerNoValidators(t *testing.T) { w := New(vdrState, subnetID, chainID) var ( - chainHeight = uint64(1) - pChainHeight = uint64(0) + chainHeight uint64 = 1 + pChainHeight uint64 = 0 ) delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) From 60ea9dbcf7a3dba25fa5e6440c5d7209ea40c531 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Fri, 8 Dec 2023 13:45:53 +0100 Subject: [PATCH 051/111] fix merge --- vms/proposervm/proposer/windower.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 9be3440e1286..3bbfa074a4c8 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -120,7 +120,7 @@ func (w *windower) ExpectedProposer( var ( numToSample = 1 slot = uint32(blockTime.Sub(parentBlockTime) / WindowDuration) - seed = int64(chainHeight ^ w.chainSource ^ uint64(bits.Reverse32(slot))) + seed = chainHeight ^ w.chainSource ^ uint64(bits.Reverse32(slot)) ) w.sampler.Seed(seed) From 82656aafbc7542af406b17947ab3d6657762ea12 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 9 Dec 2023 22:30:42 -0500 Subject: [PATCH 052/111] Remove ClearSeed() --- utils/sampler/uniform.go | 1 - utils/sampler/uniform_replacer.go | 4 ---- utils/sampler/uniform_resample.go | 4 ---- utils/sampler/uniform_test.go | 5 ----- utils/sampler/weighted_without_replacement.go | 1 - 5 files changed, 15 deletions(-) diff --git a/utils/sampler/uniform.go b/utils/sampler/uniform.go index 262de753a6f7..00452ce8ae0e 100644 --- a/utils/sampler/uniform.go +++ b/utils/sampler/uniform.go @@ -12,7 +12,6 @@ type Uniform interface { Sample(length int) ([]uint64, error) Seed(uint64) - ClearSeed() Reset() Next() (uint64, error) diff --git a/utils/sampler/uniform_replacer.go b/utils/sampler/uniform_replacer.go index 8551907da7d1..5aa403899ef4 100644 --- a/utils/sampler/uniform_replacer.go +++ b/utils/sampler/uniform_replacer.go @@ -60,10 +60,6 @@ func (s *uniformReplacer) Seed(seed uint64) { s.rng.Seed(seed) } -func (s *uniformReplacer) ClearSeed() { - s.rng = globalRNG -} - func (s *uniformReplacer) Reset() { maps.Clear(s.drawn) s.drawsCount = 0 diff --git a/utils/sampler/uniform_resample.go b/utils/sampler/uniform_resample.go index ce3e41fe15c4..aa50d07bfc5d 100644 --- a/utils/sampler/uniform_resample.go +++ b/utils/sampler/uniform_resample.go @@ -47,10 +47,6 @@ func (s *uniformResample) Seed(seed uint64) { s.rng.Seed(seed) } -func (s *uniformResample) ClearSeed() { - s.rng = globalRNG -} - func (s *uniformResample) Reset() { maps.Clear(s.drawn) } diff --git a/utils/sampler/uniform_test.go b/utils/sampler/uniform_test.go index e5b00af31c26..cc1f71d89f89 100644 --- a/utils/sampler/uniform_test.go +++ b/utils/sampler/uniform_test.go @@ -179,11 +179,6 @@ func TestSeeding(t *testing.T) { v, err := s2.Next() require.NoError(err) require.NotEqual(s1Val, v) - - s1.ClearSeed() - - _, err = s1.Next() - require.NoError(err) } func TestSeedingProducesTheSame(t *testing.T) { diff --git a/utils/sampler/weighted_without_replacement.go b/utils/sampler/weighted_without_replacement.go index 1a3699613525..31cbf56af699 100644 --- a/utils/sampler/weighted_without_replacement.go +++ b/utils/sampler/weighted_without_replacement.go @@ -11,7 +11,6 @@ type WeightedWithoutReplacement interface { Sample(count int) ([]int, error) Seed(uint64) - ClearSeed() } // NewWeightedWithoutReplacement returns a new sampler From e37816eb528dbeb97e08a0e205c618472c365c0f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 9 Dec 2023 22:42:11 -0500 Subject: [PATCH 053/111] Remove rng switching --- utils/sampler/uniform.go | 6 +- utils/sampler/uniform_best.go | 8 ++- utils/sampler/uniform_replacer.go | 8 --- utils/sampler/uniform_resample.go | 14 +---- utils/sampler/uniform_test.go | 57 +++---------------- utils/sampler/weighted_without_replacement.go | 10 ++-- .../weighted_without_replacement_generic.go | 8 --- .../weighted_without_replacement_test.go | 4 +- vms/proposervm/proposer/windower.go | 11 ++-- 9 files changed, 33 insertions(+), 93 deletions(-) diff --git a/utils/sampler/uniform.go b/utils/sampler/uniform.go index 00452ce8ae0e..b4f7fb75d718 100644 --- a/utils/sampler/uniform.go +++ b/utils/sampler/uniform.go @@ -11,13 +11,13 @@ type Uniform interface { // negative the implementation may panic. Sample(length int) ([]uint64, error) - Seed(uint64) - Reset() Next() (uint64, error) } // NewUniform returns a new sampler func NewUniform() Uniform { - return &uniformReplacer{} + return &uniformReplacer{ + rng: globalRNG, + } } diff --git a/utils/sampler/uniform_best.go b/utils/sampler/uniform_best.go index 9ce1ed7f7187..69f78bd24ce8 100644 --- a/utils/sampler/uniform_best.go +++ b/utils/sampler/uniform_best.go @@ -29,8 +29,12 @@ type uniformBest struct { func NewBestUniform(expectedSampleSize int) Uniform { return &uniformBest{ samplers: []Uniform{ - &uniformReplacer{}, - &uniformResample{}, + &uniformReplacer{ + rng: globalRNG, + }, + &uniformResample{ + rng: globalRNG, + }, }, maxSampleSize: expectedSampleSize, benchmarkIterations: 100, diff --git a/utils/sampler/uniform_replacer.go b/utils/sampler/uniform_replacer.go index 5aa403899ef4..2053c22e875a 100644 --- a/utils/sampler/uniform_replacer.go +++ b/utils/sampler/uniform_replacer.go @@ -27,15 +27,12 @@ func (m defaultMap) get(key uint64, defaultVal uint64) uint64 { // Sampling is performed in O(count) time and O(count) space. type uniformReplacer struct { rng *rng - seededRNG *rng length uint64 drawn defaultMap drawsCount uint64 } func (s *uniformReplacer) Initialize(length uint64) { - s.rng = globalRNG - s.seededRNG = newRNG() s.length = length s.drawn = make(defaultMap) s.drawsCount = 0 @@ -55,11 +52,6 @@ func (s *uniformReplacer) Sample(count int) ([]uint64, error) { return results, nil } -func (s *uniformReplacer) Seed(seed uint64) { - s.rng = s.seededRNG - s.rng.Seed(seed) -} - func (s *uniformReplacer) Reset() { maps.Clear(s.drawn) s.drawsCount = 0 diff --git a/utils/sampler/uniform_resample.go b/utils/sampler/uniform_resample.go index aa50d07bfc5d..b2ddbdeb09df 100644 --- a/utils/sampler/uniform_resample.go +++ b/utils/sampler/uniform_resample.go @@ -15,15 +15,12 @@ import "golang.org/x/exp/maps" // // Sampling is performed in O(count) time and O(count) space. type uniformResample struct { - rng *rng - seededRNG *rng - length uint64 - drawn map[uint64]struct{} + rng *rng + length uint64 + drawn map[uint64]struct{} } func (s *uniformResample) Initialize(length uint64) { - s.rng = globalRNG - s.seededRNG = newRNG() s.length = length s.drawn = make(map[uint64]struct{}) } @@ -42,11 +39,6 @@ func (s *uniformResample) Sample(count int) ([]uint64, error) { return results, nil } -func (s *uniformResample) Seed(seed uint64) { - s.rng = s.seededRNG - s.rng.Seed(seed) -} - func (s *uniformResample) Reset() { maps.Clear(s.drawn) } diff --git a/utils/sampler/uniform_test.go b/utils/sampler/uniform_test.go index cc1f71d89f89..96aabb73be57 100644 --- a/utils/sampler/uniform_test.go +++ b/utils/sampler/uniform_test.go @@ -19,12 +19,16 @@ var ( sampler Uniform }{ { - name: "replacer", - sampler: &uniformReplacer{}, + name: "replacer", + sampler: &uniformReplacer{ + rng: globalRNG, + }, }, { - name: "resampler", - sampler: &uniformResample{}, + name: "resampler", + sampler: &uniformResample{ + rng: globalRNG, + }, }, { name: "best", @@ -156,48 +160,3 @@ func UniformLazilySample(t *testing.T, s Uniform) { s.Reset() } } - -func TestSeeding(t *testing.T) { - require := require.New(t) - - s1 := NewBestUniform(30) - s2 := NewBestUniform(30) - - s1.Initialize(50) - s2.Initialize(50) - - s1.Seed(0) - - s1.Reset() - s1Val, err := s1.Next() - require.NoError(err) - - s2.Seed(1) - s2.Reset() - - s1.Seed(0) - v, err := s2.Next() - require.NoError(err) - require.NotEqual(s1Val, v) -} - -func TestSeedingProducesTheSame(t *testing.T) { - require := require.New(t) - - s := NewBestUniform(30) - - s.Initialize(50) - - s.Seed(0) - s.Reset() - - val0, err := s.Next() - require.NoError(err) - - s.Seed(0) - s.Reset() - - val1, err := s.Next() - require.NoError(err) - require.Equal(val0, val1) -} diff --git a/utils/sampler/weighted_without_replacement.go b/utils/sampler/weighted_without_replacement.go index 31cbf56af699..134273577d8e 100644 --- a/utils/sampler/weighted_without_replacement.go +++ b/utils/sampler/weighted_without_replacement.go @@ -9,14 +9,16 @@ package sampler type WeightedWithoutReplacement interface { Initialize(weights []uint64) error Sample(count int) ([]int, error) - - Seed(uint64) } // NewWeightedWithoutReplacement returns a new sampler -func NewDeterministicWeightedWithoutReplacement() WeightedWithoutReplacement { +func NewDeterministicWeightedWithoutReplacement(seed uint64) WeightedWithoutReplacement { + rng := newRNG() + rng.Seed(seed) return &weightedWithoutReplacementGeneric{ - u: NewUniform(), + u: &uniformReplacer{ + rng: rng, + }, w: NewDeterministicWeighted(), } } diff --git a/utils/sampler/weighted_without_replacement_generic.go b/utils/sampler/weighted_without_replacement_generic.go index 5fefb826c46a..a62185146f4c 100644 --- a/utils/sampler/weighted_without_replacement_generic.go +++ b/utils/sampler/weighted_without_replacement_generic.go @@ -41,11 +41,3 @@ func (s *weightedWithoutReplacementGeneric) Sample(count int) ([]int, error) { } return indices, nil } - -func (s *weightedWithoutReplacementGeneric) Seed(seed uint64) { - s.u.Seed(seed) -} - -func (s *weightedWithoutReplacementGeneric) ClearSeed() { - s.u.ClearSeed() -} diff --git a/utils/sampler/weighted_without_replacement_test.go b/utils/sampler/weighted_without_replacement_test.go index fe2dadaeb5c6..79a26075605d 100644 --- a/utils/sampler/weighted_without_replacement_test.go +++ b/utils/sampler/weighted_without_replacement_test.go @@ -23,7 +23,9 @@ var ( { name: "generic with replacer and best", sampler: &weightedWithoutReplacementGeneric{ - u: &uniformReplacer{}, + u: &uniformReplacer{ + rng: globalRNG, + }, w: &weightedBest{ samplers: []Weighted{ &weightedArray{}, diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 12afc711cfc9..cfb1ef1e8346 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -57,7 +57,6 @@ type windower struct { state validators.State subnetID ids.ID chainSource uint64 - sampler sampler.WeightedWithoutReplacement } func New(state validators.State, subnetID, chainID ids.ID) Windower { @@ -66,7 +65,6 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { state: state, subnetID: subnetID, chainSource: w.UnpackLong(), - sampler: sampler.NewDeterministicWeightedWithoutReplacement(), } } @@ -103,7 +101,9 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint validatorWeights[i] = v.weight } - if err := w.sampler.Initialize(validatorWeights); err != nil { + seed := chainHeight ^ w.chainSource + sampler := sampler.NewDeterministicWeightedWithoutReplacement(seed) + if err := sampler.Initialize(validatorWeights); err != nil { return nil, err } @@ -112,10 +112,7 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint numToSample = int(weight) } - seed := chainHeight ^ w.chainSource - w.sampler.Seed(seed) - - indices, err := w.sampler.Sample(numToSample) + indices, err := sampler.Sample(numToSample) if err != nil { return nil, err } From 5375c51815df64323cc3faa04573caaf8d85bcfb Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 9 Dec 2023 22:50:33 -0500 Subject: [PATCH 054/111] Allow custom rng sources --- utils/sampler/rand.go | 27 +++++++------------ utils/sampler/weighted_without_replacement.go | 6 ++--- vms/proposervm/proposer/windower.go | 7 ++++- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/utils/sampler/rand.go b/utils/sampler/rand.go index 1b335f718be0..b0ef8ee0f443 100644 --- a/utils/sampler/rand.go +++ b/utils/sampler/rand.go @@ -11,36 +11,29 @@ import ( "gonum.org/v1/gonum/mathext/prng" ) -var globalRNG = newRNG() +var globalRNG *rng -func newRNG() *rng { +func init() { // We don't use a cryptographically secure source of randomness here, as // there's no need to ensure a truly random sampling. source := prng.NewMT19937() source.Seed(uint64(time.Now().UnixNano())) - return &rng{rng: source} -} - -func Seed(seed uint64) { - globalRNG.Seed(seed) + globalRNG = newRNG(source) } -type source interface { - Seed(uint64) - Uint64() uint64 +func newRNG(source Source) *rng { + return &rng{rng: source} } type rng struct { lock sync.Mutex - rng source + rng Source } -// Seed uses the provided seed value to initialize the generator to a -// deterministic state. -func (r *rng) Seed(seed uint64) { - r.lock.Lock() - r.rng.Seed(seed) - r.lock.Unlock() +type Source interface { + // Uint64 returns a random number in [0, MaxUint64] and advances the + // generator's state. + Uint64() uint64 } // Uint64Inclusive returns a pseudo-random number in [0,n]. diff --git a/utils/sampler/weighted_without_replacement.go b/utils/sampler/weighted_without_replacement.go index 134273577d8e..1124c3d180c7 100644 --- a/utils/sampler/weighted_without_replacement.go +++ b/utils/sampler/weighted_without_replacement.go @@ -12,12 +12,10 @@ type WeightedWithoutReplacement interface { } // NewWeightedWithoutReplacement returns a new sampler -func NewDeterministicWeightedWithoutReplacement(seed uint64) WeightedWithoutReplacement { - rng := newRNG() - rng.Seed(seed) +func NewDeterministicWeightedWithoutReplacement(source Source) WeightedWithoutReplacement { return &weightedWithoutReplacementGeneric{ u: &uniformReplacer{ - rng: rng, + rng: newRNG(source), }, w: NewDeterministicWeighted(), } diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index cfb1ef1e8346..9abfbcfd60d4 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -7,6 +7,8 @@ import ( "context" "time" + "gonum.org/v1/gonum/mathext/prng" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" "github.com/ava-labs/avalanchego/utils" @@ -102,7 +104,10 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint } seed := chainHeight ^ w.chainSource - sampler := sampler.NewDeterministicWeightedWithoutReplacement(seed) + + source := prng.NewMT19937() + source.Seed(seed) + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) if err := sampler.Initialize(validatorWeights); err != nil { return nil, err } From b864f6b1bc88af19e5b71498227f7062fc6c94ec Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sat, 9 Dec 2023 23:48:38 -0500 Subject: [PATCH 055/111] Fix tests --- .../snowball/consensus_performance_test.go | 36 +++++------ .../snowball/consensus_reversibility_test.go | 8 +-- snow/consensus/snowball/network_test.go | 28 +++++---- snow/consensus/snowball/tree_test.go | 12 ++-- snow/consensus/snowman/consensus_test.go | 11 ++-- snow/consensus/snowman/network_test.go | 63 ++++++++++--------- utils/sampler/rand.go | 8 +-- utils/sampler/uniform.go | 9 +++ utils/sampler/weighted_without_replacement.go | 4 +- 9 files changed, 95 insertions(+), 84 deletions(-) diff --git a/snow/consensus/snowball/consensus_performance_test.go b/snow/consensus/snowball/consensus_performance_test.go index bd2752a2ec5c..febb7c6877e6 100644 --- a/snow/consensus/snowball/consensus_performance_test.go +++ b/snow/consensus/snowball/consensus_performance_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/utils/sampler" + "gonum.org/v1/gonum/mathext/prng" ) // Test that a network running the lower AlphaPreference converges faster than a @@ -26,29 +26,28 @@ func TestDualAlphaOptimization(t *testing.T) { BetaVirtuous: 15, BetaRogue: 20, } - seed uint64 = 0 + seed uint64 = 0 + source = prng.NewMT19937() ) - singleAlphaNetwork := Network{} - singleAlphaNetwork.Initialize(params, numColors) + singleAlphaNetwork := NewNetwork(params, numColors, source) params.AlphaPreference = params.K/2 + 1 - dualAlphaNetwork := Network{} - dualAlphaNetwork.Initialize(params, numColors) + dualAlphaNetwork := NewNetwork(params, numColors, source) - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { dualAlphaNetwork.AddNode(NewTree) } - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { singleAlphaNetwork.AddNode(NewTree) } // Although this can theoretically fail with a correct implementation, it // shouldn't in practice - runNetworksInLockstep(require, seed, &dualAlphaNetwork, &singleAlphaNetwork) + runNetworksInLockstep(require, seed, source, dualAlphaNetwork, singleAlphaNetwork) } // Test that a network running the snowball tree converges faster than a network @@ -61,35 +60,34 @@ func TestTreeConvergenceOptimization(t *testing.T) { numNodes = 100 params = DefaultParameters seed uint64 = 0 + source = prng.NewMT19937() ) - treeNetwork := Network{} - treeNetwork.Initialize(params, numColors) + treeNetwork := NewNetwork(params, numColors, source) + flatNetwork := NewNetwork(params, numColors, source) - flatNetwork := treeNetwork - - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { treeNetwork.AddNode(NewTree) } - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numNodes; i++ { flatNetwork.AddNode(NewFlat) } // Although this can theoretically fail with a correct implementation, it // shouldn't in practice - runNetworksInLockstep(require, seed, &treeNetwork, &flatNetwork) + runNetworksInLockstep(require, seed, source, treeNetwork, flatNetwork) } -func runNetworksInLockstep(require *require.Assertions, seed uint64, fast *Network, slow *Network) { +func runNetworksInLockstep(require *require.Assertions, seed uint64, source *prng.MT19937, fast *Network, slow *Network) { numRounds := 0 for !fast.Finalized() && !fast.Disagreement() && !slow.Finalized() && !slow.Disagreement() { - sampler.Seed(uint64(numRounds) + seed) + source.Seed(uint64(numRounds) + seed) fast.Round() - sampler.Seed(uint64(numRounds) + seed) + source.Seed(uint64(numRounds) + seed) slow.Round() numRounds++ } diff --git a/snow/consensus/snowball/consensus_reversibility_test.go b/snow/consensus/snowball/consensus_reversibility_test.go index 48d35cc7dde5..a3c5d3e98690 100644 --- a/snow/consensus/snowball/consensus_reversibility_test.go +++ b/snow/consensus/snowball/consensus_reversibility_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" - "github.com/ava-labs/avalanchego/utils/sampler" + "gonum.org/v1/gonum/mathext/prng" ) func TestSnowballGovernance(t *testing.T) { @@ -21,12 +21,12 @@ func TestSnowballGovernance(t *testing.T) { numRed = 55 params = DefaultParameters seed uint64 = 0 + source = prng.NewMT19937() ) - nBitwise := Network{} - nBitwise.Initialize(params, numColors) + nBitwise := NewNetwork(params, numColors, source) - sampler.Seed(seed) + source.Seed(seed) for i := 0; i < numRed; i++ { nBitwise.AddNodeSpecificColor(NewTree, 0, []int{1}) } diff --git a/snow/consensus/snowball/network_test.go b/snow/consensus/snowball/network_test.go index 711bbf89010e..747b51087926 100644 --- a/snow/consensus/snowball/network_test.go +++ b/snow/consensus/snowball/network_test.go @@ -4,10 +4,9 @@ package snowball import ( - "math/rand" - "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/bag" + "github.com/ava-labs/avalanchego/utils/math" "github.com/ava-labs/avalanchego/utils/sampler" ) @@ -16,20 +15,24 @@ type newConsensusFunc func(params Parameters, choice ids.ID) Consensus type Network struct { params Parameters colors []ids.ID + rngSource sampler.Source nodes, running []Consensus } -// Initialize sets the parameters for the network and adds [numColors] different -// possible colors to the network configuration. -func (n *Network) Initialize(params Parameters, numColors int) { - n.params = params +// Create a new network with [numColors] different possible colors to finalize. +func NewNetwork(params Parameters, numColors int, rngSource sampler.Source) *Network { + n := &Network{ + params: params, + rngSource: rngSource, + } for i := 0; i < numColors; i++ { n.colors = append(n.colors, ids.Empty.Prefix(uint64(i))) } + return n } func (n *Network) AddNode(newConsensusFunc newConsensusFunc) Consensus { - s := sampler.NewUniform() + s := sampler.NewDeterministicUniform(n.rngSource) s.Initialize(uint64(len(n.colors))) indices, _ := s.Sample(len(n.colors)) @@ -78,15 +81,14 @@ func (n *Network) Finalized() bool { // performing an unbiased poll of the nodes in the network for that node. func (n *Network) Round() { if len(n.running) > 0 { - runningInd := rand.Intn(len(n.running)) // #nosec G404 + s := sampler.NewDeterministicUniform(n.rngSource) + + s.Initialize(uint64(len(n.running))) + runningInd, _ := s.Next() running := n.running[runningInd] - s := sampler.NewUniform() s.Initialize(uint64(len(n.nodes))) - count := len(n.nodes) - if count > n.params.K { - count = n.params.K - } + count := math.Min(n.params.K, len(n.nodes)) indices, _ := s.Sample(count) sampledColors := bag.Bag[ids.ID]{} for _, index := range indices { diff --git a/snow/consensus/snowball/tree_test.go b/snow/consensus/snowball/tree_test.go index 8517a8559fcc..39252ea01624 100644 --- a/snow/consensus/snowball/tree_test.go +++ b/snow/consensus/snowball/tree_test.go @@ -10,9 +10,10 @@ import ( "github.com/stretchr/testify/require" + "gonum.org/v1/gonum/mathext/prng" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/utils/bag" - "github.com/ava-labs/avalanchego/utils/sampler" ) const initialUnaryDescription = "SB(PreferenceStrength = 0, SF(Confidence = 0, Finalized = false)) Bits = [0, 256)" @@ -806,14 +807,13 @@ func TestSnowballConsistent(t *testing.T) { BetaVirtuous: 20, BetaRogue: 30, } - seed uint64 = 0 + seed uint64 = 0 + source = prng.NewMT19937() ) - sampler.Seed(seed) - - n := Network{} - n.Initialize(params, numColors) + n := NewNetwork(params, numColors, source) + source.Seed(seed) for i := 0; i < numNodes; i++ { n.AddNode(NewTree) } diff --git a/snow/consensus/snowman/consensus_test.go b/snow/consensus/snowman/consensus_test.go index 024a8f69974d..a7558e67034d 100644 --- a/snow/consensus/snowman/consensus_test.go +++ b/snow/consensus/snowman/consensus_test.go @@ -17,12 +17,13 @@ import ( "github.com/stretchr/testify/require" + "gonum.org/v1/gonum/mathext/prng" + "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" "github.com/ava-labs/avalanchego/snow/choices" "github.com/ava-labs/avalanchego/snow/consensus/snowball" "github.com/ava-labs/avalanchego/utils/bag" - "github.com/ava-labs/avalanchego/utils/sampler" ) type testFunc func(*testing.T, Factory) @@ -1599,13 +1600,13 @@ func RandomizedConsistencyTest(t *testing.T, factory Factory) { MaxOutstandingItems: 1, MaxItemProcessingTime: 1, } - seed uint64 = 0 + seed uint64 = 0 + source = prng.NewMT19937() ) - sampler.Seed(seed) + source.Seed(seed) - n := Network{} - n.Initialize(params, numColors) + n := NewNetwork(params, numColors, source) for i := 0; i < numNodes; i++ { require.NoError(n.AddNode(factory.New())) diff --git a/snow/consensus/snowman/network_test.go b/snow/consensus/snowman/network_test.go index ae855ab84ac6..f6e734f3cbce 100644 --- a/snow/consensus/snowman/network_test.go +++ b/snow/consensus/snowman/network_test.go @@ -5,7 +5,6 @@ package snowman import ( "context" - "math/rand" "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow" @@ -19,45 +18,51 @@ import ( type Network struct { params snowball.Parameters colors []*TestBlock + rngSource sampler.Source nodes, running []Consensus } -func (n *Network) shuffleColors() { - s := sampler.NewUniform() - s.Initialize(uint64(len(n.colors))) - indices, _ := s.Sample(len(n.colors)) - colors := []*TestBlock(nil) - for _, index := range indices { - colors = append(colors, n.colors[int(index)]) +func NewNetwork(params snowball.Parameters, numColors int, rngSource sampler.Source) *Network { + n := &Network{ + params: params, + colors: []*TestBlock{{ + TestDecidable: choices.TestDecidable{ + IDV: ids.Empty.Prefix(rngSource.Uint64()), + StatusV: choices.Processing, + }, + ParentV: Genesis.IDV, + HeightV: 1, + }}, + rngSource: rngSource, } - n.colors = colors - utils.Sort(n.colors) -} - -func (n *Network) Initialize(params snowball.Parameters, numColors int) { - n.params = params - // #nosec G404 - n.colors = append(n.colors, &TestBlock{ - TestDecidable: choices.TestDecidable{ - IDV: ids.Empty.Prefix(uint64(rand.Int63())), - StatusV: choices.Processing, - }, - ParentV: Genesis.IDV, - HeightV: 1, - }) + s := sampler.NewDeterministicUniform(n.rngSource) for i := 1; i < numColors; i++ { - dependency := n.colors[rand.Intn(len(n.colors))] // #nosec G404 - // #nosec G404 + s.Initialize(uint64(len(n.colors))) + dependencyInd, _ := s.Next() + dependency := n.colors[dependencyInd] n.colors = append(n.colors, &TestBlock{ TestDecidable: choices.TestDecidable{ - IDV: ids.Empty.Prefix(uint64(rand.Int63())), + IDV: ids.Empty.Prefix(rngSource.Uint64()), StatusV: choices.Processing, }, ParentV: dependency.IDV, HeightV: dependency.HeightV + 1, }) } + return n +} + +func (n *Network) shuffleColors() { + s := sampler.NewDeterministicUniform(n.rngSource) + s.Initialize(uint64(len(n.colors))) + indices, _ := s.Sample(len(n.colors)) + colors := []*TestBlock(nil) + for _, index := range indices { + colors = append(colors, n.colors[int(index)]) + } + n.colors = colors + utils.Sort(n.colors) } func (n *Network) AddNode(sm Consensus) error { @@ -101,10 +106,12 @@ func (n *Network) Round() error { return nil } - runningInd := rand.Intn(len(n.running)) // #nosec G404 + s := sampler.NewDeterministicUniform(n.rngSource) + s.Initialize(uint64(len(n.running))) + + runningInd, _ := s.Next() running := n.running[runningInd] - s := sampler.NewUniform() s.Initialize(uint64(len(n.nodes))) indices, _ := s.Sample(n.params.K) sampledColors := bag.Bag[ids.ID]{} diff --git a/utils/sampler/rand.go b/utils/sampler/rand.go index b0ef8ee0f443..0dc347dad659 100644 --- a/utils/sampler/rand.go +++ b/utils/sampler/rand.go @@ -11,17 +11,13 @@ import ( "gonum.org/v1/gonum/mathext/prng" ) -var globalRNG *rng +var globalRNG = newRNG() -func init() { +func newRNG() *rng { // We don't use a cryptographically secure source of randomness here, as // there's no need to ensure a truly random sampling. source := prng.NewMT19937() source.Seed(uint64(time.Now().UnixNano())) - globalRNG = newRNG(source) -} - -func newRNG(source Source) *rng { return &rng{rng: source} } diff --git a/utils/sampler/uniform.go b/utils/sampler/uniform.go index b4f7fb75d718..e673aefa2616 100644 --- a/utils/sampler/uniform.go +++ b/utils/sampler/uniform.go @@ -21,3 +21,12 @@ func NewUniform() Uniform { rng: globalRNG, } } + +// NewDeterministicUniform returns a new sampler +func NewDeterministicUniform(source Source) Uniform { + return &uniformReplacer{ + rng: &rng{ + rng: source, + }, + } +} diff --git a/utils/sampler/weighted_without_replacement.go b/utils/sampler/weighted_without_replacement.go index 1124c3d180c7..2f592a783bc0 100644 --- a/utils/sampler/weighted_without_replacement.go +++ b/utils/sampler/weighted_without_replacement.go @@ -14,9 +14,7 @@ type WeightedWithoutReplacement interface { // NewWeightedWithoutReplacement returns a new sampler func NewDeterministicWeightedWithoutReplacement(source Source) WeightedWithoutReplacement { return &weightedWithoutReplacementGeneric{ - u: &uniformReplacer{ - rng: newRNG(source), - }, + u: NewDeterministicUniform(source), w: NewDeterministicWeighted(), } } From a7231aff0cb07855e8c5ccbd2cf2a9f84603a6e1 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 00:23:34 -0500 Subject: [PATCH 056/111] Address comments --- vms/proposervm/batched_vm_test.go | 6 +- vms/proposervm/block_test.go | 12 +-- vms/proposervm/post_fork_block_test.go | 72 +++++++------- vms/proposervm/post_fork_option_test.go | 36 +++---- vms/proposervm/pre_fork_block_test.go | 54 +++++----- vms/proposervm/proposer/windower.go | 71 +++++++------- vms/proposervm/proposer/windower_test.go | 10 +- vms/proposervm/state_syncable_vm_test.go | 6 +- vms/proposervm/vm_byzantine_test.go | 36 +++---- vms/proposervm/vm_test.go | 120 +++++++++++------------ 10 files changed, 211 insertions(+), 212 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index edb62920c171..37bcd05cc885 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -29,10 +29,10 @@ func TestCoreVMNotRemote(t *testing.T) { // if coreVM is not remote VM, a specific error is returned require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 2240cb88ba55..bdadba8da619 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -107,10 +107,10 @@ func TestPreDurangoValidatorNodeBlockBuiltDelaysTests(t *testing.T) { ctx := context.Background() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() @@ -244,10 +244,10 @@ func TestPreDurangoNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { ctx := context.Background() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(ctx)) }() diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index 11494d1ed934..e9e05f0e209d 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -41,10 +41,10 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { // setup var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -101,10 +101,10 @@ func TestBlockVerify_PostForkBlock_PreDurango_ParentChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime // pre Durango + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime // pre Durango ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -205,10 +205,10 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) // post Durango + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) // post Durango ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -314,10 +314,10 @@ func TestBlockVerify_PostForkBlock_TimestampChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -535,10 +535,10 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -706,10 +706,10 @@ func TestBlockVerify_PostForkBlockBuiltOnOption_PChainHeightChecks(t *testing.T) require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -906,10 +906,10 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify a block once (in this test by building it). // Show that other verify call would not call coreBlk.Verify() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -973,10 +973,10 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { // setup var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1040,10 +1040,10 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1091,10 +1091,10 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1127,10 +1127,10 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1245,10 +1245,10 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 5) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 5) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index b2eec7520a33..a69769e63e05 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -37,10 +37,10 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -156,10 +156,10 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -261,10 +261,10 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -374,10 +374,10 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -479,10 +479,10 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -567,10 +567,10 @@ func TestOptionTimestampValidity(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoTime, 0) coreOracleBlkID := ids.GenerateTestID() coreOracleBlk := &TestOptionsBlock{ diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 61cc064b615e..3dc233a3e9a7 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -51,10 +51,10 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = time.Unix(0, 0) + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -143,10 +143,10 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = time.Unix(0, 0) + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -240,10 +240,10 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = time.Unix(0, 0) + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -319,10 +319,10 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = time.Unix(0, 0) + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -453,10 +453,10 @@ func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(-1 * time.Second) - durangoForkTime = time.Unix(0, 0) + activationTime = genesisTimestamp.Add(-1 * time.Second) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(activationTime) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -498,10 +498,10 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { // setup var ( - activationTime = mockable.MaxTime - durangoForkTime = time.Unix(0, 0) + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -560,10 +560,10 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = time.Unix(0, 0) + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -595,10 +595,10 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = time.Unix(0, 0) + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -689,10 +689,10 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { require := require.New(t) var ( - activationTime = genesisTimestamp.Add(10 * time.Second) - durangoForkTime = time.Unix(0, 0) + activationTime = genesisTimestamp.Add(10 * time.Second) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index e1fade110783..f735168c5e3d 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -102,29 +102,25 @@ func (w *windower) ExpectedProposer( blockTime, parentBlockTime time.Time, ) (ids.NodeID, error) { - validators, _, err := w.sortedValidators(ctx, pChainHeight) + validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { return ids.EmptyNodeID, err } - // convert the slice of validators to a slice of weights - validatorWeights := make([]uint64, len(validators)) - for i, v := range validators { - validatorWeights[i] = v.weight - } + var ( + slot = uint64(blockTime.Sub(parentBlockTime) / WindowDuration) + seed = chainHeight ^ bits.Reverse64(slot) ^ w.chainSource + source = prng.NewMT19937_64() + validatorWeights = validatorsToWeight(validators) + ) - if err := w.sampler.Initialize(validatorWeights); err != nil { + source.Seed(seed) + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) + if err := sampler.Initialize(validatorWeights); err != nil { return ids.EmptyNodeID, err } - var ( - numToSample = 1 - slot = uint32(blockTime.Sub(parentBlockTime) / WindowDuration) - seed = chainHeight ^ w.chainSource ^ uint64(bits.Reverse32(slot)) - ) - w.sampler.Seed(seed) - - indices, err := w.sampler.Sample(numToSample) + indices, err := sampler.Sample(1) if err != nil { return ids.EmptyNodeID, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) } @@ -136,31 +132,32 @@ func (w *windower) ExpectedProposer( // in order. The minimum delay of a validator is the index they appear times // [WindowDuration]. func (w *windower) proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { - validators, totalWeight, err := w.sortedValidators(ctx, pChainHeight) + validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { return nil, err } - // convert the slice of validators to a slice of weights - validatorWeights := make([]uint64, len(validators)) - for i, v := range validators { - validatorWeights[i] = v.weight - } - - seed := chainHeight ^ w.chainSource + var ( + seed = chainHeight ^ w.chainSource + source = prng.NewMT19937() + validatorWeights = validatorsToWeight(validators) + ) - source := prng.NewMT19937() source.Seed(seed) sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) if err := sampler.Initialize(validatorWeights); err != nil { return nil, err } - numToSample := maxWindows - if totalWeight < uint64(numToSample) { - numToSample = int(totalWeight) + var totalWeight uint64 + for _, weight := range validatorWeights { + totalWeight, err = math.Add64(totalWeight, weight) + if err != nil { + return nil, err + } } + numToSample := int(math.Min(uint64(maxWindows), totalWeight)) indices, err := sampler.Sample(numToSample) if err != nil { return nil, err @@ -173,26 +170,20 @@ func (w *windower) proposers(ctx context.Context, chainHeight, pChainHeight uint return nodeIDs, nil } -func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, uint64, error) { +func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, error) { // get the validator set by the p-chain height validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) if err != nil { - return nil, 0, err + return nil, err } // convert the map of validators to a slice validators := make([]validatorData, 0, len(validatorsMap)) - totalWeight := uint64(0) for k, v := range validatorsMap { validators = append(validators, validatorData{ id: k, weight: v.Weight, }) - newWeight, err := math.Add64(totalWeight, v.Weight) - if err != nil { - return nil, 0, err - } - totalWeight = newWeight } // canonically sort validators @@ -200,5 +191,13 @@ func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([ // canonically sorted list utils.Sort(validators) - return validators, totalWeight, nil + return validators, nil +} + +func validatorsToWeight(validators []validatorData) []uint64 { + weights := make([]uint64, len(validators)) + for i, validator := range validators { + weights[i] = validator.weight + } + return weights } diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 56d717dd636d..ab869eca9b55 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -248,12 +248,12 @@ func TestExpectedProposerChangeByHeight(t *testing.T) { proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) require.NoError(err) - require.Equal(validatorIDs[6], proposerID) + require.Equal(validatorIDs[2], proposerID) chainHeight = 2 proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) require.NoError(err) - require.Equal(validatorIDs[4], proposerID) + require.Equal(validatorIDs[1], proposerID) } func TestExpectedProposerChangeByChain(t *testing.T) { @@ -353,14 +353,14 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) require.NoError(err) - require.Equal(validatorIDs[6], proposerID) + require.Equal(validatorIDs[2], proposerID) { // proposerID won't change within the same slot blockTime = parentBlockTime.Add(WindowDuration).Add(-1 * time.Second) proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) require.NoError(err) - require.Equal(validatorIDs[6], proposerID) + require.Equal(validatorIDs[2], proposerID) } { @@ -368,7 +368,7 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { blockTime = parentBlockTime.Add(WindowDuration) proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) require.NoError(err) - require.Equal(validatorIDs[6], proposerID) + require.Equal(validatorIDs[0], proposerID) } { diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 4bf3a61c54db..3b761d708209 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -603,10 +603,10 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { // Note: by default proVM is built such that heightIndex will be considered complete var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index 10b37b48d386..b52c7310e7eb 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -33,10 +33,10 @@ func TestInvalidByzantineProposerParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -104,10 +104,10 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -213,10 +213,10 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -303,10 +303,10 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -403,10 +403,10 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) defer func() { require.NoError(proVM.Shutdown(context.Background())) @@ -587,10 +587,10 @@ func TestGetBlock_MutatedSignature(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 74c87fcf8b5e..ee56936f4885 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -246,10 +246,10 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -282,10 +282,10 @@ func TestBuildBlockIsIdempotent(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -320,10 +320,10 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { // setup var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -357,10 +357,10 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -453,10 +453,10 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -550,10 +550,10 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -592,10 +592,10 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -668,10 +668,10 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -738,10 +738,10 @@ func TestPreFork_Initialize(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = time.Unix(0, 0) + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) - _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -761,10 +761,10 @@ func TestPreFork_BuildBlock(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = time.Unix(0, 0) + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -803,10 +803,10 @@ func TestPreFork_ParseBlock(t *testing.T) { // setup var ( - activationTime = mockable.MaxTime - durangoForkTime = time.Unix(0, 0) + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -842,10 +842,10 @@ func TestPreFork_SetPreference(t *testing.T) { require := require.New(t) var ( - activationTime = mockable.MaxTime - durangoForkTime = time.Unix(0, 0) + activationTime = mockable.MaxTime + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1119,10 +1119,10 @@ func TestInnerBlockDeduplication(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1425,10 +1425,10 @@ func TestBuildBlockDuringWindow(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1530,10 +1530,10 @@ func TestTwoForks_OneIsAccepted(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1627,10 +1627,10 @@ func TestTooFarAdvanced(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1721,10 +1721,10 @@ func TestTwoOptions_OneIsAccepted(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = mockable.MaxTime + activationTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -1799,10 +1799,10 @@ func TestLaggedPChainHeight(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2370,10 +2370,10 @@ func TestVMInnerBlkCache(t *testing.T) { func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() @@ -2449,10 +2449,10 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) var ( - activationTime = time.Unix(0, 0) - durangoForkTime = time.Unix(0, 0) + activationTime = time.Unix(0, 0) + durangoTime = time.Unix(0, 0) ) - coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoForkTime, 0) + coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { require.NoError(proVM.Shutdown(context.Background())) }() From 2fcfea718780850a8d8330e06040c6f092de0f26 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 00:27:30 -0500 Subject: [PATCH 057/111] nit --- vms/proposervm/batched_vm_test.go | 4 ++-- vms/proposervm/pre_fork_block_test.go | 6 +++--- vms/proposervm/vm_test.go | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 37bcd05cc885..839fa3310c81 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -59,7 +59,7 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { @@ -571,7 +571,7 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 3dc233a3e9a7..962f1812a263 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -52,7 +52,7 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -499,7 +499,7 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { // setup var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -561,7 +561,7 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index ee56936f4885..48b465929e88 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -739,7 +739,7 @@ func TestPreFork_Initialize(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -762,7 +762,7 @@ func TestPreFork_BuildBlock(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -804,7 +804,7 @@ func TestPreFork_ParseBlock(t *testing.T) { // setup var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -843,7 +843,7 @@ func TestPreFork_SetPreference(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = time.Unix(0, 0) + durangoTime = mockable.MaxTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { From 790215eacb8ffd28fb3ef07785300837693abe25 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 00:28:57 -0500 Subject: [PATCH 058/111] nit --- vms/proposervm/batched_vm_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 839fa3310c81..9505d9d520d7 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -367,7 +367,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - durangoTime = time.Unix(0, 0) + durangoTime = currentTime.Add(10 * time.Minute) ) // enable ProBlks in next future @@ -808,7 +808,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - durangoTime = time.Unix(0, 0) + durangoTime = currentTime.Add(10 * time.Minute) ) // enable ProBlks in next future From d120dd6a9c50ea87d7805f4f2721a6ab93e76062 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 00:37:24 -0500 Subject: [PATCH 059/111] nit --- vms/proposervm/block.go | 61 +++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 6c32c475d71c..628a312026be 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -205,16 +205,15 @@ func (p *postForkCommonComponents) buildChild( shouldBuildUnsignedBlock := false if p.vm.IsDurangoActivated(parentTimestamp) { - parentHeight := p.innerBlk.Height() - err = p.shouldPostDurangoBuildBlock( + err = p.shouldBuildBlockPostDurango( ctx, + parentID, parentTimestamp, - parentHeight, parentPChainHeight, newTimestamp, ) } else { - shouldBuildUnsignedBlock, err = p.shouldPreDurangoBuildUnsignedBlock( + shouldBuildUnsignedBlock, err = p.shouldBuildUnsignedBlockPreDurango( ctx, parentID, parentTimestamp, @@ -337,7 +336,13 @@ func (p *postForkCommonComponents) verifyPreDurangoBlockDelay( childHeight = blk.Height() proposerID = blk.Proposer() ) - minDelay, err := p.vm.Windower.Delay(ctx, childHeight, parentPChainHeight, proposerID, proposer.MaxVerifyWindows) + minDelay, err := p.vm.Windower.Delay( + ctx, + childHeight, + parentPChainHeight, + proposerID, + proposer.MaxVerifyWindows, + ) if err != nil { return 0, err } @@ -379,13 +384,14 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( return nil } -func (p *postForkCommonComponents) shouldPostDurangoBuildBlock( +func (p *postForkCommonComponents) shouldBuildBlockPostDurango( ctx context.Context, + parentID ids.ID, parentTimestamp time.Time, - parentHeight uint64, parentPChainHeight uint64, newTimestamp time.Time, ) error { + parentHeight := p.innerBlk.Height() expectedProposerID, err := p.vm.Windower.ExpectedProposer( ctx, parentHeight+1, @@ -394,16 +400,33 @@ func (p *postForkCommonComponents) shouldPostDurangoBuildBlock( parentTimestamp, ) if err != nil { + p.vm.ctx.Log.Error("unexpected build block failure", + zap.String("reason", "failed to calculate expected proposer"), + zap.Stringer("parentID", parentID), + zap.Error(err), + ) return err } - if expectedProposerID != p.vm.ctx.NodeID { - return errProposerWindowNotStarted + if expectedProposerID == p.vm.ctx.NodeID { + return nil } - return nil + // It's not our turn to propose a block yet. This is likely caused by having + // previously notified the consensus engine to attempt to build a block on + // top of a block that is no longer the preferred block. + p.vm.ctx.Log.Debug("build block dropped", + zap.Time("parentTimestamp", parentTimestamp), + zap.Time("blockTimestamp", newTimestamp), + zap.Stringer("expectedProposer", expectedProposerID), + ) + + // In case the inner VM only issued one pendingTxs message, we should + // attempt to re-handle that once it is our turn to build the block. + p.vm.notifyInnerBlockReady() + return errProposerWindowNotStarted } -func (p *postForkCommonComponents) shouldPreDurangoBuildUnsignedBlock( +func (p *postForkCommonComponents) shouldBuildUnsignedBlockPreDurango( ctx context.Context, parentID ids.ID, parentTimestamp time.Time, @@ -429,24 +452,22 @@ func (p *postForkCommonComponents) shouldPreDurangoBuildUnsignedBlock( } if delay >= minDelay { - // it's time for this node to propose a block. It'll be signed or unsigned - // depending on the delay + // it's time for this node to propose a block. It'll be signed or + // unsigned depending on the delay return delay >= proposer.MaxVerifyDelay, nil } - // It's not our turn to propose a block yet. This is likely caused - // by having previously notified the consensus engine to attempt to - // build a block on top of a block that is no longer the preferred - // block. + // It's not our turn to propose a block yet. This is likely caused by having + // previously notified the consensus engine to attempt to build a block on + // top of a block that is no longer the preferred block. p.vm.ctx.Log.Debug("build block dropped", zap.Time("parentTimestamp", parentTimestamp), zap.Duration("minDelay", minDelay), zap.Time("blockTimestamp", newTimestamp), ) - // In case the inner VM only issued one pendingTxs message, we - // should attempt to re-handle that once it is our turn to build the - // block. + // In case the inner VM only issued one pendingTxs message, we should + // attempt to re-handle that once it is our turn to build the block. p.vm.notifyInnerBlockReady() return false, errProposerWindowNotStarted } From e72b46b9cc46fbfe797a37d0d3a2194d153e6914 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 00:41:25 -0500 Subject: [PATCH 060/111] nit --- vms/proposervm/block.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 628a312026be..3b045e7783f4 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -344,6 +344,11 @@ func (p *postForkCommonComponents) verifyPreDurangoBlockDelay( proposer.MaxVerifyWindows, ) if err != nil { + p.vm.ctx.Log.Error("unexpected block verification failure", + zap.String("reason", "failed to calculate required timestamp delay"), + zap.Stringer("blkID", blk.ID()), + zap.Error(err), + ) return 0, err } @@ -375,6 +380,11 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( parentTimestamp, ) if err != nil { + p.vm.ctx.Log.Error("unexpected block verification failure", + zap.String("reason", "failed to calculate expected proposer"), + zap.Stringer("blkID", blk.ID()), + zap.Error(err), + ) return err } if expectedProposerID != proposerID { From 608de010921350d2f4de2167aafc103adbfaba7f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 00:48:33 -0500 Subject: [PATCH 061/111] nit --- vms/proposervm/batched_vm_test.go | 6 +++--- vms/proposervm/post_fork_block_test.go | 18 +++++++++--------- vms/proposervm/post_fork_option_test.go | 12 ++++++------ vms/proposervm/pre_fork_block_test.go | 12 ++++++------ vms/proposervm/state_syncable_vm_test.go | 2 +- vms/proposervm/vm_byzantine_test.go | 12 ++++++------ vms/proposervm/vm_test.go | 24 ++++++++++++------------ 7 files changed, 43 insertions(+), 43 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 9505d9d520d7..ec5dd78709b3 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -30,7 +30,7 @@ func TestCoreVMNotRemote(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -209,7 +209,7 @@ func TestGetAncestorsPostForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { @@ -693,7 +693,7 @@ func TestBatchedParseBlockPostForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { diff --git a/vms/proposervm/post_fork_block_test.go b/vms/proposervm/post_fork_block_test.go index e9e05f0e209d..4e4a35bf0761 100644 --- a/vms/proposervm/post_fork_block_test.go +++ b/vms/proposervm/post_fork_block_test.go @@ -42,7 +42,7 @@ func TestOracle_PostForkBlock_ImplementsInterface(t *testing.T) { // setup var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) _, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -206,7 +206,7 @@ func TestBlockVerify_PostForkBlock_PostDurango_ParentChecks(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) // post Durango + durangoTime = activationTime // post Durango ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -536,7 +536,7 @@ func TestBlockVerify_PostForkBlock_PChainHeightChecks(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -907,7 +907,7 @@ func TestBlockVerify_PostForkBlock_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Show that other verify call would not call coreBlk.Verify() var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -974,7 +974,7 @@ func TestBlockAccept_PostForkBlock_SetsLastAcceptedBlock(t *testing.T) { // setup var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -1041,7 +1041,7 @@ func TestBlockAccept_PostForkBlock_TwoProBlocksWithSameCoreBlock_OneIsAccepted(t var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -1092,7 +1092,7 @@ func TestBlockReject_PostForkBlock_InnerBlockIsNotRejected(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -1128,7 +1128,7 @@ func TestBlockVerify_PostForkBlock_ShouldBePostForkOption(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -1246,7 +1246,7 @@ func TestBlockVerify_PostForkBlock_PChainTooLow(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 5) defer func() { diff --git a/vms/proposervm/post_fork_option_test.go b/vms/proposervm/post_fork_option_test.go index a69769e63e05..26000f59ba33 100644 --- a/vms/proposervm/post_fork_option_test.go +++ b/vms/proposervm/post_fork_option_test.go @@ -38,7 +38,7 @@ func TestBlockVerify_PostForkOption_ParentChecks(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -157,7 +157,7 @@ func TestBlockVerify_PostForkOption_CoreBlockVerifyIsCalledOnce(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -262,7 +262,7 @@ func TestBlockAccept_PostForkOption_SetsLastAcceptedBlock(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -375,7 +375,7 @@ func TestBlockReject_InnerBlockIsNotRejected(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -480,7 +480,7 @@ func TestBlockVerify_PostForkOption_ParentIsNotOracleWithError(t *testing.T) { // Verify an option once; then show that another verify call would not call coreBlk.Verify() var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -568,7 +568,7 @@ func TestOptionTimestampValidity(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, db := initTestProposerVM(t, activationTime, durangoTime, 0) diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index 962f1812a263..cc79b74a8ec2 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -144,7 +144,7 @@ func TestOracle_PostForkBlkCanBuiltOnPreForkOption(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -241,7 +241,7 @@ func TestBlockVerify_PreFork_ParentChecks(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -320,7 +320,7 @@ func TestBlockVerify_BlocksBuiltOnPreForkGenesis(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -454,7 +454,7 @@ func TestBlockVerify_BlocksBuiltOnPostForkGenesis(t *testing.T) { var ( activationTime = genesisTimestamp.Add(-1 * time.Second) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(activationTime) @@ -596,7 +596,7 @@ func TestBlockVerify_ForkBlockIsOracleBlock(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -690,7 +690,7 @@ func TestBlockVerify_ForkBlockIsOracleBlockButChildrenAreSigned(t *testing.T) { var ( activationTime = genesisTimestamp.Add(10 * time.Second) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { diff --git a/vms/proposervm/state_syncable_vm_test.go b/vms/proposervm/state_syncable_vm_test.go index 3b761d708209..0a4ba6d3bfe1 100644 --- a/vms/proposervm/state_syncable_vm_test.go +++ b/vms/proposervm/state_syncable_vm_test.go @@ -604,7 +604,7 @@ func TestNoStateSummariesServedWhileRepairingHeightIndex(t *testing.T) { // Note: by default proVM is built such that heightIndex will be considered complete var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { diff --git a/vms/proposervm/vm_byzantine_test.go b/vms/proposervm/vm_byzantine_test.go index b52c7310e7eb..fcb230156c96 100644 --- a/vms/proposervm/vm_byzantine_test.go +++ b/vms/proposervm/vm_byzantine_test.go @@ -34,7 +34,7 @@ func TestInvalidByzantineProposerParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -105,7 +105,7 @@ func TestInvalidByzantineProposerOracleParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -214,7 +214,7 @@ func TestInvalidByzantineProposerPreForkParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -304,7 +304,7 @@ func TestBlockVerify_PostForkOption_FaultyParent(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -404,7 +404,7 @@ func TestBlockVerify_InvalidPostForkOption(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) proVM.Set(coreGenBlk.Timestamp()) @@ -588,7 +588,7 @@ func TestGetBlock_MutatedSignature(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, valState, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 48b465929e88..f14fda8a5238 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -247,7 +247,7 @@ func TestBuildBlockTimestampAreRoundedToSeconds(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -283,7 +283,7 @@ func TestBuildBlockIsIdempotent(t *testing.T) { // given the same core block, BuildBlock returns the same proposer block var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -321,7 +321,7 @@ func TestFirstProposerBlockIsBuiltOnTopOfGenesis(t *testing.T) { // setup var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -358,7 +358,7 @@ func TestProposerBlocksAreBuiltOnPreferredProBlock(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -454,7 +454,7 @@ func TestCoreBlocksMustBeBuiltOnPreferredCoreBlock(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -551,7 +551,7 @@ func TestCoreBlockFailureCauseProposerBlockParseFailure(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -593,7 +593,7 @@ func TestTwoProBlocksWrappingSameCoreBlockCanBeParsed(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, gencoreBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -669,7 +669,7 @@ func TestTwoProBlocksWithSameParentCanBothVerify(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -1120,7 +1120,7 @@ func TestInnerBlockDeduplication(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -1800,7 +1800,7 @@ func TestLaggedPChainHeight(t *testing.T) { var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -2371,7 +2371,7 @@ func TestVMInnerBlkCacheDeduplicationRegression(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -2450,7 +2450,7 @@ func TestVMInnerBlkMarkedAcceptedRegression(t *testing.T) { require := require.New(t) var ( activationTime = time.Unix(0, 0) - durangoTime = time.Unix(0, 0) + durangoTime = activationTime ) coreVM, _, proVM, gBlock, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { From 07a1498523da3402a4b61b71c2d5334e085dd703 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Sun, 10 Dec 2023 00:54:22 -0500 Subject: [PATCH 062/111] nit --- vms/proposervm/batched_vm_test.go | 4 ++-- vms/proposervm/pre_fork_block_test.go | 6 +++--- vms/proposervm/vm_test.go | 9 ++++----- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index ec5dd78709b3..00169eac3066 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -59,7 +59,7 @@ func TestGetAncestorsPreForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { @@ -571,7 +571,7 @@ func TestBatchedParseBlockPreForkOnly(t *testing.T) { require := require.New(t) var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, proRemoteVM, coreGenBlk := initTestRemoteProposerVM(t, activationTime, durangoTime) defer func() { diff --git a/vms/proposervm/pre_fork_block_test.go b/vms/proposervm/pre_fork_block_test.go index cc79b74a8ec2..42dfe14789f5 100644 --- a/vms/proposervm/pre_fork_block_test.go +++ b/vms/proposervm/pre_fork_block_test.go @@ -52,7 +52,7 @@ func TestOracle_PreForkBlkCanBuiltOnPreForkOption(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -499,7 +499,7 @@ func TestBlockAccept_PreFork_SetsLastAcceptedBlock(t *testing.T) { // setup var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -561,7 +561,7 @@ func TestBlockReject_PreForkBlock_InnerBlockIsRejected(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index f14fda8a5238..155727f640d3 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -739,7 +739,7 @@ func TestPreFork_Initialize(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) _, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -762,7 +762,7 @@ func TestPreFork_BuildBlock(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -801,10 +801,9 @@ func TestPreFork_BuildBlock(t *testing.T) { func TestPreFork_ParseBlock(t *testing.T) { require := require.New(t) - // setup var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, _, proVM, _, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { @@ -843,7 +842,7 @@ func TestPreFork_SetPreference(t *testing.T) { var ( activationTime = mockable.MaxTime - durangoTime = mockable.MaxTime + durangoTime = activationTime ) coreVM, _, proVM, coreGenBlk, _ := initTestProposerVM(t, activationTime, durangoTime, 0) defer func() { From 0f1f5266d2600081c9a405e03033a5277aaf9b4a Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 10 Dec 2023 15:11:59 +0100 Subject: [PATCH 063/111] wip: fixing scheduler --- vms/proposervm/proposer/mock_windower.go | 15 +++++++ vms/proposervm/proposer/windower.go | 57 +++++++++++++++++++++++- vms/proposervm/vm_test.go | 23 ++++++---- 3 files changed, 85 insertions(+), 10 deletions(-) diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index 6396c4092cd2..bb8f9856a2a6 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -68,3 +68,18 @@ func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3, arg mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExpectedProposer", reflect.TypeOf((*MockWindower)(nil).ExpectedProposer), arg0, arg1, arg2, arg3, arg4) } + +// MinDelayForProposer mocks base method. +func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 time.Time, arg4 ids.NodeID, arg5 time.Time) (time.Time, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "MinDelayForProposer", arg0, arg1, arg2, arg3, arg4, arg5) + ret0, _ := ret[0].(time.Time) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// MinDelayForProposer indicates an expected call of MinDelayForProposer. +func (mr *MockWindowerMockRecorder) MinDelayForProposer(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinDelayForProposer", reflect.TypeOf((*MockWindower)(nil).MinDelayForProposer), arg0, arg1, arg2, arg3, arg4, arg5) +} diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index f735168c5e3d..22a67f3dc60b 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -29,12 +29,15 @@ const ( MaxBuildWindows = 60 MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes + + MaxLookAheadWindow = time.Hour ) var ( _ Windower = (*windower)(nil) - ErrNoProposersAvailable = errors.New("no proposers available") + ErrNoProposersAvailable = errors.New("no proposers available") + ErrNoSlotsScheduledInNextFuture = errors.New("no slots scheduled in next future") ) type Windower interface { @@ -56,6 +59,15 @@ type Windower interface { blockTime, parentBlockTime time.Time, ) (ids.NodeID, error) + + MinDelayForProposer( + ctx context.Context, + chainHeight, + pChainHeight uint64, + parentBlockTime time.Time, + nodeID ids.NodeID, + startTime time.Time, + ) (time.Time, error) } // windower interfaces with P-Chain and it is responsible for calculating the @@ -127,6 +139,49 @@ func (w *windower) ExpectedProposer( return validators[indices[0]].id, nil } +func (w *windower) MinDelayForProposer( + ctx context.Context, + chainHeight, + pChainHeight uint64, + parentBlockTime time.Time, + nodeID ids.NodeID, + startTime time.Time, +) (time.Time, error) { + validators, err := w.sortedValidators(ctx, pChainHeight) + if err != nil { + return time.Time{}, err + } + + var ( + res = startTime + source = prng.NewMT19937_64() + validatorWeights = validatorsToWeight(validators) + ) + + for res.Sub(startTime) < MaxLookAheadWindow { + var ( + slot = uint64(startTime.Sub(parentBlockTime) / WindowDuration) + seed = chainHeight ^ bits.Reverse64(slot) ^ w.chainSource + ) + + source.Seed(seed) + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) + if err := sampler.Initialize(validatorWeights); err != nil { + return time.Time{}, err + } + indices, err := sampler.Sample(1) + if err != nil { + return time.Time{}, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) + } + + if validators[indices[0]].id == nodeID { + return res, nil + } + res = res.Add(WindowDuration) + } + return time.Time{}, ErrNoSlotsScheduledInNextFuture +} + // proposers returns the proposer list for building a block at [chainHeight] // when the validator set is defined at [pChainHeight]. The list is returned // in order. The minimum delay of a validator is the index they appear times diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 155727f640d3..4ef1e95b740d 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -220,23 +220,28 @@ func initTestProposerVM( func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) error { ctx := context.Background() vm.Clock.Set(vm.Clock.Time().Truncate(time.Second)) - for { // find the right time to issue next block - proposerID, err := vm.ExpectedProposer( + + for { + nextTime, err := vm.MinDelayForProposer( ctx, chainTip.Height()+1, pchainHeight, - vm.Clock.Time(), chainTip.Timestamp(), + vm.ctx.NodeID, + vm.Clock.Time(), ) - if err != nil { + + switch err { + case nil: + vm.Clock.Set(nextTime) + return nil + case proposer.ErrNoSlotsScheduledInNextFuture: + // repeat slot search + vm.Clock.Set(vm.Clock.Time().Add(proposer.MaxLookAheadWindow)) + default: return err } - if proposerID == vm.ctx.NodeID { - break - } - vm.Clock.Set(vm.Time().Add(proposer.WindowDuration)) } - return nil } // VM.BuildBlock tests section From bb0386dcab75f0c67b61933ed1bf336b7897b7f2 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Sun, 10 Dec 2023 15:44:50 +0100 Subject: [PATCH 064/111] updated block scheduler --- vms/proposervm/vm.go | 74 +++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index ae9afe6562cd..f8a4616cc14e 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -333,39 +333,71 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { return err } - // reset scheduler - minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) + nextStartTime, err := vm.resetScheduler(ctx, blk, pChainHeight) if err != nil { - vm.ctx.Log.Debug("failed to fetch the expected delay", - zap.Error(err), - ) - // A nil error is returned here because it is possible that - // bootstrapping caused the last accepted block to move past the latest - // P-chain height. This will cause building blocks to return an error - // until the P-chain's height has advanced. return nil } - - // Note: The P-chain does not currently try to target any block time. It - // notifies the consensus engine as soon as a new block may be built. To - // avoid fast runs of blocks there is an additional minimum delay that - // validators can specify. This delay may be an issue for high performance, - // custom VMs. Until the P-chain is modified to target a specific block - // time, ProposerMinBlockDelay can be configured in the subnet config. - minDelay = math.Max(minDelay, vm.MinBlkDelay) - - preferredTime := blk.Timestamp() - nextStartTime := preferredTime.Add(minDelay) vm.Scheduler.SetBuildBlockTime(nextStartTime) vm.ctx.Log.Debug("set preference", zap.Stringer("blkID", blk.ID()), - zap.Time("blockTimestamp", preferredTime), + zap.Time("blockTimestamp", blk.Timestamp()), zap.Time("nextStartTime", nextStartTime), ) return nil } +func (vm *VM) resetScheduler( + ctx context.Context, + blk PostForkBlock, + pChainHeight uint64, +) (time.Time, error) { + var ( + parentTimestamp = blk.Timestamp() + nextStartTime time.Time + ) + + if vm.IsDurangoActivated(parentTimestamp) { + var err error + nextStartTime, err = vm.Windower.MinDelayForProposer( + ctx, + blk.Height()+1, + pChainHeight, + parentTimestamp, + vm.ctx.NodeID, + vm.Clock.Time().Truncate(time.Second), + ) + if err != nil { + vm.ctx.Log.Debug("failed to calculate min delay for proposer", + zap.Error(err), + ) + return time.Time{}, err + } + } else { + minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) + if err != nil { + vm.ctx.Log.Debug("failed to fetch the expected delay", + zap.Error(err), + ) + // A nil error is returned here because it is possible that + // bootstrapping caused the last accepted block to move past the latest + // P-chain height. This will cause building blocks to return an error + // until the P-chain's height has advanced. + return time.Time{}, err + } + + // Note: The P-chain does not currently try to target any block time. It + // notifies the consensus engine as soon as a new block may be built. To + // avoid fast runs of blocks there is an additional minimum delay that + // validators can specify. This delay may be an issue for high performance, + // custom VMs. Until the P-chain is modified to target a specific block + // time, ProposerMinBlockDelay can be configured in the subnet config. + minDelay = math.Max(minDelay, vm.MinBlkDelay) + nextStartTime = parentTimestamp.Add(minDelay) + } + return nextStartTime, nil +} + func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error) { lastAccepted, err := vm.State.GetLastAccepted() if err == database.ErrNotFound { From 2f59a4a09e0dfd79a1e07636707e46cd001686a1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Dec 2023 18:07:11 +0100 Subject: [PATCH 065/111] fixed scheduling reset --- vms/proposervm/block.go | 14 ++++++ vms/proposervm/vm.go | 94 +++++++++++++++++++++++------------------ 2 files changed, 66 insertions(+), 42 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 3b045e7783f4..86c873f446c0 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -148,6 +148,20 @@ func (p *postForkCommonComponents) Verify( if err != nil { return err } + + // Post durango, p.vm.Ctx.NodeID slot may be so far in time that we don't + // schedule it when resetting vm preferred block. So we make sure to reschedule timer + // every time we verify a block to avoid stalls where innerVM is ready to build a block + // but proposerVM has not scheduled its timer. + nextStartTime, err := p.vm.resetPostDurangoScheduler(ctx, child, childPChainHeight) + switch err { + case nil: + p.vm.Scheduler.SetBuildBlockTime(nextStartTime) + case proposer.ErrNoSlotsScheduledInNextFuture: + // Can't schedule a slot now. We'll try later again + default: + return err + } } else { delay, err := p.verifyPreDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) if err != nil { diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index f8a4616cc14e..b2e9681c19b8 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -333,7 +333,15 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { return err } - nextStartTime, err := vm.resetScheduler(ctx, blk, pChainHeight) + var ( + nextStartTime time.Time + parentTimestamp = blk.Timestamp() + ) + if vm.IsDurangoActivated(parentTimestamp) { + nextStartTime, err = vm.resetPostDurangoScheduler(ctx, blk, pChainHeight) + } else { + nextStartTime, err = vm.resetPreDurangoScheduler(ctx, blk, pChainHeight) + } if err != nil { return nil } @@ -347,53 +355,55 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { return nil } -func (vm *VM) resetScheduler( +func (vm *VM) resetPreDurangoScheduler( ctx context.Context, blk PostForkBlock, pChainHeight uint64, ) (time.Time, error) { - var ( - parentTimestamp = blk.Timestamp() - nextStartTime time.Time - ) - - if vm.IsDurangoActivated(parentTimestamp) { - var err error - nextStartTime, err = vm.Windower.MinDelayForProposer( - ctx, - blk.Height()+1, - pChainHeight, - parentTimestamp, - vm.ctx.NodeID, - vm.Clock.Time().Truncate(time.Second), + parentTimestamp := blk.Timestamp() + minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) + if err != nil { + vm.ctx.Log.Debug("failed to fetch the expected delay", + zap.Error(err), ) - if err != nil { - vm.ctx.Log.Debug("failed to calculate min delay for proposer", - zap.Error(err), - ) - return time.Time{}, err - } - } else { - minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) - if err != nil { - vm.ctx.Log.Debug("failed to fetch the expected delay", - zap.Error(err), - ) - // A nil error is returned here because it is possible that - // bootstrapping caused the last accepted block to move past the latest - // P-chain height. This will cause building blocks to return an error - // until the P-chain's height has advanced. - return time.Time{}, err - } + // A nil error is returned here because it is possible that + // bootstrapping caused the last accepted block to move past the latest + // P-chain height. This will cause building blocks to return an error + // until the P-chain's height has advanced. + return time.Time{}, err + } + + // Note: The P-chain does not currently try to target any block time. It + // notifies the consensus engine as soon as a new block may be built. To + // avoid fast runs of blocks there is an additional minimum delay that + // validators can specify. This delay may be an issue for high performance, + // custom VMs. Until the P-chain is modified to target a specific block + // time, ProposerMinBlockDelay can be configured in the subnet config. + minDelay = math.Max(minDelay, vm.MinBlkDelay) + nextStartTime := parentTimestamp.Add(minDelay) + + return nextStartTime, nil +} - // Note: The P-chain does not currently try to target any block time. It - // notifies the consensus engine as soon as a new block may be built. To - // avoid fast runs of blocks there is an additional minimum delay that - // validators can specify. This delay may be an issue for high performance, - // custom VMs. Until the P-chain is modified to target a specific block - // time, ProposerMinBlockDelay can be configured in the subnet config. - minDelay = math.Max(minDelay, vm.MinBlkDelay) - nextStartTime = parentTimestamp.Add(minDelay) +func (vm *VM) resetPostDurangoScheduler( + ctx context.Context, + blk PostForkBlock, + pChainHeight uint64, +) (time.Time, error) { + parentTimestamp := blk.Timestamp() + nextStartTime, err := vm.Windower.MinDelayForProposer( + ctx, + blk.Height()+1, + pChainHeight, + parentTimestamp, + vm.ctx.NodeID, + vm.Clock.Time().Truncate(time.Second), + ) + if err != nil { + vm.ctx.Log.Debug("failed to calculate min delay for proposer", + zap.Error(err), + ) + return time.Time{}, err } return nextStartTime, nil } From c528a1a589f7b585b2ae606c40fc6f86aaf21b35 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Dec 2023 18:51:04 +0100 Subject: [PATCH 066/111] re-exported Proposers --- vms/proposervm/proposer/mock_windower.go | 15 ++++ vms/proposervm/proposer/windower.go | 95 +++++++++++++----------- 2 files changed, 66 insertions(+), 44 deletions(-) diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index bb8f9856a2a6..eea021da273a 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -83,3 +83,18 @@ func (mr *MockWindowerMockRecorder) MinDelayForProposer(arg0, arg1, arg2, arg3, mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinDelayForProposer", reflect.TypeOf((*MockWindower)(nil).MinDelayForProposer), arg0, arg1, arg2, arg3, arg4, arg5) } + +// Proposers mocks base method. +func (m *MockWindower) Proposers(arg0 context.Context, arg1, arg2 uint64, arg3 int) ([]ids.NodeID, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Proposers", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].([]ids.NodeID) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Proposers indicates an expected call of Proposers. +func (mr *MockWindowerMockRecorder) Proposers(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Proposers", reflect.TypeOf((*MockWindower)(nil).Proposers), arg0, arg1, arg2, arg3) +} diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 22a67f3dc60b..8d003c8da439 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -41,6 +41,17 @@ var ( ) type Windower interface { + // Proposers returns the proposer list for building a block at [chainHeight] + // when the validator set is defined at [pChainHeight]. The list is returned + // in order. The minimum delay of a validator is the index they appear times + // [WindowDuration]. + Proposers( + ctx context.Context, + chainHeight, + pChainHeight uint64, + maxWindows int, + ) ([]ids.NodeID, error) + // Delay returns the amount of time that [validatorID] must wait before // building a block at [chainHeight] when the validator set is defined at // [pChainHeight]. @@ -87,12 +98,51 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { } } +func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { + validators, err := w.sortedValidators(ctx, pChainHeight) + if err != nil { + return nil, err + } + + var ( + seed = chainHeight ^ w.chainSource + source = prng.NewMT19937() + validatorWeights = validatorsToWeight(validators) + ) + + source.Seed(seed) + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) + if err := sampler.Initialize(validatorWeights); err != nil { + return nil, err + } + + var totalWeight uint64 + for _, weight := range validatorWeights { + totalWeight, err = math.Add64(totalWeight, weight) + if err != nil { + return nil, err + } + } + + numToSample := int(math.Min(uint64(maxWindows), totalWeight)) + indices, err := sampler.Sample(numToSample) + if err != nil { + return nil, err + } + + nodeIDs := make([]ids.NodeID, numToSample) + for i, index := range indices { + nodeIDs[i] = validators[index].id + } + return nodeIDs, nil +} + func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { if validatorID == ids.EmptyNodeID { return time.Duration(maxWindows) * WindowDuration, nil } - proposers, err := w.proposers(ctx, chainHeight, pChainHeight, maxWindows) + proposers, err := w.Proposers(ctx, chainHeight, pChainHeight, maxWindows) if err != nil { return 0, err } @@ -182,49 +232,6 @@ func (w *windower) MinDelayForProposer( return time.Time{}, ErrNoSlotsScheduledInNextFuture } -// proposers returns the proposer list for building a block at [chainHeight] -// when the validator set is defined at [pChainHeight]. The list is returned -// in order. The minimum delay of a validator is the index they appear times -// [WindowDuration]. -func (w *windower) proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { - validators, err := w.sortedValidators(ctx, pChainHeight) - if err != nil { - return nil, err - } - - var ( - seed = chainHeight ^ w.chainSource - source = prng.NewMT19937() - validatorWeights = validatorsToWeight(validators) - ) - - source.Seed(seed) - sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) - if err := sampler.Initialize(validatorWeights); err != nil { - return nil, err - } - - var totalWeight uint64 - for _, weight := range validatorWeights { - totalWeight, err = math.Add64(totalWeight, weight) - if err != nil { - return nil, err - } - } - - numToSample := int(math.Min(uint64(maxWindows), totalWeight)) - indices, err := sampler.Sample(numToSample) - if err != nil { - return nil, err - } - - nodeIDs := make([]ids.NodeID, numToSample) - for i, index := range indices { - nodeIDs[i] = validators[index].id - } - return nodeIDs, nil -} - func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, error) { // get the validator set by the p-chain height validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) From 4107482853e7570c90c918cfe0091ac7a2ca2310 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Mon, 11 Dec 2023 19:22:38 +0100 Subject: [PATCH 067/111] avoid reinstantiating sampler at each round --- vms/proposervm/proposer/windower.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 8d003c8da439..0b5e6fc2c6f9 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -206,7 +206,11 @@ func (w *windower) MinDelayForProposer( res = startTime source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) + sampler = sampler.NewDeterministicWeightedWithoutReplacement(source) ) + if err := sampler.Initialize(validatorWeights); err != nil { + return time.Time{}, err + } for res.Sub(startTime) < MaxLookAheadWindow { var ( @@ -215,10 +219,7 @@ func (w *windower) MinDelayForProposer( ) source.Seed(seed) - sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) - if err := sampler.Initialize(validatorWeights); err != nil { - return time.Time{}, err - } + indices, err := sampler.Sample(1) if err != nil { return time.Time{}, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) From 96c898dfae33362c923715e3543a192501cdbb54 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 12 Dec 2023 01:22:40 -0500 Subject: [PATCH 068/111] nit --- vms/proposervm/batched_vm_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/batched_vm_test.go b/vms/proposervm/batched_vm_test.go index 00169eac3066..9934e8f13811 100644 --- a/vms/proposervm/batched_vm_test.go +++ b/vms/proposervm/batched_vm_test.go @@ -367,7 +367,7 @@ func TestGetAncestorsAtSnomanPlusPlusFork(t *testing.T) { forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - durangoTime = currentTime.Add(10 * time.Minute) + durangoTime = forkTime ) // enable ProBlks in next future @@ -808,7 +808,7 @@ func TestBatchedParseBlockAtSnomanPlusPlusFork(t *testing.T) { forkTime = currentTime.Add(10 * time.Minute) postForkTime = currentTime.Add(15 * time.Minute) - durangoTime = currentTime.Add(10 * time.Minute) + durangoTime = forkTime ) // enable ProBlks in next future From 2e80f1328e726330daf1f697b9aeec268a402bb0 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 12 Dec 2023 01:42:01 -0500 Subject: [PATCH 069/111] nit --- vms/proposervm/proposer/windower.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 0b5e6fc2c6f9..c5a29e3785dd 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -110,7 +110,6 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint validatorWeights = validatorsToWeight(validators) ) - source.Seed(seed) sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) if err := sampler.Initialize(validatorWeights); err != nil { return nil, err @@ -125,6 +124,7 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint } numToSample := int(math.Min(uint64(maxWindows), totalWeight)) + source.Seed(seed) indices, err := sampler.Sample(numToSample) if err != nil { return nil, err @@ -176,12 +176,12 @@ func (w *windower) ExpectedProposer( validatorWeights = validatorsToWeight(validators) ) - source.Seed(seed) sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) if err := sampler.Initialize(validatorWeights); err != nil { return ids.EmptyNodeID, err } + source.Seed(seed) indices, err := sampler.Sample(1) if err != nil { return ids.EmptyNodeID, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) @@ -219,7 +219,6 @@ func (w *windower) MinDelayForProposer( ) source.Seed(seed) - indices, err := sampler.Sample(1) if err != nil { return time.Time{}, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) From d750e3caf01b8302b293292ab239e51a600f8497 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Tue, 12 Dec 2023 13:32:01 +0100 Subject: [PATCH 070/111] some more fixes --- vms/proposervm/block.go | 14 -------------- vms/proposervm/vm.go | 33 +++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 86c873f446c0..3b045e7783f4 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -148,20 +148,6 @@ func (p *postForkCommonComponents) Verify( if err != nil { return err } - - // Post durango, p.vm.Ctx.NodeID slot may be so far in time that we don't - // schedule it when resetting vm preferred block. So we make sure to reschedule timer - // every time we verify a block to avoid stalls where innerVM is ready to build a block - // but proposerVM has not scheduled its timer. - nextStartTime, err := p.vm.resetPostDurangoScheduler(ctx, child, childPChainHeight) - switch err { - case nil: - p.vm.Scheduler.SetBuildBlockTime(nextStartTime) - case proposer.ErrNoSlotsScheduledInNextFuture: - // Can't schedule a slot now. We'll try later again - default: - return err - } } else { delay, err := p.verifyPreDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) if err != nil { diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index b2e9681c19b8..7879c7942108 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -299,7 +299,28 @@ func (vm *VM) BuildBlock(ctx context.Context) (snowman.Block, error) { return nil, err } - return preferredBlock.buildChild(ctx) + blk, err := preferredBlock.buildChild(ctx) + if err != nil { + return nil, err + } + + // Following Durango activation make sure we try and reschedule the block building timer + if vm.IsDurangoActivated(preferredBlock.Timestamp()) { + postForkBlk, ok := preferredBlock.(PostForkBlock) + if ok { + pChainHeight, err := blk.pChainHeight(ctx) + if err != nil { + return nil, err + } + nextStartTime, err := vm.resetPostDurangoScheduler(ctx, postForkBlk, pChainHeight) + if err != nil { + return nil, err + } + vm.Scheduler.SetBuildBlockTime(nextStartTime) + } + } + + return blk, nil } func (vm *VM) ParseBlock(ctx context.Context, b []byte) (snowman.Block, error) { @@ -399,13 +420,17 @@ func (vm *VM) resetPostDurangoScheduler( vm.ctx.NodeID, vm.Clock.Time().Truncate(time.Second), ) - if err != nil { + if errors.Is(err, proposer.ErrNoSlotsScheduledInNextFuture) { + // while there are no slots available in the next figure for vm.ctx.NodeID, + // we still want to make sure we reset the time to eventually server build + // block requests from innerVM + nextStartTime, err = parentTimestamp.Add(proposer.MaxLookAheadWindow), nil + } else if err != nil { vm.ctx.Log.Debug("failed to calculate min delay for proposer", zap.Error(err), ) - return time.Time{}, err } - return nextStartTime, nil + return nextStartTime, err } func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error) { From ff47d3bd53040cdad6ea77b70dfeaf980285fafb Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 12 Dec 2023 17:59:43 -0500 Subject: [PATCH 071/111] fix building time logic --- vms/proposervm/block.go | 18 ++++++++- vms/proposervm/proposer/windower.go | 8 ++-- vms/proposervm/proposer/windower_test.go | 18 ++++----- vms/proposervm/vm.go | 51 +++++++++--------------- 4 files changed, 48 insertions(+), 47 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 3b045e7783f4..4012d0c979ee 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -376,8 +376,8 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( ctx, blkHeight, parentPChainHeight, - blkTimestamp, parentTimestamp, + blkTimestamp, ) if err != nil { p.vm.ctx.Log.Error("unexpected block verification failure", @@ -406,8 +406,8 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( ctx, parentHeight+1, parentPChainHeight, - newTimestamp, parentTimestamp, + newTimestamp, ) if err != nil { p.vm.ctx.Log.Error("unexpected build block failure", @@ -430,6 +430,20 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( zap.Stringer("expectedProposer", expectedProposerID), ) + // We need to reschedule the block builder to the next time we can try to + // build a block. + nextStartTime, err := p.vm.resetPostDurangoScheduler( + ctx, + parentHeight+1, + parentPChainHeight, + parentTimestamp, + newTimestamp, + ) + if err != nil { + return err + } + p.vm.Scheduler.SetBuildBlockTime(nextStartTime) + // In case the inner VM only issued one pendingTxs message, we should // attempt to re-handle that once it is our turn to build the block. p.vm.notifyInnerBlockReady() diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index c5a29e3785dd..738bfa9b0aa0 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -67,8 +67,8 @@ type Windower interface { ctx context.Context, chainHeight, pChainHeight uint64, - blockTime, - parentBlockTime time.Time, + parentBlockTime, + blockTime time.Time, ) (ids.NodeID, error) MinDelayForProposer( @@ -161,8 +161,8 @@ func (w *windower) ExpectedProposer( ctx context.Context, chainHeight, pChainHeight uint64, - blockTime, - parentBlockTime time.Time, + parentBlockTime, + blockTime time.Time, ) (ids.NodeID, error) { validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index ab869eca9b55..654c62b3bf83 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -43,7 +43,7 @@ func TestWindowerNoValidators(t *testing.T) { require.NoError(err) require.Zero(delay) - expectedProposer, err := w.ExpectedProposer(context.Background(), chainHeight, pChainHeight, blockTime, parentBlockTime) + expectedProposer, err := w.ExpectedProposer(context.Background(), chainHeight, pChainHeight, parentBlockTime, blockTime) require.ErrorIs(err, ErrNoProposersAvailable) require.Equal(ids.EmptyNodeID, expectedProposer) } @@ -246,12 +246,12 @@ func TestExpectedProposerChangeByHeight(t *testing.T) { blockTime = parentBlockTime.Add(time.Second) ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[2], proposerID) chainHeight = 2 - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[1], proposerID) } @@ -304,11 +304,11 @@ func TestExpectedProposerChangeByChain(t *testing.T) { blockTime = parentBlockTime.Add(time.Second) ) - proposerID, err := w0.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err := w0.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[5], proposerID) - proposerID, err = w1.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err = w1.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[3], proposerID) } @@ -351,14 +351,14 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { blockTime = parentBlockTime.Add(time.Second) ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[2], proposerID) { // proposerID won't change within the same slot blockTime = parentBlockTime.Add(WindowDuration).Add(-1 * time.Second) - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[2], proposerID) } @@ -366,7 +366,7 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { { // proposerID changes with new slot blockTime = parentBlockTime.Add(WindowDuration) - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[0], proposerID) } @@ -374,7 +374,7 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { { // proposerID changes with new slot blockTime = parentBlockTime.Add(2 * WindowDuration) - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, blockTime, parentBlockTime) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[9], proposerID) } diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 7879c7942108..9012ecc2c9e3 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -299,28 +299,7 @@ func (vm *VM) BuildBlock(ctx context.Context) (snowman.Block, error) { return nil, err } - blk, err := preferredBlock.buildChild(ctx) - if err != nil { - return nil, err - } - - // Following Durango activation make sure we try and reschedule the block building timer - if vm.IsDurangoActivated(preferredBlock.Timestamp()) { - postForkBlk, ok := preferredBlock.(PostForkBlock) - if ok { - pChainHeight, err := blk.pChainHeight(ctx) - if err != nil { - return nil, err - } - nextStartTime, err := vm.resetPostDurangoScheduler(ctx, postForkBlk, pChainHeight) - if err != nil { - return nil, err - } - vm.Scheduler.SetBuildBlockTime(nextStartTime) - } - } - - return blk, nil + return preferredBlock.buildChild(ctx) } func (vm *VM) ParseBlock(ctx context.Context, b []byte) (snowman.Block, error) { @@ -359,7 +338,13 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { parentTimestamp = blk.Timestamp() ) if vm.IsDurangoActivated(parentTimestamp) { - nextStartTime, err = vm.resetPostDurangoScheduler(ctx, blk, pChainHeight) + nextStartTime, err = vm.resetPostDurangoScheduler( + ctx, + blk.Height()+1, + pChainHeight, + blk.Timestamp(), + vm.Clock.Time().Truncate(time.Second), + ) } else { nextStartTime, err = vm.resetPreDurangoScheduler(ctx, blk, pChainHeight) } @@ -408,24 +393,26 @@ func (vm *VM) resetPreDurangoScheduler( func (vm *VM) resetPostDurangoScheduler( ctx context.Context, - blk PostForkBlock, + blkHeight uint64, pChainHeight uint64, + parentTimestamp time.Time, + currentTime time.Time, ) (time.Time, error) { - parentTimestamp := blk.Timestamp() nextStartTime, err := vm.Windower.MinDelayForProposer( ctx, - blk.Height()+1, + blkHeight, pChainHeight, parentTimestamp, vm.ctx.NodeID, - vm.Clock.Time().Truncate(time.Second), + currentTime, ) if errors.Is(err, proposer.ErrNoSlotsScheduledInNextFuture) { - // while there are no slots available in the next figure for vm.ctx.NodeID, - // we still want to make sure we reset the time to eventually server build - // block requests from innerVM - nextStartTime, err = parentTimestamp.Add(proposer.MaxLookAheadWindow), nil - } else if err != nil { + // This node is not scheduled to propose in any nearby slots. To avoid + // costly iteration, stop iterating early and only continue iterating if + // needed. + return currentTime.Add(proposer.MaxLookAheadWindow), nil + } + if err != nil { vm.ctx.Log.Debug("failed to calculate min delay for proposer", zap.Error(err), ) From 86adaedce31e06a917f8d0020afbe91c0143315f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Tue, 12 Dec 2023 18:37:29 -0500 Subject: [PATCH 072/111] nit --- vms/proposervm/block.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 4012d0c979ee..733c02e87ba0 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -440,6 +440,11 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( newTimestamp, ) if err != nil { + p.vm.ctx.Log.Error("failed to reset block builder scheduler", + zap.String("reason", "failed to calculate expected proposer"), + zap.Stringer("parentID", parentID), + zap.Error(err), + ) return err } p.vm.Scheduler.SetBuildBlockTime(nextStartTime) From da7b307f4528b0a218b35abf87e35d95a9eb68b7 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Dec 2023 13:59:01 +0100 Subject: [PATCH 073/111] added UT --- scripts/mocks.mockgen.txt | 1 + vms/proposervm/block_test.go | 67 ++++++++++++++++++++ vms/proposervm/scheduler/mock_scheduler.go | 74 ++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 vms/proposervm/scheduler/mock_scheduler.go diff --git a/scripts/mocks.mockgen.txt b/scripts/mocks.mockgen.txt index 3ec7849d6e0b..d5352e2ad62f 100644 --- a/scripts/mocks.mockgen.txt +++ b/scripts/mocks.mockgen.txt @@ -37,6 +37,7 @@ github.com/ava-labs/avalanchego/vms/platformvm/txs/builder=Builder=vms/platformv github.com/ava-labs/avalanchego/vms/platformvm/txs/mempool=Mempool=vms/platformvm/txs/mempool/mock_mempool.go github.com/ava-labs/avalanchego/vms/platformvm/utxo=Verifier=vms/platformvm/utxo/mock_verifier.go github.com/ava-labs/avalanchego/vms/proposervm/proposer=Windower=vms/proposervm/proposer/mock_windower.go +github.com/ava-labs/avalanchego/vms/proposervm/scheduler=Scheduler=vms/proposervm/scheduler/mock_scheduler.go github.com/ava-labs/avalanchego/vms/proposervm/state=State=vms/proposervm/state/mock_state.go github.com/ava-labs/avalanchego/vms/proposervm=PostForkBlock=vms/proposervm/mock_post_fork_block.go github.com/ava-labs/avalanchego/vms/registry=VMGetter=vms/registry/mock_vm_getter.go diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index bdadba8da619..7e512d5d98fc 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -27,6 +27,7 @@ import ( "github.com/ava-labs/avalanchego/utils/logging" "github.com/ava-labs/avalanchego/utils/timer/mockable" "github.com/ava-labs/avalanchego/vms/proposervm/proposer" + "github.com/ava-labs/avalanchego/vms/proposervm/scheduler" ) // Assert that when the underlying VM implements ChainVMWithBuildBlockContext @@ -371,3 +372,69 @@ func TestPreDurangoNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { require.Equal(ids.EmptyNodeID, childBlk.(*postForkBlock).Proposer()) // unsigned so no proposer } } + +// We consider a case where this node is not current proposer, nor is scheduled to propose in the next future +// We check that scheduler is called nonetheless, to be able to process innerVM block requests +func TestPostDurangoBuildChildResetScheduler(t *testing.T) { + require := require.New(t) + ctrl := gomock.NewController(t) + + var ( + thisNodeID = ids.GenerateTestNodeID() + selectedProposer = ids.GenerateTestNodeID() + pChainHeight uint64 = 1337 + parentID = ids.GenerateTestID() + parentTimestamp = time.Now().Truncate(time.Second) + parentHeight uint64 = 1234 + ) + + innerBlk := snowman.NewMockBlock(ctrl) + innerBlk.EXPECT().Height().Return(parentHeight + 1) + + innerVM := mocks.NewMockChainVM(ctrl) + + vdrState := validators.NewMockState(ctrl) + vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil) + + windower := proposer.NewMockWindower(ctrl) + windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(selectedProposer, nil) // return a proposer different from thisNode, to check whether scheduler is reset + windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(time.Time{}, proposer.ErrNoSlotsScheduledInNextFuture) // let there be no slot available in the next future + + // we mock the scheduler setting the exact time we expect it to be reset to + scheduler := scheduler.NewMockScheduler(ctrl) + scheduler.EXPECT().SetBuildBlockTime(parentTimestamp.Add(proposer.MaxLookAheadWindow)) + + pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + require.NoError(err) + vm := &VM{ + Config: Config{ + ActivationTime: time.Unix(0, 0), + DurangoTime: time.Unix(0, 0), + StakingCertLeaf: &staking.Certificate{}, + StakingLeafSigner: pk, + }, + ChainVM: innerVM, + ctx: &snow.Context{ + NodeID: thisNodeID, + ValidatorState: vdrState, + Log: logging.NoLog{}, + }, + Windower: windower, + Scheduler: scheduler, + } + + blk := &postForkCommonComponents{ + innerBlk: innerBlk, + vm: vm, + } + + _, err = blk.buildChild( + context.Background(), + parentID, + parentTimestamp, + pChainHeight-1, + ) + require.ErrorIs(err, errProposerWindowNotStarted) +} diff --git a/vms/proposervm/scheduler/mock_scheduler.go b/vms/proposervm/scheduler/mock_scheduler.go new file mode 100644 index 000000000000..bb4c19b941f1 --- /dev/null +++ b/vms/proposervm/scheduler/mock_scheduler.go @@ -0,0 +1,74 @@ +// Copyright (C) 2019-2023, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ava-labs/avalanchego/vms/proposervm/scheduler (interfaces: Scheduler) + +// Package scheduler is a generated GoMock package. +package scheduler + +import ( + reflect "reflect" + time "time" + + gomock "go.uber.org/mock/gomock" +) + +// MockScheduler is a mock of Scheduler interface. +type MockScheduler struct { + ctrl *gomock.Controller + recorder *MockSchedulerMockRecorder +} + +// MockSchedulerMockRecorder is the mock recorder for MockScheduler. +type MockSchedulerMockRecorder struct { + mock *MockScheduler +} + +// NewMockScheduler creates a new mock instance. +func NewMockScheduler(ctrl *gomock.Controller) *MockScheduler { + mock := &MockScheduler{ctrl: ctrl} + mock.recorder = &MockSchedulerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockScheduler) EXPECT() *MockSchedulerMockRecorder { + return m.recorder +} + +// Close mocks base method. +func (m *MockScheduler) Close() { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Close") +} + +// Close indicates an expected call of Close. +func (mr *MockSchedulerMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockScheduler)(nil).Close)) +} + +// Dispatch mocks base method. +func (m *MockScheduler) Dispatch(arg0 time.Time) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Dispatch", arg0) +} + +// Dispatch indicates an expected call of Dispatch. +func (mr *MockSchedulerMockRecorder) Dispatch(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Dispatch", reflect.TypeOf((*MockScheduler)(nil).Dispatch), arg0) +} + +// SetBuildBlockTime mocks base method. +func (m *MockScheduler) SetBuildBlockTime(arg0 time.Time) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "SetBuildBlockTime", arg0) +} + +// SetBuildBlockTime indicates an expected call of SetBuildBlockTime. +func (mr *MockSchedulerMockRecorder) SetBuildBlockTime(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetBuildBlockTime", reflect.TypeOf((*MockScheduler)(nil).SetBuildBlockTime), arg0) +} From d7f14ed4cf3a2a1643b8e37494e95a112febaaa0 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Dec 2023 14:02:41 +0100 Subject: [PATCH 074/111] added UT --- vms/proposervm/block_test.go | 60 +++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 7e512d5d98fc..9d15c03bf6f9 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -373,7 +373,7 @@ func TestPreDurangoNonValidatorNodeBlockBuiltDelaysTests(t *testing.T) { } } -// We consider a case where this node is not current proposer, nor is scheduled to propose in the next future +// We consider cases where this node is not current proposer (may be scheduled in the next future or not). // We check that scheduler is called nonetheless, to be able to process innerVM block requests func TestPostDurangoBuildChildResetScheduler(t *testing.T) { require := require.New(t) @@ -389,22 +389,16 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { ) innerBlk := snowman.NewMockBlock(ctrl) - innerBlk.EXPECT().Height().Return(parentHeight + 1) - - innerVM := mocks.NewMockChainVM(ctrl) + innerBlk.EXPECT().Height().Return(parentHeight + 1).AnyTimes() vdrState := validators.NewMockState(ctrl) - vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil) + vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() windower := proposer.NewMockWindower(ctrl) windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(selectedProposer, nil) // return a proposer different from thisNode, to check whether scheduler is reset - windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(time.Time{}, proposer.ErrNoSlotsScheduledInNextFuture) // let there be no slot available in the next future + Return(selectedProposer, nil).AnyTimes() // return a proposer different from thisNode, to check whether scheduler is reset - // we mock the scheduler setting the exact time we expect it to be reset to scheduler := scheduler.NewMockScheduler(ctrl) - scheduler.EXPECT().SetBuildBlockTime(parentTimestamp.Add(proposer.MaxLookAheadWindow)) pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) @@ -415,7 +409,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { StakingCertLeaf: &staking.Certificate{}, StakingLeafSigner: pk, }, - ChainVM: innerVM, + ChainVM: mocks.NewMockChainVM(ctrl), ctx: &snow.Context{ NodeID: thisNodeID, ValidatorState: vdrState, @@ -430,11 +424,41 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { vm: vm, } - _, err = blk.buildChild( - context.Background(), - parentID, - parentTimestamp, - pChainHeight-1, - ) - require.ErrorIs(err, errProposerWindowNotStarted) + { + // no slots within inspected window + + windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(time.Time{}, proposer.ErrNoSlotsScheduledInNextFuture).AnyTimes() + + // we mock the scheduler setting the exact time we expect it to be reset to + expectedSchedulerTime := parentTimestamp.Add(proposer.MaxLookAheadWindow) + scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).AnyTimes() + + _, err = blk.buildChild( + context.Background(), + parentID, + parentTimestamp, + pChainHeight-1, + ) + require.ErrorIs(err, errProposerWindowNotStarted) + } + + { + // a slot within inspected window + + expectedSchedulerTime := parentTimestamp.Add(proposer.MaxLookAheadWindow).Add(-1 * time.Minute) + windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + Return(expectedSchedulerTime, nil).AnyTimes() + + // we mock the scheduler setting the exact time we expect it to be reset to + scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).AnyTimes() + + _, err = blk.buildChild( + context.Background(), + parentID, + parentTimestamp, + pChainHeight-1, + ) + require.ErrorIs(err, errProposerWindowNotStarted) + } } From f5ac69a3d0ec11bb326ffc5106a3d6d1fa107955 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Dec 2023 18:15:06 +0100 Subject: [PATCH 075/111] MinDelayForProposer rework --- vms/proposervm/proposer/mock_windower.go | 4 +-- vms/proposervm/proposer/windower.go | 35 +++++++++++++++--------- vms/proposervm/vm.go | 4 +-- vms/proposervm/vm_test.go | 4 +-- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index eea021da273a..dc649016c3e7 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -70,10 +70,10 @@ func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3, arg } // MinDelayForProposer mocks base method. -func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 time.Time, arg4 ids.NodeID, arg5 time.Time) (time.Time, error) { +func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 time.Time, arg4 ids.NodeID, arg5 time.Time) (time.Duration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MinDelayForProposer", arg0, arg1, arg2, arg3, arg4, arg5) - ret0, _ := ret[0].(time.Time) + ret0, _ := ret[0].(time.Duration) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 738bfa9b0aa0..375acceec726 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -63,14 +63,23 @@ type Windower interface { maxWindows int, ) (time.Duration, error) + // In the Post Durango windowing scheme, every validator active + // at [pChainHeight] gets one and only one slot to propose a block. + // [ExpectedProposer] calculates which nodeID is scheduled to propose + // a block of height [blockHeight] at [blockTime]. ExpectedProposer( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, parentBlockTime, blockTime time.Time, ) (ids.NodeID, error) + // In the Post Durango windowing scheme, every validator active + // at [pChainHeight] gets one and only one slot to propose a block. + // [MinDelayForProposer] specifies how long [nodeID] needs to wait + // for its slot to start. Delay is specified as starting from [parentBlockTime]. + // For efficiency reasons, we cap the slot search to [MaxLookAheadWindow] delay. MinDelayForProposer( ctx context.Context, chainHeight, @@ -78,7 +87,7 @@ type Windower interface { parentBlockTime time.Time, nodeID ids.NodeID, startTime time.Time, - ) (time.Time, error) + ) (time.Duration, error) } // windower interfaces with P-Chain and it is responsible for calculating the @@ -159,7 +168,7 @@ func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, func (w *windower) ExpectedProposer( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, parentBlockTime, blockTime time.Time, @@ -171,7 +180,7 @@ func (w *windower) ExpectedProposer( var ( slot = uint64(blockTime.Sub(parentBlockTime) / WindowDuration) - seed = chainHeight ^ bits.Reverse64(slot) ^ w.chainSource + seed = blockHeight ^ bits.Reverse64(slot) ^ w.chainSource source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) ) @@ -196,23 +205,23 @@ func (w *windower) MinDelayForProposer( parentBlockTime time.Time, nodeID ids.NodeID, startTime time.Time, -) (time.Time, error) { +) (time.Duration, error) { validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { - return time.Time{}, err + return 0, err } var ( - res = startTime + delay = time.Duration(0) source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) sampler = sampler.NewDeterministicWeightedWithoutReplacement(source) ) if err := sampler.Initialize(validatorWeights); err != nil { - return time.Time{}, err + return 0, err } - for res.Sub(startTime) < MaxLookAheadWindow { + for delay < MaxLookAheadWindow { var ( slot = uint64(startTime.Sub(parentBlockTime) / WindowDuration) seed = chainHeight ^ bits.Reverse64(slot) ^ w.chainSource @@ -221,15 +230,15 @@ func (w *windower) MinDelayForProposer( source.Seed(seed) indices, err := sampler.Sample(1) if err != nil { - return time.Time{}, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) + return 0, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) } if validators[indices[0]].id == nodeID { - return res, nil + return delay, nil } - res = res.Add(WindowDuration) + delay += WindowDuration } - return time.Time{}, ErrNoSlotsScheduledInNextFuture + return 0, ErrNoSlotsScheduledInNextFuture } func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, error) { diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 9012ecc2c9e3..2a4c71149d6d 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -398,7 +398,7 @@ func (vm *VM) resetPostDurangoScheduler( parentTimestamp time.Time, currentTime time.Time, ) (time.Time, error) { - nextStartTime, err := vm.Windower.MinDelayForProposer( + delay, err := vm.Windower.MinDelayForProposer( ctx, blkHeight, pChainHeight, @@ -417,7 +417,7 @@ func (vm *VM) resetPostDurangoScheduler( zap.Error(err), ) } - return nextStartTime, err + return parentTimestamp.Add(delay), err } func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error) { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 4ef1e95b740d..2db9a3289cba 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -222,7 +222,7 @@ func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) vm.Clock.Set(vm.Clock.Time().Truncate(time.Second)) for { - nextTime, err := vm.MinDelayForProposer( + delay, err := vm.MinDelayForProposer( ctx, chainTip.Height()+1, pchainHeight, @@ -233,7 +233,7 @@ func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) switch err { case nil: - vm.Clock.Set(nextTime) + vm.Clock.Set(chainTip.Timestamp().Add(delay)) return nil case proposer.ErrNoSlotsScheduledInNextFuture: // repeat slot search From 341a37146e168bc750f044d1fa33c997197e6933 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Dec 2023 18:42:23 +0100 Subject: [PATCH 076/111] extended UTs --- vms/proposervm/proposer/windower_test.go | 35 ++++++++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 654c62b3bf83..9e03e57e6e0f 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -351,31 +351,54 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { blockTime = parentBlockTime.Add(time.Second) ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) - require.NoError(err) - require.Equal(validatorIDs[2], proposerID) + { + // base case. Next tests are variations on top of this. + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + require.NoError(err) + require.Equal(validatorIDs[2], proposerID) + + // proposerID is the scheduled proposer. It may start with no further delay + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) + require.NoError(err) + require.Zero(delay) + } { // proposerID won't change within the same slot blockTime = parentBlockTime.Add(WindowDuration).Add(-1 * time.Second) - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[2], proposerID) + + // proposerID is the scheduled proposer. It may start with no further delay + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) + require.NoError(err) + require.Zero(delay) } { // proposerID changes with new slot blockTime = parentBlockTime.Add(WindowDuration) - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[0], proposerID) + + // proposerID is the scheduled proposer. It may start with no further delay + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) + require.NoError(err) + require.Zero(delay) } { // proposerID changes with new slot blockTime = parentBlockTime.Add(2 * WindowDuration) - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[9], proposerID) + + // proposerID is the scheduled proposer. It may start with no further delay + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) + require.NoError(err) + require.Zero(delay) } } From 104603ab47e6a10b70bba6fe745b34bbd0a3c739 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Dec 2023 19:15:28 +0100 Subject: [PATCH 077/111] nits --- vms/proposervm/block.go | 2 +- vms/proposervm/proposer/windower.go | 2 +- vms/proposervm/vm.go | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 733c02e87ba0..ba44c65366f9 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -432,7 +432,7 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( // We need to reschedule the block builder to the next time we can try to // build a block. - nextStartTime, err := p.vm.resetPostDurangoScheduler( + nextStartTime, err := p.vm.getPostDurangoSlotTime( ctx, parentHeight+1, parentPChainHeight, diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 375acceec726..92072ab8bc6c 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -78,7 +78,7 @@ type Windower interface { // In the Post Durango windowing scheme, every validator active // at [pChainHeight] gets one and only one slot to propose a block. // [MinDelayForProposer] specifies how long [nodeID] needs to wait - // for its slot to start. Delay is specified as starting from [parentBlockTime]. + // for its slot to start. Delay is specified as starting from [startTime]. // For efficiency reasons, we cap the slot search to [MaxLookAheadWindow] delay. MinDelayForProposer( ctx context.Context, diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 2a4c71149d6d..0e28dd972f95 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -338,7 +338,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { parentTimestamp = blk.Timestamp() ) if vm.IsDurangoActivated(parentTimestamp) { - nextStartTime, err = vm.resetPostDurangoScheduler( + nextStartTime, err = vm.getPostDurangoSlotTime( ctx, blk.Height()+1, pChainHeight, @@ -346,7 +346,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { vm.Clock.Time().Truncate(time.Second), ) } else { - nextStartTime, err = vm.resetPreDurangoScheduler(ctx, blk, pChainHeight) + nextStartTime, err = vm.getPreDurangoSlotTime(ctx, blk, pChainHeight) } if err != nil { return nil @@ -361,7 +361,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { return nil } -func (vm *VM) resetPreDurangoScheduler( +func (vm *VM) getPreDurangoSlotTime( ctx context.Context, blk PostForkBlock, pChainHeight uint64, @@ -391,7 +391,7 @@ func (vm *VM) resetPreDurangoScheduler( return nextStartTime, nil } -func (vm *VM) resetPostDurangoScheduler( +func (vm *VM) getPostDurangoSlotTime( ctx context.Context, blkHeight uint64, pChainHeight uint64, @@ -417,7 +417,7 @@ func (vm *VM) resetPostDurangoScheduler( zap.Error(err), ) } - return parentTimestamp.Add(delay), err + return currentTime.Add(delay), err } func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error) { From 6d8509a39a8cff9c6c3c466cce4bc8720ae28509 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Dec 2023 22:57:55 +0100 Subject: [PATCH 078/111] reworked MinDelayForProposer --- vms/proposervm/block_test.go | 13 +++++++------ vms/proposervm/proposer/windower.go | 16 +++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 9d15c03bf6f9..4f257943724d 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -385,6 +385,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { pChainHeight uint64 = 1337 parentID = ids.GenerateTestID() parentTimestamp = time.Now().Truncate(time.Second) + now = parentTimestamp.Add(12 * time.Second) parentHeight uint64 = 1234 ) @@ -418,6 +419,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { Windower: windower, Scheduler: scheduler, } + vm.Clock.Set(now) blk := &postForkCommonComponents{ innerBlk: innerBlk, @@ -426,12 +428,11 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { { // no slots within inspected window - windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(time.Time{}, proposer.ErrNoSlotsScheduledInNextFuture).AnyTimes() + Return(time.Duration(0), proposer.ErrNoSlotsScheduledInNextFuture).AnyTimes() // we mock the scheduler setting the exact time we expect it to be reset to - expectedSchedulerTime := parentTimestamp.Add(proposer.MaxLookAheadWindow) + expectedSchedulerTime := now.Add(proposer.MaxLookAheadWindow) scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).AnyTimes() _, err = blk.buildChild( @@ -445,10 +446,10 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { { // a slot within inspected window - - expectedSchedulerTime := parentTimestamp.Add(proposer.MaxLookAheadWindow).Add(-1 * time.Minute) + delay := proposer.MaxLookAheadWindow - time.Minute + expectedSchedulerTime := now.Add(delay) windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(expectedSchedulerTime, nil).AnyTimes() + Return(delay, nil).AnyTimes() // we mock the scheduler setting the exact time we expect it to be reset to scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).AnyTimes() diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 92072ab8bc6c..7d997d13c138 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -212,7 +212,8 @@ func (w *windower) MinDelayForProposer( } var ( - delay = time.Duration(0) + slot = uint64(startTime.Sub(parentBlockTime) / WindowDuration) + source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) sampler = sampler.NewDeterministicWeightedWithoutReplacement(source) @@ -221,12 +222,8 @@ func (w *windower) MinDelayForProposer( return 0, err } - for delay < MaxLookAheadWindow { - var ( - slot = uint64(startTime.Sub(parentBlockTime) / WindowDuration) - seed = chainHeight ^ bits.Reverse64(slot) ^ w.chainSource - ) - + for time.Duration(slot)*WindowDuration < MaxLookAheadWindow { + seed := chainHeight ^ bits.Reverse64(slot) ^ w.chainSource source.Seed(seed) indices, err := sampler.Sample(1) if err != nil { @@ -234,9 +231,10 @@ func (w *windower) MinDelayForProposer( } if validators[indices[0]].id == nodeID { - return delay, nil + slotStartTime := parentBlockTime.Add(time.Duration(slot) * WindowDuration) + return math.Max(0, slotStartTime.Sub(startTime)), nil } - delay += WindowDuration + slot += 1 } return 0, ErrNoSlotsScheduledInNextFuture } From a737b0020eca76cfd50ed7fe26518aa6620780b7 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Wed, 13 Dec 2023 23:05:23 +0100 Subject: [PATCH 079/111] fixed min delay --- vms/proposervm/vm.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 0e28dd972f95..93cf16c6c786 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -417,6 +417,14 @@ func (vm *VM) getPostDurangoSlotTime( zap.Error(err), ) } + + // Note: The P-chain does not currently try to target any block time. It + // notifies the consensus engine as soon as a new block may be built. To + // avoid fast runs of blocks there is an additional minimum delay that + // validators can specify. This delay may be an issue for high performance, + // custom VMs. Until the P-chain is modified to target a specific block + // time, ProposerMinBlockDelay can be configured in the subnet config. + delay = math.Max(delay, vm.MinBlkDelay) return currentTime.Add(delay), err } From 1e539b8381386032ed209f34fd163c47565319b9 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 18:41:49 +0100 Subject: [PATCH 080/111] nit --- vms/proposervm/proposer/windower.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 7d997d13c138..5cdba9abc7b1 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -63,7 +63,7 @@ type Windower interface { maxWindows int, ) (time.Duration, error) - // In the Post Durango windowing scheme, every validator active + // In the Post-Durango windowing scheme, every validator active // at [pChainHeight] gets one and only one slot to propose a block. // [ExpectedProposer] calculates which nodeID is scheduled to propose // a block of height [blockHeight] at [blockTime]. @@ -75,7 +75,7 @@ type Windower interface { blockTime time.Time, ) (ids.NodeID, error) - // In the Post Durango windowing scheme, every validator active + // In the Post-Durango windowing scheme, every validator active // at [pChainHeight] gets one and only one slot to propose a block. // [MinDelayForProposer] specifies how long [nodeID] needs to wait // for its slot to start. Delay is specified as starting from [startTime]. From fe45d235c4a3f2d5fa00a3371c93b74c15118cc7 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 20:27:38 +0100 Subject: [PATCH 081/111] improved comments --- vms/proposervm/proposer/windower.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 5cdba9abc7b1..69fb0adf4bc6 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -64,7 +64,8 @@ type Windower interface { ) (time.Duration, error) // In the Post-Durango windowing scheme, every validator active - // at [pChainHeight] gets one and only one slot to propose a block. + // at [pChainHeight] gets specific slots it can propose in (instead + // of being able to propose from a given time on as it happens Pre-Durango). // [ExpectedProposer] calculates which nodeID is scheduled to propose // a block of height [blockHeight] at [blockTime]. ExpectedProposer( @@ -76,7 +77,8 @@ type Windower interface { ) (ids.NodeID, error) // In the Post-Durango windowing scheme, every validator active - // at [pChainHeight] gets one and only one slot to propose a block. + // at [pChainHeight] gets specific slots it can propose in (instead + // of being able to propose from a given time on as it happens Pre-Durango). // [MinDelayForProposer] specifies how long [nodeID] needs to wait // for its slot to start. Delay is specified as starting from [startTime]. // For efficiency reasons, we cap the slot search to [MaxLookAheadWindow] delay. From d7847c9e5817c650b5e67969e7384b7084ec25ab Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 20:31:43 +0100 Subject: [PATCH 082/111] added test case for edge of look ahead window --- vms/proposervm/proposer/windower_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 9e03e57e6e0f..f07dc585747d 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -401,4 +401,17 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { require.NoError(err) require.Zero(delay) } + + { + // ExpectedProposer can return the proposer starting the end of the lookup window + blockTime = parentBlockTime.Add(MaxLookAheadWindow) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + require.NoError(err) + require.Equal(validatorIDs[4], proposerID) + + // MinDelayForProposer will err when blockTime is at the end of the lookup window + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) + require.ErrorIs(err, ErrNoSlotsScheduledInNextFuture) + require.Zero(delay) + } } From 0bad92c9b17338a9f10a3a2ab6bbcce0f0d8f229 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 20:52:16 +0100 Subject: [PATCH 083/111] extended look ahead window --- vms/proposervm/proposer/windower.go | 8 +++++-- vms/proposervm/proposer/windower_test.go | 29 ++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 69fb0adf4bc6..8fca2eeceff3 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -214,7 +214,7 @@ func (w *windower) MinDelayForProposer( } var ( - slot = uint64(startTime.Sub(parentBlockTime) / WindowDuration) + slot = TimeToSlot(parentBlockTime, startTime) source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) @@ -224,7 +224,7 @@ func (w *windower) MinDelayForProposer( return 0, err } - for time.Duration(slot)*WindowDuration < MaxLookAheadWindow { + for time.Duration(slot)*WindowDuration <= MaxLookAheadWindow { seed := chainHeight ^ bits.Reverse64(slot) ^ w.chainSource source.Seed(seed) indices, err := sampler.Sample(1) @@ -272,3 +272,7 @@ func validatorsToWeight(validators []validatorData) []uint64 { } return weights } + +func TimeToSlot(baseTime, targetTime time.Time) uint64 { + return uint64(targetTime.Sub(baseTime) / WindowDuration) +} diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index f07dc585747d..98fa5d213480 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -409,9 +409,34 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { require.NoError(err) require.Equal(validatorIDs[4], proposerID) - // MinDelayForProposer will err when blockTime is at the end of the lookup window + // MinDelayForProposer won't err when blockTime is at the end of the lookup window delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.ErrorIs(err, ErrNoSlotsScheduledInNextFuture) + require.NoError(err) require.Zero(delay) } + + { + // ExpectedProposer can return the proposer starting right after end of the lookup window + blockTime = parentBlockTime.Add(MaxLookAheadWindow + WindowDuration - time.Second) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + require.NoError(err) + require.Equal(validatorIDs[4], proposerID) + + // MinDelayForProposer won't err when blockTime is at the end of the lookup window + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) + require.NoError(err) + require.Zero(delay) + } + + { + // ExpectedProposer can return the proposer starting right after end of the lookup window + blockTime = parentBlockTime.Add(MaxLookAheadWindow + WindowDuration) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + require.NoError(err) + require.Equal(validatorIDs[6], proposerID) + + // MinDelayForProposer won't err when blockTime is at the end of the lookup window + _, err = w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) + require.ErrorIs(err, ErrNoSlotsScheduledInNextFuture) + } } From 1f8bf7f16e28d4b194751a2ab5c48796a5db9087 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 22:01:55 +0100 Subject: [PATCH 084/111] MinDelayForProposer rework --- vms/proposervm/block_test.go | 4 ++-- vms/proposervm/proposer/windower.go | 14 +++++++++----- vms/proposervm/vm.go | 4 ++-- vms/proposervm/vm_test.go | 12 ++++++++---- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 4f257943724d..9ff631321b40 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -432,7 +432,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { Return(time.Duration(0), proposer.ErrNoSlotsScheduledInNextFuture).AnyTimes() // we mock the scheduler setting the exact time we expect it to be reset to - expectedSchedulerTime := now.Add(proposer.MaxLookAheadWindow) + expectedSchedulerTime := parentTimestamp.Add(proposer.MaxLookAheadWindow) scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).AnyTimes() _, err = blk.buildChild( @@ -447,7 +447,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { { // a slot within inspected window delay := proposer.MaxLookAheadWindow - time.Minute - expectedSchedulerTime := now.Add(delay) + expectedSchedulerTime := parentTimestamp.Add(delay) windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(delay, nil).AnyTimes() diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 8fca2eeceff3..2842eed7c51c 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -214,17 +214,19 @@ func (w *windower) MinDelayForProposer( } var ( - slot = TimeToSlot(parentBlockTime, startTime) + initialSlot = TimeToSlot(parentBlockTime, startTime) + finalSlot = uint64(MaxLookAheadWindow / WindowDuration) source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) sampler = sampler.NewDeterministicWeightedWithoutReplacement(source) ) + if err := sampler.Initialize(validatorWeights); err != nil { return 0, err } - for time.Duration(slot)*WindowDuration <= MaxLookAheadWindow { + for slot := initialSlot; slot <= finalSlot; slot++ { seed := chainHeight ^ bits.Reverse64(slot) ^ w.chainSource source.Seed(seed) indices, err := sampler.Sample(1) @@ -233,11 +235,10 @@ func (w *windower) MinDelayForProposer( } if validators[indices[0]].id == nodeID { - slotStartTime := parentBlockTime.Add(time.Duration(slot) * WindowDuration) - return math.Max(0, slotStartTime.Sub(startTime)), nil + return time.Duration(slot-initialSlot) * WindowDuration, nil } - slot += 1 } + return 0, ErrNoSlotsScheduledInNextFuture } @@ -274,5 +275,8 @@ func validatorsToWeight(validators []validatorData) []uint64 { } func TimeToSlot(baseTime, targetTime time.Time) uint64 { + if !targetTime.After(baseTime) { + return 0 + } return uint64(targetTime.Sub(baseTime) / WindowDuration) } diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 93cf16c6c786..9f4d571da379 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -410,7 +410,7 @@ func (vm *VM) getPostDurangoSlotTime( // This node is not scheduled to propose in any nearby slots. To avoid // costly iteration, stop iterating early and only continue iterating if // needed. - return currentTime.Add(proposer.MaxLookAheadWindow), nil + return parentTimestamp.Add(proposer.MaxLookAheadWindow), nil } if err != nil { vm.ctx.Log.Debug("failed to calculate min delay for proposer", @@ -425,7 +425,7 @@ func (vm *VM) getPostDurangoSlotTime( // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. delay = math.Max(delay, vm.MinBlkDelay) - return currentTime.Add(delay), err + return parentTimestamp.Add(delay), err } func (vm *VM) LastAccepted(ctx context.Context) (ids.ID, error) { diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 2db9a3289cba..e8930e16c58c 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -218,7 +218,10 @@ func initTestProposerVM( } func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) error { - ctx := context.Background() + var ( + ctx = context.Background() + parentTimestamp = chainTip.Timestamp() + ) vm.Clock.Set(vm.Clock.Time().Truncate(time.Second)) for { @@ -226,18 +229,19 @@ func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) ctx, chainTip.Height()+1, pchainHeight, - chainTip.Timestamp(), + parentTimestamp, vm.ctx.NodeID, vm.Clock.Time(), ) switch err { case nil: - vm.Clock.Set(chainTip.Timestamp().Add(delay)) + parentTimestamp = parentTimestamp.Add(delay) + vm.Clock.Set(parentTimestamp) return nil case proposer.ErrNoSlotsScheduledInNextFuture: // repeat slot search - vm.Clock.Set(vm.Clock.Time().Add(proposer.MaxLookAheadWindow)) + vm.Clock.Set(parentTimestamp.Add(proposer.MaxLookAheadWindow)) default: return err } From 302e8ac437a01e5066392d0f9f57df350fb763d1 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 23:11:20 +0100 Subject: [PATCH 085/111] some more MinDelayForProposer changes --- vms/proposervm/block_test.go | 2 +- vms/proposervm/proposer/mock_windower.go | 2 +- vms/proposervm/proposer/windower.go | 20 ++-- vms/proposervm/proposer/windower_test.go | 119 +++++++++++++---------- vms/proposervm/vm.go | 8 +- vms/proposervm/vm_test.go | 5 +- 6 files changed, 79 insertions(+), 77 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 9ff631321b40..4c383f383529 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -429,7 +429,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { { // no slots within inspected window windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(time.Duration(0), proposer.ErrNoSlotsScheduledInNextFuture).AnyTimes() + Return(proposer.MaxLookAheadWindow, nil).AnyTimes() // we mock the scheduler setting the exact time we expect it to be reset to expectedSchedulerTime := parentTimestamp.Add(proposer.MaxLookAheadWindow) diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index dc649016c3e7..29438a3bac88 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -70,7 +70,7 @@ func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3, arg } // MinDelayForProposer mocks base method. -func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 time.Time, arg4 ids.NodeID, arg5 time.Time) (time.Duration, error) { +func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 time.Time, arg4 ids.NodeID, arg5 uint64) (time.Duration, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "MinDelayForProposer", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(time.Duration) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 2842eed7c51c..eaf2fe59d124 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -30,14 +30,14 @@ const ( MaxBuildWindows = 60 MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes - MaxLookAheadWindow = time.Hour + MaxLookAheadSlots = 720 // 5 secs windows in 1 hour + MaxLookAheadWindow = MaxLookAheadSlots * WindowDuration ) var ( _ Windower = (*windower)(nil) - ErrNoProposersAvailable = errors.New("no proposers available") - ErrNoSlotsScheduledInNextFuture = errors.New("no slots scheduled in next future") + ErrNoProposersAvailable = errors.New("no proposers available") ) type Windower interface { @@ -88,7 +88,7 @@ type Windower interface { pChainHeight uint64, parentBlockTime time.Time, nodeID ids.NodeID, - startTime time.Time, + initialSlot uint64, ) (time.Duration, error) } @@ -206,7 +206,7 @@ func (w *windower) MinDelayForProposer( pChainHeight uint64, parentBlockTime time.Time, nodeID ids.NodeID, - startTime time.Time, + initialSlot uint64, ) (time.Duration, error) { validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { @@ -214,8 +214,7 @@ func (w *windower) MinDelayForProposer( } var ( - initialSlot = TimeToSlot(parentBlockTime, startTime) - finalSlot = uint64(MaxLookAheadWindow / WindowDuration) + maxSlot = initialSlot + MaxLookAheadSlots source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) @@ -226,7 +225,7 @@ func (w *windower) MinDelayForProposer( return 0, err } - for slot := initialSlot; slot <= finalSlot; slot++ { + for slot := initialSlot; slot < maxSlot; slot++ { seed := chainHeight ^ bits.Reverse64(slot) ^ w.chainSource source.Seed(seed) indices, err := sampler.Sample(1) @@ -235,11 +234,12 @@ func (w *windower) MinDelayForProposer( } if validators[indices[0]].id == nodeID { - return time.Duration(slot-initialSlot) * WindowDuration, nil + return time.Duration(slot) * WindowDuration, nil } } - return 0, ErrNoSlotsScheduledInNextFuture + // no slots scheduled for the max window we inspect. Return max delay + return time.Duration(maxSlot) * WindowDuration, nil } func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, error) { diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 98fa5d213480..13a7b127e640 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -348,95 +348,106 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { chainHeight = uint64(1) pChainHeight = uint64(0) parentBlockTime = time.Now().Truncate(time.Second) - blockTime = parentBlockTime.Add(time.Second) + currentSlot = uint64(0) ) { // base case. Next tests are variations on top of this. + var ( + expectedDelay = time.Duration(currentSlot) * WindowDuration + blockTime = parentBlockTime.Add(expectedDelay) + ) proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[2], proposerID) - - // proposerID is the scheduled proposer. It may start with no further delay - delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.NoError(err) - require.Zero(delay) - } - - { - // proposerID won't change within the same slot - blockTime = parentBlockTime.Add(WindowDuration).Add(-1 * time.Second) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) - require.NoError(err) - require.Equal(validatorIDs[2], proposerID) - - // proposerID is the scheduled proposer. It may start with no further delay - delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.NoError(err) - require.Zero(delay) } { // proposerID changes with new slot + var ( + currentSlot = uint64(1) + expectedDelay = time.Duration(currentSlot) * WindowDuration + blockTime = parentBlockTime.Add(expectedDelay) + ) blockTime = parentBlockTime.Add(WindowDuration) proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[0], proposerID) - - // proposerID is the scheduled proposer. It may start with no further delay - delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.NoError(err) - require.Zero(delay) } { // proposerID changes with new slot - blockTime = parentBlockTime.Add(2 * WindowDuration) + var ( + currentSlot = uint64(2) + expectedDelay = time.Duration(currentSlot) * WindowDuration + blockTime = parentBlockTime.Add(expectedDelay) + ) proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[9], proposerID) - - // proposerID is the scheduled proposer. It may start with no further delay - delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.NoError(err) - require.Zero(delay) } { - // ExpectedProposer can return the proposer starting the end of the lookup window - blockTime = parentBlockTime.Add(MaxLookAheadWindow) + // proposerID at last inspected slot + var ( + currentSlot = MaxLookAheadSlots + expectedDelay = time.Duration(currentSlot) * WindowDuration + blockTime = parentBlockTime.Add(expectedDelay) + ) proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[4], proposerID) - - // MinDelayForProposer won't err when blockTime is at the end of the lookup window - delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.NoError(err) - require.Zero(delay) } +} - { - // ExpectedProposer can return the proposer starting right after end of the lookup window - blockTime = parentBlockTime.Add(MaxLookAheadWindow + WindowDuration - time.Second) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) - require.NoError(err) - require.Equal(validatorIDs[4], proposerID) +func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { + require := require.New(t) - // MinDelayForProposer won't err when blockTime is at the end of the lookup window - delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.NoError(err) - require.Zero(delay) + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + + validatorsCount = 10 + ) + + validatorIDs := make([]ids.NodeID, validatorsCount) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, } - { - // ExpectedProposer can return the proposer starting right after end of the lookup window - blockTime = parentBlockTime.Add(MaxLookAheadWindow + WindowDuration) + w := New(vdrState, subnetID, chainID) + + var ( + dummyCtx = context.Background() + chainHeight = uint64(1) + pChainHeight = uint64(0) + parentBlockTime = time.Now().Truncate(time.Second) + ) + + for slot := uint64(0); slot < 3*MaxLookAheadSlots; slot++ { + var ( + expectedDelay = time.Duration(slot) * WindowDuration + blockTime = parentBlockTime.Add(expectedDelay) + ) proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) - require.Equal(validatorIDs[6], proposerID) - // MinDelayForProposer won't err when blockTime is at the end of the lookup window - _, err = w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, blockTime) - require.ErrorIs(err, ErrNoSlotsScheduledInNextFuture) + // proposerID is the scheduled proposer. It may start with the expected delay + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, slot) + require.NoError(err) + require.Equal(expectedDelay, delay) } } diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 9f4d571da379..f62fca9c42ab 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -404,14 +404,8 @@ func (vm *VM) getPostDurangoSlotTime( pChainHeight, parentTimestamp, vm.ctx.NodeID, - currentTime, + proposer.TimeToSlot(parentTimestamp, currentTime), ) - if errors.Is(err, proposer.ErrNoSlotsScheduledInNextFuture) { - // This node is not scheduled to propose in any nearby slots. To avoid - // costly iteration, stop iterating early and only continue iterating if - // needed. - return parentTimestamp.Add(proposer.MaxLookAheadWindow), nil - } if err != nil { vm.ctx.Log.Debug("failed to calculate min delay for proposer", zap.Error(err), diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index e8930e16c58c..7e909368d0e4 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -231,7 +231,7 @@ func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) pchainHeight, parentTimestamp, vm.ctx.NodeID, - vm.Clock.Time(), + proposer.TimeToSlot(parentTimestamp, vm.Clock.Time()), ) switch err { @@ -239,9 +239,6 @@ func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) parentTimestamp = parentTimestamp.Add(delay) vm.Clock.Set(parentTimestamp) return nil - case proposer.ErrNoSlotsScheduledInNextFuture: - // repeat slot search - vm.Clock.Set(parentTimestamp.Add(proposer.MaxLookAheadWindow)) default: return err } From 3d7e1ff58ca412df380c83c09e93e0078ea40403 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 23:21:51 +0100 Subject: [PATCH 086/111] appease linter --- vms/proposervm/block_test.go | 4 ++-- vms/proposervm/proposer/mock_windower.go | 8 ++++---- vms/proposervm/proposer/windower.go | 11 +++++------ vms/proposervm/proposer/windower_test.go | 3 +-- vms/proposervm/vm.go | 1 - vms/proposervm/vm_test.go | 1 - 6 files changed, 12 insertions(+), 16 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 4c383f383529..27f0f73dc88e 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -428,7 +428,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { { // no slots within inspected window - windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(proposer.MaxLookAheadWindow, nil).AnyTimes() // we mock the scheduler setting the exact time we expect it to be reset to @@ -448,7 +448,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { // a slot within inspected window delay := proposer.MaxLookAheadWindow - time.Minute expectedSchedulerTime := parentTimestamp.Add(delay) - windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(delay, nil).AnyTimes() // we mock the scheduler setting the exact time we expect it to be reset to diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index 29438a3bac88..6911ecd49bd8 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -70,18 +70,18 @@ func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3, arg } // MinDelayForProposer mocks base method. -func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 time.Time, arg4 ids.NodeID, arg5 uint64) (time.Duration, error) { +func (m *MockWindower) MinDelayForProposer(arg0 context.Context, arg1, arg2 uint64, arg3 ids.NodeID, arg4 uint64) (time.Duration, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "MinDelayForProposer", arg0, arg1, arg2, arg3, arg4, arg5) + ret := m.ctrl.Call(m, "MinDelayForProposer", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(time.Duration) ret1, _ := ret[1].(error) return ret0, ret1 } // MinDelayForProposer indicates an expected call of MinDelayForProposer. -func (mr *MockWindowerMockRecorder) MinDelayForProposer(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) MinDelayForProposer(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinDelayForProposer", reflect.TypeOf((*MockWindower)(nil).MinDelayForProposer), arg0, arg1, arg2, arg3, arg4, arg5) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MinDelayForProposer", reflect.TypeOf((*MockWindower)(nil).MinDelayForProposer), arg0, arg1, arg2, arg3, arg4) } // Proposers mocks base method. diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index eaf2fe59d124..8c673b9aaa8d 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -30,7 +30,7 @@ const ( MaxBuildWindows = 60 MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes - MaxLookAheadSlots = 720 // 5 secs windows in 1 hour + MaxLookAheadSlots = 720 // 1 hour MaxLookAheadWindow = MaxLookAheadSlots * WindowDuration ) @@ -80,13 +80,13 @@ type Windower interface { // at [pChainHeight] gets specific slots it can propose in (instead // of being able to propose from a given time on as it happens Pre-Durango). // [MinDelayForProposer] specifies how long [nodeID] needs to wait - // for its slot to start. Delay is specified as starting from [startTime]. - // For efficiency reasons, we cap the slot search to [MaxLookAheadWindow] delay. + // for its slot to start. Delay is specified as starting from slot zero start. + // (which is parent timestamp). For efficiency reasons, we cap the slot search + // to [MaxLookAheadWindow] slots. MinDelayForProposer( ctx context.Context, chainHeight, pChainHeight uint64, - parentBlockTime time.Time, nodeID ids.NodeID, initialSlot uint64, ) (time.Duration, error) @@ -204,7 +204,6 @@ func (w *windower) MinDelayForProposer( ctx context.Context, chainHeight, pChainHeight uint64, - parentBlockTime time.Time, nodeID ids.NodeID, initialSlot uint64, ) (time.Duration, error) { @@ -275,7 +274,7 @@ func validatorsToWeight(validators []validatorData) []uint64 { } func TimeToSlot(baseTime, targetTime time.Time) uint64 { - if !targetTime.After(baseTime) { + if targetTime.Before(baseTime) { return 0 } return uint64(targetTime.Sub(baseTime) / WindowDuration) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 13a7b127e640..adc058f493d9 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -369,7 +369,6 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { expectedDelay = time.Duration(currentSlot) * WindowDuration blockTime = parentBlockTime.Add(expectedDelay) ) - blockTime = parentBlockTime.Add(WindowDuration) proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) require.NoError(err) require.Equal(validatorIDs[0], proposerID) @@ -446,7 +445,7 @@ func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { require.NoError(err) // proposerID is the scheduled proposer. It may start with the expected delay - delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, proposerID, slot) + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, proposerID, slot) require.NoError(err) require.Equal(expectedDelay, delay) } diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index f62fca9c42ab..07e674df58b6 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -402,7 +402,6 @@ func (vm *VM) getPostDurangoSlotTime( ctx, blkHeight, pChainHeight, - parentTimestamp, vm.ctx.NodeID, proposer.TimeToSlot(parentTimestamp, currentTime), ) diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 7e909368d0e4..975615548b07 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -229,7 +229,6 @@ func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) ctx, chainTip.Height()+1, pchainHeight, - parentTimestamp, vm.ctx.NodeID, proposer.TimeToSlot(parentTimestamp, vm.Clock.Time()), ) From 971db238d08dce5c88dcf92b8deb859c1e7ca46c Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 23:31:51 +0100 Subject: [PATCH 087/111] changed ExpectedProposer interface --- vms/proposervm/block.go | 6 +-- vms/proposervm/block_test.go | 4 +- vms/proposervm/proposer/mock_windower.go | 8 +-- vms/proposervm/proposer/windower.go | 23 ++++---- vms/proposervm/proposer/windower_test.go | 68 +++++++++--------------- 5 files changed, 42 insertions(+), 67 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index ba44c65366f9..81e62474a98b 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -376,8 +376,7 @@ func (p *postForkCommonComponents) verifyPostDurangoBlockDelay( ctx, blkHeight, parentPChainHeight, - parentTimestamp, - blkTimestamp, + proposer.TimeToSlot(parentTimestamp, blkTimestamp), ) if err != nil { p.vm.ctx.Log.Error("unexpected block verification failure", @@ -406,8 +405,7 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( ctx, parentHeight+1, parentPChainHeight, - parentTimestamp, - newTimestamp, + proposer.TimeToSlot(parentTimestamp, newTimestamp), ) if err != nil { p.vm.ctx.Log.Error("unexpected build block failure", diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 27f0f73dc88e..6233abcdec0d 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -66,7 +66,7 @@ func TestPostForkCommonComponents_buildChild(t *testing.T) { vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() windower := proposer.NewMockWindower(ctrl) - windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nodeID, nil).AnyTimes() + windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nodeID, nil).AnyTimes() pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(err) @@ -396,7 +396,7 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { vdrState.EXPECT().GetMinimumHeight(context.Background()).Return(pChainHeight, nil).AnyTimes() windower := proposer.NewMockWindower(ctrl) - windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). + windower.EXPECT().ExpectedProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). Return(selectedProposer, nil).AnyTimes() // return a proposer different from thisNode, to check whether scheduler is reset scheduler := scheduler.NewMockScheduler(ctrl) diff --git a/vms/proposervm/proposer/mock_windower.go b/vms/proposervm/proposer/mock_windower.go index 6911ecd49bd8..7df10ee28bcf 100644 --- a/vms/proposervm/proposer/mock_windower.go +++ b/vms/proposervm/proposer/mock_windower.go @@ -55,18 +55,18 @@ func (mr *MockWindowerMockRecorder) Delay(arg0, arg1, arg2, arg3, arg4 interface } // ExpectedProposer mocks base method. -func (m *MockWindower) ExpectedProposer(arg0 context.Context, arg1, arg2 uint64, arg3, arg4 time.Time) (ids.NodeID, error) { +func (m *MockWindower) ExpectedProposer(arg0 context.Context, arg1, arg2, arg3 uint64) (ids.NodeID, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ExpectedProposer", arg0, arg1, arg2, arg3, arg4) + ret := m.ctrl.Call(m, "ExpectedProposer", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(ids.NodeID) ret1, _ := ret[1].(error) return ret0, ret1 } // ExpectedProposer indicates an expected call of ExpectedProposer. -func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { +func (mr *MockWindowerMockRecorder) ExpectedProposer(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExpectedProposer", reflect.TypeOf((*MockWindower)(nil).ExpectedProposer), arg0, arg1, arg2, arg3, arg4) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExpectedProposer", reflect.TypeOf((*MockWindower)(nil).ExpectedProposer), arg0, arg1, arg2, arg3) } // MinDelayForProposer mocks base method. diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 8c673b9aaa8d..3461768570ae 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -30,8 +30,8 @@ const ( MaxBuildWindows = 60 MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes - MaxLookAheadSlots = 720 // 1 hour - MaxLookAheadWindow = MaxLookAheadSlots * WindowDuration + MaxLookAheadSlots uint64 = 720 // 1 hour + MaxLookAheadWindow = time.Duration(MaxLookAheadSlots) * WindowDuration ) var ( @@ -67,13 +67,12 @@ type Windower interface { // at [pChainHeight] gets specific slots it can propose in (instead // of being able to propose from a given time on as it happens Pre-Durango). // [ExpectedProposer] calculates which nodeID is scheduled to propose - // a block of height [blockHeight] at [blockTime]. + // a block of height [blockHeight] at [slot]. ExpectedProposer( ctx context.Context, blockHeight, - pChainHeight uint64, - parentBlockTime, - blockTime time.Time, + pChainHeight, + slot uint64, ) (ids.NodeID, error) // In the Post-Durango windowing scheme, every validator active @@ -171,9 +170,8 @@ func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, func (w *windower) ExpectedProposer( ctx context.Context, blockHeight, - pChainHeight uint64, - parentBlockTime, - blockTime time.Time, + pChainHeight, + slot uint64, ) (ids.NodeID, error) { validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { @@ -181,7 +179,6 @@ func (w *windower) ExpectedProposer( } var ( - slot = uint64(blockTime.Sub(parentBlockTime) / WindowDuration) seed = blockHeight ^ bits.Reverse64(slot) ^ w.chainSource source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) @@ -205,7 +202,7 @@ func (w *windower) MinDelayForProposer( chainHeight, pChainHeight uint64, nodeID ids.NodeID, - initialSlot uint64, + slot uint64, ) (time.Duration, error) { validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { @@ -213,7 +210,7 @@ func (w *windower) MinDelayForProposer( } var ( - maxSlot = initialSlot + MaxLookAheadSlots + maxSlot = slot + MaxLookAheadSlots source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) @@ -224,7 +221,7 @@ func (w *windower) MinDelayForProposer( return 0, err } - for slot := initialSlot; slot < maxSlot; slot++ { + for slot := slot; slot < maxSlot; slot++ { seed := chainHeight ^ bits.Reverse64(slot) ^ w.chainSource source.Seed(seed) indices, err := sampler.Sample(1) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index adc058f493d9..c31e52a8ac9d 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -38,12 +38,13 @@ func TestWindowerNoValidators(t *testing.T) { pChainHeight uint64 = 0 parentBlockTime = time.Now().Truncate(time.Second) blockTime = parentBlockTime.Add(time.Second) + slot = TimeToSlot(parentBlockTime, blockTime) ) delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) require.Zero(delay) - expectedProposer, err := w.ExpectedProposer(context.Background(), chainHeight, pChainHeight, parentBlockTime, blockTime) + expectedProposer, err := w.ExpectedProposer(context.Background(), chainHeight, pChainHeight, slot) require.ErrorIs(err, ErrNoProposersAvailable) require.Equal(ids.EmptyNodeID, expectedProposer) } @@ -244,14 +245,15 @@ func TestExpectedProposerChangeByHeight(t *testing.T) { pChainHeight = uint64(0) parentBlockTime = time.Now().Truncate(time.Second) blockTime = parentBlockTime.Add(time.Second) + slot = TimeToSlot(parentBlockTime, blockTime) ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) require.NoError(err) require.Equal(validatorIDs[2], proposerID) chainHeight = 2 - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) require.NoError(err) require.Equal(validatorIDs[1], proposerID) } @@ -302,13 +304,14 @@ func TestExpectedProposerChangeByChain(t *testing.T) { pChainHeight = uint64(0) parentBlockTime = time.Now().Truncate(time.Second) blockTime = parentBlockTime.Add(time.Second) + slot = TimeToSlot(parentBlockTime, blockTime) ) - proposerID, err := w0.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err := w0.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) require.NoError(err) require.Equal(validatorIDs[5], proposerID) - proposerID, err = w1.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err = w1.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) require.NoError(err) require.Equal(validatorIDs[3], proposerID) } @@ -344,56 +347,38 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { w := New(vdrState, subnetID, chainID) var ( - dummyCtx = context.Background() - chainHeight = uint64(1) - pChainHeight = uint64(0) - parentBlockTime = time.Now().Truncate(time.Second) - currentSlot = uint64(0) + dummyCtx = context.Background() + chainHeight = uint64(1) + pChainHeight = uint64(0) ) { - // base case. Next tests are variations on top of this. - var ( - expectedDelay = time.Duration(currentSlot) * WindowDuration - blockTime = parentBlockTime.Add(expectedDelay) - ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + currentSlot := uint64(0) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) require.NoError(err) require.Equal(validatorIDs[2], proposerID) } { // proposerID changes with new slot - var ( - currentSlot = uint64(1) - expectedDelay = time.Duration(currentSlot) * WindowDuration - blockTime = parentBlockTime.Add(expectedDelay) - ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + currentSlot := uint64(1) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) require.NoError(err) require.Equal(validatorIDs[0], proposerID) } { // proposerID changes with new slot - var ( - currentSlot = uint64(2) - expectedDelay = time.Duration(currentSlot) * WindowDuration - blockTime = parentBlockTime.Add(expectedDelay) - ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + currentSlot := uint64(2) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) require.NoError(err) require.Equal(validatorIDs[9], proposerID) } { // proposerID at last inspected slot - var ( - currentSlot = MaxLookAheadSlots - expectedDelay = time.Duration(currentSlot) * WindowDuration - blockTime = parentBlockTime.Add(expectedDelay) - ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + currentSlot := MaxLookAheadSlots + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) require.NoError(err) require.Equal(validatorIDs[4], proposerID) } @@ -430,23 +415,18 @@ func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { w := New(vdrState, subnetID, chainID) var ( - dummyCtx = context.Background() - chainHeight = uint64(1) - pChainHeight = uint64(0) - parentBlockTime = time.Now().Truncate(time.Second) + dummyCtx = context.Background() + chainHeight = uint64(1) + pChainHeight = uint64(0) ) for slot := uint64(0); slot < 3*MaxLookAheadSlots; slot++ { - var ( - expectedDelay = time.Duration(slot) * WindowDuration - blockTime = parentBlockTime.Add(expectedDelay) - ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, parentBlockTime, blockTime) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) require.NoError(err) // proposerID is the scheduled proposer. It may start with the expected delay delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, proposerID, slot) require.NoError(err) - require.Equal(expectedDelay, delay) + require.Equal(time.Duration(slot)*WindowDuration, delay) } } From c451ff187de9a7c8f8949491cd103fbc612ef1a4 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 23:37:04 +0100 Subject: [PATCH 088/111] simplified test --- vms/proposervm/proposer/windower_test.go | 34 ++++++------------------ 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index c31e52a8ac9d..352a88679241 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -352,35 +352,17 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { pChainHeight = uint64(0) ) - { - currentSlot := uint64(0) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) - require.NoError(err) - require.Equal(validatorIDs[2], proposerID) - } - - { - // proposerID changes with new slot - currentSlot := uint64(1) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) - require.NoError(err) - require.Equal(validatorIDs[0], proposerID) - } - - { - // proposerID changes with new slot - currentSlot := uint64(2) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) - require.NoError(err) - require.Equal(validatorIDs[9], proposerID) + expectedProposers := map[uint64]ids.NodeID{ + 0: validatorIDs[2], + 1: validatorIDs[0], + 2: validatorIDs[9], + MaxLookAheadSlots: validatorIDs[4], } - { - // proposerID at last inspected slot - currentSlot := MaxLookAheadSlots - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, currentSlot) + for slot, expectedProposerID := range expectedProposers { + actualProposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) require.NoError(err) - require.Equal(validatorIDs[4], proposerID) + require.Equal(expectedProposerID, actualProposerID) } } From 5007103b6a5d3450f55ac288b4164db99b5dbae7 Mon Sep 17 00:00:00 2001 From: Alberto Benegiamo Date: Thu, 14 Dec 2023 23:43:50 +0100 Subject: [PATCH 089/111] nit --- vms/proposervm/block.go | 2 +- vms/proposervm/vm.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 81e62474a98b..97d1dfa06a26 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -434,8 +434,8 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( ctx, parentHeight+1, parentPChainHeight, + proposer.TimeToSlot(parentTimestamp, newTimestamp), parentTimestamp, - newTimestamp, ) if err != nil { p.vm.ctx.Log.Error("failed to reset block builder scheduler", diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index 07e674df58b6..d4691846af1c 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -342,8 +342,8 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { ctx, blk.Height()+1, pChainHeight, + proposer.TimeToSlot(blk.Timestamp(), vm.Clock.Time().Truncate(time.Second)), blk.Timestamp(), - vm.Clock.Time().Truncate(time.Second), ) } else { nextStartTime, err = vm.getPreDurangoSlotTime(ctx, blk, pChainHeight) @@ -393,17 +393,17 @@ func (vm *VM) getPreDurangoSlotTime( func (vm *VM) getPostDurangoSlotTime( ctx context.Context, - blkHeight uint64, - pChainHeight uint64, + blkHeight, + pChainHeight, + slot uint64, parentTimestamp time.Time, - currentTime time.Time, ) (time.Time, error) { delay, err := vm.Windower.MinDelayForProposer( ctx, blkHeight, pChainHeight, vm.ctx.NodeID, - proposer.TimeToSlot(parentTimestamp, currentTime), + slot, ) if err != nil { vm.ctx.Log.Debug("failed to calculate min delay for proposer", From b18bc5b7d3a9fd96658e29d876a36767cb07c421 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 14 Dec 2023 17:56:28 -0500 Subject: [PATCH 090/111] nit --- vms/proposervm/block.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 97d1dfa06a26..4065f72cedea 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -401,11 +401,12 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( newTimestamp time.Time, ) error { parentHeight := p.innerBlk.Height() + slot := proposer.TimeToSlot(parentTimestamp, newTimestamp) expectedProposerID, err := p.vm.Windower.ExpectedProposer( ctx, parentHeight+1, parentPChainHeight, - proposer.TimeToSlot(parentTimestamp, newTimestamp), + slot, ) if err != nil { p.vm.ctx.Log.Error("unexpected build block failure", @@ -425,6 +426,7 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( p.vm.ctx.Log.Debug("build block dropped", zap.Time("parentTimestamp", parentTimestamp), zap.Time("blockTimestamp", newTimestamp), + zap.Uint64("slot", slot), zap.Stringer("expectedProposer", expectedProposerID), ) @@ -434,7 +436,7 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( ctx, parentHeight+1, parentPChainHeight, - proposer.TimeToSlot(parentTimestamp, newTimestamp), + slot, parentTimestamp, ) if err != nil { From d0840da65660b15108ee0491f10d16be6665bbc5 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 14 Dec 2023 17:58:15 -0500 Subject: [PATCH 091/111] nit --- vms/proposervm/block.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 4065f72cedea..bd971ea9ba58 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -401,12 +401,12 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( newTimestamp time.Time, ) error { parentHeight := p.innerBlk.Height() - slot := proposer.TimeToSlot(parentTimestamp, newTimestamp) + currentSlot := proposer.TimeToSlot(parentTimestamp, newTimestamp) expectedProposerID, err := p.vm.Windower.ExpectedProposer( ctx, parentHeight+1, parentPChainHeight, - slot, + currentSlot, ) if err != nil { p.vm.ctx.Log.Error("unexpected build block failure", @@ -426,7 +426,7 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( p.vm.ctx.Log.Debug("build block dropped", zap.Time("parentTimestamp", parentTimestamp), zap.Time("blockTimestamp", newTimestamp), - zap.Uint64("slot", slot), + zap.Uint64("slot", currentSlot), zap.Stringer("expectedProposer", expectedProposerID), ) @@ -436,7 +436,7 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( ctx, parentHeight+1, parentPChainHeight, - slot, + currentSlot+1, // We know we aren't the proposer for the current slot parentTimestamp, ) if err != nil { From 4d7776f464edc97aa0cec3d5b473ffe77669741f Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Thu, 14 Dec 2023 18:09:47 -0500 Subject: [PATCH 092/111] nit --- vms/proposervm/block_test.go | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/vms/proposervm/block_test.go b/vms/proposervm/block_test.go index 6233abcdec0d..8297e3681b2c 100644 --- a/vms/proposervm/block_test.go +++ b/vms/proposervm/block_test.go @@ -426,33 +426,20 @@ func TestPostDurangoBuildChildResetScheduler(t *testing.T) { vm: vm, } - { - // no slots within inspected window - windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(proposer.MaxLookAheadWindow, nil).AnyTimes() - - // we mock the scheduler setting the exact time we expect it to be reset to - expectedSchedulerTime := parentTimestamp.Add(proposer.MaxLookAheadWindow) - scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).AnyTimes() - - _, err = blk.buildChild( - context.Background(), - parentID, - parentTimestamp, - pChainHeight-1, - ) - require.ErrorIs(err, errProposerWindowNotStarted) + delays := []time.Duration{ + proposer.MaxLookAheadWindow - time.Minute, + proposer.MaxLookAheadWindow, + proposer.MaxLookAheadWindow + time.Minute, } - { - // a slot within inspected window - delay := proposer.MaxLookAheadWindow - time.Minute - expectedSchedulerTime := parentTimestamp.Add(delay) + for _, delay := range delays { windower.EXPECT().MinDelayForProposer(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). - Return(delay, nil).AnyTimes() + Return(delay, nil).Times(1) - // we mock the scheduler setting the exact time we expect it to be reset to - scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).AnyTimes() + // we mock the scheduler setting the exact time we expect it to be reset + // to + expectedSchedulerTime := parentTimestamp.Add(delay) + scheduler.EXPECT().SetBuildBlockTime(expectedSchedulerTime).Times(1) _, err = blk.buildChild( context.Background(), From e299aaba4609a49c7a625ce3d550412529f8e1bc Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 10:55:08 -0500 Subject: [PATCH 093/111] nits --- vms/proposervm/proposer/windower.go | 76 ++++++++++++++---------- vms/proposervm/proposer/windower_test.go | 63 ++++++++++---------- vms/proposervm/vm.go | 7 ++- 3 files changed, 80 insertions(+), 66 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 3461768570ae..ce3473a67499 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -30,8 +30,8 @@ const ( MaxBuildWindows = 60 MaxBuildDelay = MaxBuildWindows * WindowDuration // 5 minutes - MaxLookAheadSlots uint64 = 720 // 1 hour - MaxLookAheadWindow = time.Duration(MaxLookAheadSlots) * WindowDuration + MaxLookAheadSlots = 720 + MaxLookAheadWindow = MaxLookAheadSlots * WindowDuration // 1 hour ) var ( @@ -41,33 +41,33 @@ var ( ) type Windower interface { - // Proposers returns the proposer list for building a block at [chainHeight] + // Proposers returns the proposer list for building a block at [blockHeight] // when the validator set is defined at [pChainHeight]. The list is returned // in order. The minimum delay of a validator is the index they appear times // [WindowDuration]. Proposers( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, maxWindows int, ) ([]ids.NodeID, error) // Delay returns the amount of time that [validatorID] must wait before - // building a block at [chainHeight] when the validator set is defined at + // building a block at [blockHeight] when the validator set is defined at // [pChainHeight]. Delay( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int, ) (time.Duration, error) - // In the Post-Durango windowing scheme, every validator active - // at [pChainHeight] gets specific slots it can propose in (instead - // of being able to propose from a given time on as it happens Pre-Durango). - // [ExpectedProposer] calculates which nodeID is scheduled to propose - // a block of height [blockHeight] at [slot]. + // In the Post-Durango windowing scheme, every validator active at + // [pChainHeight] gets specific slots it can propose in (instead of being + // able to propose from a given time on as it happens Pre-Durango). + // [ExpectedProposer] calculates which nodeID is scheduled to propose a + // block of height [blockHeight] at [slot]. ExpectedProposer( ctx context.Context, blockHeight, @@ -75,16 +75,16 @@ type Windower interface { slot uint64, ) (ids.NodeID, error) - // In the Post-Durango windowing scheme, every validator active - // at [pChainHeight] gets specific slots it can propose in (instead - // of being able to propose from a given time on as it happens Pre-Durango). - // [MinDelayForProposer] specifies how long [nodeID] needs to wait - // for its slot to start. Delay is specified as starting from slot zero start. - // (which is parent timestamp). For efficiency reasons, we cap the slot search - // to [MaxLookAheadWindow] slots. + // In the Post-Durango windowing scheme, every validator active at + // [pChainHeight] gets specific slots it can propose in (instead of being + // able to propose from a given time on as it happens Pre-Durango). + // [MinDelayForProposer] specifies how long [nodeID] needs to wait for its + // slot to start. Delay is specified as starting from slot zero start. + // (which is parent timestamp). For efficiency reasons, we cap the slot + // search to [MaxLookAheadWindow] slots. MinDelayForProposer( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, nodeID ids.NodeID, initialSlot uint64, @@ -108,14 +108,16 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { } } -func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { +func (w *windower) Proposers(ctx context.Context, blockHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { return nil, err } + // Note: The 32-bit prng is used here for legacy reasons. All other usages + // of a prng in this file should use the 64-bit version. var ( - seed = chainHeight ^ w.chainSource + seed = preDurangoSeed(w.chainSource, blockHeight) source = prng.NewMT19937() validatorWeights = validatorsToWeight(validators) ) @@ -147,12 +149,12 @@ func (w *windower) Proposers(ctx context.Context, chainHeight, pChainHeight uint return nodeIDs, nil } -func (w *windower) Delay(ctx context.Context, chainHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { +func (w *windower) Delay(ctx context.Context, blockHeight, pChainHeight uint64, validatorID ids.NodeID, maxWindows int) (time.Duration, error) { if validatorID == ids.EmptyNodeID { return time.Duration(maxWindows) * WindowDuration, nil } - proposers, err := w.Proposers(ctx, chainHeight, pChainHeight, maxWindows) + proposers, err := w.Proposers(ctx, blockHeight, pChainHeight, maxWindows) if err != nil { return 0, err } @@ -179,7 +181,7 @@ func (w *windower) ExpectedProposer( } var ( - seed = blockHeight ^ bits.Reverse64(slot) ^ w.chainSource + seed = postDurangoSeed(w.chainSource, blockHeight, slot) source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) ) @@ -199,7 +201,7 @@ func (w *windower) ExpectedProposer( func (w *windower) MinDelayForProposer( ctx context.Context, - chainHeight, + blockHeight, pChainHeight uint64, nodeID ids.NodeID, slot uint64, @@ -222,7 +224,7 @@ func (w *windower) MinDelayForProposer( } for slot := slot; slot < maxSlot; slot++ { - seed := chainHeight ^ bits.Reverse64(slot) ^ w.chainSource + seed := postDurangoSeed(w.chainSource, blockHeight, slot) source.Seed(seed) indices, err := sampler.Sample(1) if err != nil { @@ -262,6 +264,13 @@ func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([ return validators, nil } +func TimeToSlot(baseTime, targetTime time.Time) uint64 { + if targetTime.Before(baseTime) { + return 0 + } + return uint64(targetTime.Sub(baseTime) / WindowDuration) +} + func validatorsToWeight(validators []validatorData) []uint64 { weights := make([]uint64, len(validators)) for i, validator := range validators { @@ -270,9 +279,14 @@ func validatorsToWeight(validators []validatorData) []uint64 { return weights } -func TimeToSlot(baseTime, targetTime time.Time) uint64 { - if targetTime.Before(baseTime) { - return 0 - } - return uint64(targetTime.Sub(baseTime) / WindowDuration) +func preDurangoSeed(chainSource, height uint64) uint64 { + return chainSource ^ height +} + +func postDurangoSeed(chainSource, height, slot uint64) uint64 { + // Slot is reversed to utilize a different state space in the seed than the + // height. If the slot was not reversed the state space would collide, + // biasing the seed generation. For example, without reversing the slot + // postDurangoSeed(0,0,1) would equal postDurangoSeed(0,1,0). + return chainSource ^ height ^ bits.Reverse64(slot) } diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 352a88679241..e1b0413ee73b 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -240,22 +240,21 @@ func TestExpectedProposerChangeByHeight(t *testing.T) { w := New(vdrState, subnetID, chainID) var ( - dummyCtx = context.Background() - chainHeight = uint64(1) - pChainHeight = uint64(0) - parentBlockTime = time.Now().Truncate(time.Second) - blockTime = parentBlockTime.Add(time.Second) - slot = TimeToSlot(parentBlockTime, blockTime) + dummyCtx = context.Background() + pChainHeight uint64 = 0 + slot uint64 = 0 ) - proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) - require.NoError(err) - require.Equal(validatorIDs[2], proposerID) + expectedProposers := map[uint64]ids.NodeID{ + 1: validatorIDs[2], + 2: validatorIDs[1], + } - chainHeight = 2 - proposerID, err = w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) - require.NoError(err) - require.Equal(validatorIDs[1], proposerID) + for chainHeight, expectedProposerID := range expectedProposers { + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + require.Equal(expectedProposerID, proposerID) + } } func TestExpectedProposerChangeByChain(t *testing.T) { @@ -295,25 +294,24 @@ func TestExpectedProposerChangeByChain(t *testing.T) { }, } - w0 := New(vdrState, subnetID, chainID0) - w1 := New(vdrState, subnetID, chainID1) - var ( - dummyCtx = context.Background() - chainHeight = uint64(1) - pChainHeight = uint64(0) - parentBlockTime = time.Now().Truncate(time.Second) - blockTime = parentBlockTime.Add(time.Second) - slot = TimeToSlot(parentBlockTime, blockTime) + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + slot uint64 = 0 ) - proposerID, err := w0.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) - require.NoError(err) - require.Equal(validatorIDs[5], proposerID) + expectedProposers := map[ids.ID]ids.NodeID{ + chainID0: validatorIDs[5], + chainID1: validatorIDs[3], + } - proposerID, err = w1.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) - require.NoError(err) - require.Equal(validatorIDs[3], proposerID) + for chainID, expectedProposerID := range expectedProposers { + w := New(vdrState, subnetID, chainID) + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + require.Equal(expectedProposerID, proposerID) + } } func TestExpectedProposerChangeBySlot(t *testing.T) { @@ -347,9 +345,9 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { w := New(vdrState, subnetID, chainID) var ( - dummyCtx = context.Background() - chainHeight = uint64(1) - pChainHeight = uint64(0) + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 ) expectedProposers := map[uint64]ids.NodeID{ @@ -406,7 +404,8 @@ func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) require.NoError(err) - // proposerID is the scheduled proposer. It may start with the expected delay + // proposerID is the scheduled proposer. It should start with the + // expected delay delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, proposerID, slot) require.NoError(err) require.Equal(time.Duration(slot)*WindowDuration, delay) diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index d4691846af1c..cb14aae12ee2 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -338,12 +338,13 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { parentTimestamp = blk.Timestamp() ) if vm.IsDurangoActivated(parentTimestamp) { + currentTime := vm.Clock.Time().Truncate(time.Second) nextStartTime, err = vm.getPostDurangoSlotTime( ctx, blk.Height()+1, pChainHeight, - proposer.TimeToSlot(blk.Timestamp(), vm.Clock.Time().Truncate(time.Second)), - blk.Timestamp(), + proposer.TimeToSlot(parentTimestamp, currentTime), + parentTimestamp, ) } else { nextStartTime, err = vm.getPreDurangoSlotTime(ctx, blk, pChainHeight) @@ -355,7 +356,7 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { vm.ctx.Log.Debug("set preference", zap.Stringer("blkID", blk.ID()), - zap.Time("blockTimestamp", blk.Timestamp()), + zap.Time("blockTimestamp", parentTimestamp), zap.Time("nextStartTime", nextStartTime), ) return nil From a239d6160744acbc2f37dfdfd01a9cdf08e5eae4 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 11:37:42 -0500 Subject: [PATCH 094/111] expand tests --- vms/proposervm/proposer/windower_test.go | 100 +++++++++++++++++++++-- 1 file changed, 91 insertions(+), 9 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index e1b0413ee73b..bc6bd0b409ac 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -34,11 +34,9 @@ func TestWindowerNoValidators(t *testing.T) { w := New(vdrState, subnetID, chainID) var ( - chainHeight uint64 = 1 - pChainHeight uint64 = 0 - parentBlockTime = time.Now().Truncate(time.Second) - blockTime = parentBlockTime.Add(time.Second) - slot = TimeToSlot(parentBlockTime, blockTime) + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + slot uint64 = 1 ) delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) require.NoError(err) @@ -350,11 +348,38 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { pChainHeight uint64 = 0 ) + proposers := []ids.NodeID{ + validatorIDs[2], + validatorIDs[0], + validatorIDs[9], + validatorIDs[7], + validatorIDs[0], + validatorIDs[3], + validatorIDs[3], + validatorIDs[3], + validatorIDs[3], + validatorIDs[3], + validatorIDs[4], + validatorIDs[0], + validatorIDs[6], + validatorIDs[3], + validatorIDs[2], + validatorIDs[1], + validatorIDs[6], + validatorIDs[0], + validatorIDs[5], + validatorIDs[1], + validatorIDs[9], + validatorIDs[6], + validatorIDs[0], + validatorIDs[8], + } expectedProposers := map[uint64]ids.NodeID{ - 0: validatorIDs[2], - 1: validatorIDs[0], - 2: validatorIDs[9], - MaxLookAheadSlots: validatorIDs[4], + MaxLookAheadSlots: validatorIDs[4], + MaxLookAheadSlots + 1: validatorIDs[6], + } + for slot, expectedProposerID := range proposers { + expectedProposers[uint64(slot)] = expectedProposerID } for slot, expectedProposerID := range expectedProposers { @@ -411,3 +436,60 @@ func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { require.Equal(time.Duration(slot)*WindowDuration, delay) } } + +func TestMinDelayForProposer(t *testing.T) { + require := require.New(t) + + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + + validatorsCount = 10 + ) + + validatorIDs := make([]ids.NodeID, validatorsCount) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + + w := New(vdrState, subnetID, chainID) + + var ( + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 + slot uint64 = 0 + ) + + expectedDelays := map[ids.NodeID]time.Duration{ + validatorIDs[0]: 1 * WindowDuration, + validatorIDs[1]: 15 * WindowDuration, + validatorIDs[2]: 0 * WindowDuration, + validatorIDs[3]: 5 * WindowDuration, + validatorIDs[4]: 10 * WindowDuration, + validatorIDs[5]: 18 * WindowDuration, + validatorIDs[6]: 12 * WindowDuration, + validatorIDs[7]: 3 * WindowDuration, + validatorIDs[8]: 23 * WindowDuration, + validatorIDs[9]: 2 * WindowDuration, + } + + for nodeID, expectedDelay := range expectedDelays { + delay, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, nodeID, slot) + require.NoError(err) + require.Equal(expectedDelay, delay) + } +} From 80ee67d98d0b622396ea702695d44410a919e9ab Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 11:39:27 -0500 Subject: [PATCH 095/111] nit --- vms/proposervm/proposer/windower_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index bc6bd0b409ac..eec298cae838 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -420,9 +420,9 @@ func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { w := New(vdrState, subnetID, chainID) var ( - dummyCtx = context.Background() - chainHeight = uint64(1) - pChainHeight = uint64(0) + dummyCtx = context.Background() + chainHeight uint64 = 1 + pChainHeight uint64 = 0 ) for slot := uint64(0); slot < 3*MaxLookAheadSlots; slot++ { From d1690b9f6b7ebd7a4dee72ff79e6d0447a2da6e2 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 12:02:49 -0500 Subject: [PATCH 096/111] nit --- vms/proposervm/vm.go | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index cb14aae12ee2..b24a7ffef271 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -350,6 +350,14 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { nextStartTime, err = vm.getPreDurangoSlotTime(ctx, blk, pChainHeight) } if err != nil { + vm.ctx.Log.Debug("failed to fetch the expected delay", + zap.Error(err), + ) + + // A nil error is returned here because it is possible that + // bootstrapping caused the last accepted block to move past the latest + // P-chain height. This will cause building blocks to return an error + // until the P-chain's height has advanced. return nil } vm.Scheduler.SetBuildBlockTime(nextStartTime) @@ -367,16 +375,8 @@ func (vm *VM) getPreDurangoSlotTime( blk PostForkBlock, pChainHeight uint64, ) (time.Time, error) { - parentTimestamp := blk.Timestamp() - minDelay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) + delay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) if err != nil { - vm.ctx.Log.Debug("failed to fetch the expected delay", - zap.Error(err), - ) - // A nil error is returned here because it is possible that - // bootstrapping caused the last accepted block to move past the latest - // P-chain height. This will cause building blocks to return an error - // until the P-chain's height has advanced. return time.Time{}, err } @@ -386,10 +386,9 @@ func (vm *VM) getPreDurangoSlotTime( // validators can specify. This delay may be an issue for high performance, // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. - minDelay = math.Max(minDelay, vm.MinBlkDelay) - nextStartTime := parentTimestamp.Add(minDelay) - - return nextStartTime, nil + delay = math.Max(delay, vm.MinBlkDelay) + parentTimestamp := blk.Timestamp() + return parentTimestamp.Add(delay), nil } func (vm *VM) getPostDurangoSlotTime( @@ -407,9 +406,7 @@ func (vm *VM) getPostDurangoSlotTime( slot, ) if err != nil { - vm.ctx.Log.Debug("failed to calculate min delay for proposer", - zap.Error(err), - ) + return time.Time{}, err } // Note: The P-chain does not currently try to target any block time. It From c2813a86238f9fd749117b6c7fd80d31e04c2ba2 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 12:07:34 -0500 Subject: [PATCH 097/111] nit --- vms/proposervm/vm.go | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/vms/proposervm/vm.go b/vms/proposervm/vm.go index b24a7ffef271..2963739ef990 100644 --- a/vms/proposervm/vm.go +++ b/vms/proposervm/vm.go @@ -334,20 +334,26 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { } var ( - nextStartTime time.Time - parentTimestamp = blk.Timestamp() + childBlockHeight = blk.Height() + 1 + parentTimestamp = blk.Timestamp() + nextStartTime time.Time ) if vm.IsDurangoActivated(parentTimestamp) { currentTime := vm.Clock.Time().Truncate(time.Second) nextStartTime, err = vm.getPostDurangoSlotTime( ctx, - blk.Height()+1, + childBlockHeight, pChainHeight, proposer.TimeToSlot(parentTimestamp, currentTime), parentTimestamp, ) } else { - nextStartTime, err = vm.getPreDurangoSlotTime(ctx, blk, pChainHeight) + nextStartTime, err = vm.getPreDurangoSlotTime( + ctx, + childBlockHeight, + pChainHeight, + parentTimestamp, + ) } if err != nil { vm.ctx.Log.Debug("failed to fetch the expected delay", @@ -372,10 +378,11 @@ func (vm *VM) SetPreference(ctx context.Context, preferred ids.ID) error { func (vm *VM) getPreDurangoSlotTime( ctx context.Context, - blk PostForkBlock, + blkHeight, pChainHeight uint64, + parentTimestamp time.Time, ) (time.Time, error) { - delay, err := vm.Windower.Delay(ctx, blk.Height()+1, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) + delay, err := vm.Windower.Delay(ctx, blkHeight, pChainHeight, vm.ctx.NodeID, proposer.MaxBuildWindows) if err != nil { return time.Time{}, err } @@ -387,7 +394,6 @@ func (vm *VM) getPreDurangoSlotTime( // custom VMs. Until the P-chain is modified to target a specific block // time, ProposerMinBlockDelay can be configured in the subnet config. delay = math.Max(delay, vm.MinBlkDelay) - parentTimestamp := blk.Timestamp() return parentTimestamp.Add(delay), nil } From 527768cd352eb1edcf1375717020f5fc17385e93 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 12:33:12 -0500 Subject: [PATCH 098/111] nit --- vms/proposervm/vm_test.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/vms/proposervm/vm_test.go b/vms/proposervm/vm_test.go index 975615548b07..97216d9c0905 100644 --- a/vms/proposervm/vm_test.go +++ b/vms/proposervm/vm_test.go @@ -219,27 +219,27 @@ func initTestProposerVM( func waitForProposerWindow(vm *VM, chainTip snowman.Block, pchainHeight uint64) error { var ( - ctx = context.Background() - parentTimestamp = chainTip.Timestamp() + ctx = context.Background() + childBlockHeight = chainTip.Height() + 1 + parentTimestamp = chainTip.Timestamp() ) - vm.Clock.Set(vm.Clock.Time().Truncate(time.Second)) for { + slot := proposer.TimeToSlot(parentTimestamp, vm.Clock.Time().Truncate(time.Second)) delay, err := vm.MinDelayForProposer( ctx, - chainTip.Height()+1, + childBlockHeight, pchainHeight, vm.ctx.NodeID, - proposer.TimeToSlot(parentTimestamp, vm.Clock.Time()), + slot, ) + if err != nil { + return err + } - switch err { - case nil: - parentTimestamp = parentTimestamp.Add(delay) - vm.Clock.Set(parentTimestamp) + vm.Clock.Set(parentTimestamp.Add(delay)) + if delay < proposer.MaxLookAheadWindow { return nil - default: - return err } } } From 78c449aad8ee0c57424cdff96168f8cc3eb251ef Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 12:58:21 -0500 Subject: [PATCH 099/111] more tests --- vms/proposervm/proposer/windower_test.go | 52 +++++++++++++++++++----- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index eec298cae838..5481a0699d3b 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -475,16 +475,17 @@ func TestMinDelayForProposer(t *testing.T) { ) expectedDelays := map[ids.NodeID]time.Duration{ - validatorIDs[0]: 1 * WindowDuration, - validatorIDs[1]: 15 * WindowDuration, - validatorIDs[2]: 0 * WindowDuration, - validatorIDs[3]: 5 * WindowDuration, - validatorIDs[4]: 10 * WindowDuration, - validatorIDs[5]: 18 * WindowDuration, - validatorIDs[6]: 12 * WindowDuration, - validatorIDs[7]: 3 * WindowDuration, - validatorIDs[8]: 23 * WindowDuration, - validatorIDs[9]: 2 * WindowDuration, + validatorIDs[0]: 1 * WindowDuration, + validatorIDs[1]: 15 * WindowDuration, + validatorIDs[2]: 0 * WindowDuration, + validatorIDs[3]: 5 * WindowDuration, + validatorIDs[4]: 10 * WindowDuration, + validatorIDs[5]: 18 * WindowDuration, + validatorIDs[6]: 12 * WindowDuration, + validatorIDs[7]: 3 * WindowDuration, + validatorIDs[8]: 23 * WindowDuration, + validatorIDs[9]: 2 * WindowDuration, + ids.GenerateTestNodeID(): MaxLookAheadWindow, } for nodeID, expectedDelay := range expectedDelays { @@ -493,3 +494,34 @@ func TestMinDelayForProposer(t *testing.T) { require.Equal(expectedDelay, delay) } } + +func TestTimeToSlot(t *testing.T) { + parentTime := time.Now() + tests := []struct { + timeOffset time.Duration + expectedSlot uint64 + }{ + { + timeOffset: -time.Second, + expectedSlot: 0, + }, + { + timeOffset: 0, + expectedSlot: 0, + }, + { + timeOffset: WindowDuration, + expectedSlot: 1, + }, + { + timeOffset: 2 * WindowDuration, + expectedSlot: 2, + }, + } + for _, test := range tests { + t.Run(test.timeOffset.String(), func(t *testing.T) { + slot := TimeToSlot(parentTime, parentTime.Add(test.timeOffset)) + require.Equal(t, test.expectedSlot, slot) + }) + } +} From b37f0b03861ef08420ccdde91adfc4af446a5bdf Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 13:00:03 -0500 Subject: [PATCH 100/111] nit --- vms/proposervm/proposer/windower_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 5481a0699d3b..c7a2d26982a0 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -501,6 +501,10 @@ func TestTimeToSlot(t *testing.T) { timeOffset time.Duration expectedSlot uint64 }{ + { + timeOffset: -WindowDuration, + expectedSlot: 0, + }, { timeOffset: -time.Second, expectedSlot: 0, From 35f44bddea244afe4cf93b663b20d45854937c54 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 14:26:36 -0500 Subject: [PATCH 101/111] Add distribution test --- vms/proposervm/proposer/windower_test.go | 73 ++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index c7a2d26982a0..38356d0d5957 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -5,6 +5,7 @@ package proposer import ( "context" + "math" "math/rand" "testing" "time" @@ -13,6 +14,8 @@ import ( "github.com/ava-labs/avalanchego/ids" "github.com/ava-labs/avalanchego/snow/validators" + + safemath "github.com/ava-labs/avalanchego/utils/math" ) func TestWindowerNoValidators(t *testing.T) { @@ -529,3 +532,73 @@ func TestTimeToSlot(t *testing.T) { }) } } + +// Ensure that the proposer distribution is within 3 standard deviations of the +// expected value assuming a truly random binomial distribution. +func TestProposerDistribution(t *testing.T) { + require := require.New(t) + + var ( + subnetID = ids.ID{0, 1} + chainID = ids.ID{0, 2} + + validatorsCount = 10 + ) + + validatorIDs := make([]ids.NodeID, validatorsCount) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + + w := New(vdrState, subnetID, chainID) + + var ( + dummyCtx = context.Background() + pChainHeight uint64 = 0 + numChainHeights uint64 = 100 + numSlots uint64 = 100 + ) + + proposerFrequency := make(map[ids.NodeID]int) + for chainHeight := uint64(0); chainHeight < numChainHeights; chainHeight++ { + for slot := uint64(0); slot < numSlots; slot++ { + proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) + require.NoError(err) + proposerFrequency[proposerID]++ + } + } + + var ( + totalNumberOfSamples = numChainHeights * numSlots + probabilityOfBeingSampled = 1 / float64(len(validatorIDs)) + expectedNumberOfSamples = uint64(probabilityOfBeingSampled * float64(totalNumberOfSamples)) + variance = float64(totalNumberOfSamples) * probabilityOfBeingSampled * (1 - probabilityOfBeingSampled) + stdDeviation = math.Sqrt(variance) + maxDeviation uint64 + ) + for _, sampled := range proposerFrequency { + maxDeviation = safemath.Max( + maxDeviation, + safemath.AbsDiff( + uint64(sampled), + expectedNumberOfSamples, + ), + ) + } + + maxSTDDeviation := float64(maxDeviation) / stdDeviation + require.Less(maxSTDDeviation, 3.) +} From a0a174fc479146d7e264f5db1a1bab6857b8ef55 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 14:56:09 -0500 Subject: [PATCH 102/111] cleanup tests --- vms/proposervm/proposer/windower_test.go | 259 ++++------------------- 1 file changed, 46 insertions(+), 213 deletions(-) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 38356d0d5957..57a37f6782ba 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -18,27 +18,22 @@ import ( safemath "github.com/ava-labs/avalanchego/utils/math" ) +var ( + subnetID = ids.GenerateTestID() + randomChainID = ids.GenerateTestID() + fixedChainID = ids.ID{0, 2} +) + func TestWindowerNoValidators(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.GenerateTestID() - chainID = ids.GenerateTestID() - nodeID = ids.GenerateTestNodeID() - ) - - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - return nil, nil - }, - } - - w := New(vdrState, subnetID, chainID) + _, vdrState := makeValidators(t, 0) + w := New(vdrState, subnetID, randomChainID) var ( chainHeight uint64 = 1 pChainHeight uint64 = 0 + nodeID = ids.GenerateTestNodeID() slot uint64 = 1 ) delay, err := w.Delay(context.Background(), chainHeight, pChainHeight, nodeID, MaxVerifyWindows) @@ -54,8 +49,6 @@ func TestWindowerRepeatedValidator(t *testing.T) { require := require.New(t) var ( - subnetID = ids.GenerateTestID() - chainID = ids.GenerateTestID() validatorID = ids.GenerateTestNodeID() nonValidatorID = ids.GenerateTestNodeID() ) @@ -72,7 +65,7 @@ func TestWindowerRepeatedValidator(t *testing.T) { }, } - w := New(vdrState, subnetID, chainID) + w := New(vdrState, subnetID, randomChainID) validatorDelay, err := w.Delay(context.Background(), 1, 0, validatorID, MaxVerifyWindows) require.NoError(err) @@ -86,30 +79,8 @@ func TestWindowerRepeatedValidator(t *testing.T) { func TestDelayChangeByHeight(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - ) - - validatorIDs := make([]ids.NodeID, MaxVerifyWindows) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) + validatorIDs, vdrState := makeValidators(t, MaxVerifyWindows) + w := New(vdrState, subnetID, fixedChainID) expectedDelays1 := []time.Duration{ 2 * WindowDuration, @@ -145,8 +116,6 @@ func TestDelayChangeByHeight(t *testing.T) { func TestDelayChangeByChain(t *testing.T) { require := require.New(t) - subnetID := ids.ID{0, 1} - source := rand.NewSource(int64(0)) rng := rand.New(source) // #nosec G404 @@ -158,24 +127,7 @@ func TestDelayChangeByChain(t *testing.T) { _, err = rng.Read(chainID1[:]) require.NoError(err) - validatorIDs := make([]ids.NodeID, MaxVerifyWindows) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - + validatorIDs, vdrState := makeValidators(t, MaxVerifyWindows) w0 := New(vdrState, subnetID, chainID0) w1 := New(vdrState, subnetID, chainID1) @@ -213,32 +165,8 @@ func TestDelayChangeByChain(t *testing.T) { func TestExpectedProposerChangeByHeight(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - - validatorsCount = 10 - ) - - validatorIDs := make([]ids.NodeID, validatorsCount) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) var ( dummyCtx = context.Background() @@ -261,11 +189,6 @@ func TestExpectedProposerChangeByHeight(t *testing.T) { func TestExpectedProposerChangeByChain(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - validatorsCount = 10 - ) - source := rand.NewSource(int64(0)) rng := rand.New(source) // #nosec G404 @@ -277,23 +200,7 @@ func TestExpectedProposerChangeByChain(t *testing.T) { _, err = rng.Read(chainID1[:]) require.NoError(err) - validatorIDs := make([]ids.NodeID, validatorsCount) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } + validatorIDs, vdrState := makeValidators(t, 10) var ( dummyCtx = context.Background() @@ -318,32 +225,8 @@ func TestExpectedProposerChangeByChain(t *testing.T) { func TestExpectedProposerChangeBySlot(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - - validatorsCount = 10 - ) - - validatorIDs := make([]ids.NodeID, validatorsCount) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) var ( dummyCtx = context.Background() @@ -395,32 +278,8 @@ func TestExpectedProposerChangeBySlot(t *testing.T) { func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - - validatorsCount = 10 - ) - - validatorIDs := make([]ids.NodeID, validatorsCount) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) + _, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) var ( dummyCtx = context.Background() @@ -443,32 +302,8 @@ func TestCoherenceOfExpectedProposerAndMinDelayForProposer(t *testing.T) { func TestMinDelayForProposer(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - - validatorsCount = 10 - ) - - validatorIDs := make([]ids.NodeID, validatorsCount) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) var ( dummyCtx = context.Background() @@ -538,32 +373,8 @@ func TestTimeToSlot(t *testing.T) { func TestProposerDistribution(t *testing.T) { require := require.New(t) - var ( - subnetID = ids.ID{0, 1} - chainID = ids.ID{0, 2} - - validatorsCount = 10 - ) - - validatorIDs := make([]ids.NodeID, validatorsCount) - for i := range validatorIDs { - validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) - } - vdrState := &validators.TestState{ - T: t, - GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { - vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) - for _, id := range validatorIDs { - vdrs[id] = &validators.GetValidatorOutput{ - NodeID: id, - Weight: 1, - } - } - return vdrs, nil - }, - } - - w := New(vdrState, subnetID, chainID) + validatorIDs, vdrState := makeValidators(t, 10) + w := New(vdrState, subnetID, fixedChainID) var ( dummyCtx = context.Background() @@ -602,3 +413,25 @@ func TestProposerDistribution(t *testing.T) { maxSTDDeviation := float64(maxDeviation) / stdDeviation require.Less(maxSTDDeviation, 3.) } + +func makeValidators(t *testing.T, count int) ([]ids.NodeID, *validators.TestState) { + validatorIDs := make([]ids.NodeID, count) + for i := range validatorIDs { + validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1}) + } + + vdrState := &validators.TestState{ + T: t, + GetValidatorSetF: func(context.Context, uint64, ids.ID) (map[ids.NodeID]*validators.GetValidatorOutput, error) { + vdrs := make(map[ids.NodeID]*validators.GetValidatorOutput, MaxVerifyWindows) + for _, id := range validatorIDs { + vdrs[id] = &validators.GetValidatorOutput{ + NodeID: id, + Weight: 1, + } + } + return vdrs, nil + }, + } + return validatorIDs, vdrState +} From d8d807ff1142f00c4a7bff609555a468182d4a1d Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 17:31:58 -0500 Subject: [PATCH 103/111] nit --- vms/proposervm/proposer/windower.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index ce3473a67499..a1db7556471d 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -87,7 +87,7 @@ type Windower interface { blockHeight, pChainHeight uint64, nodeID ids.NodeID, - initialSlot uint64, + startSlot uint64, ) (time.Duration, error) } @@ -204,7 +204,7 @@ func (w *windower) MinDelayForProposer( blockHeight, pChainHeight uint64, nodeID ids.NodeID, - slot uint64, + startSlot uint64, ) (time.Duration, error) { validators, err := w.sortedValidators(ctx, pChainHeight) if err != nil { @@ -212,7 +212,7 @@ func (w *windower) MinDelayForProposer( } var ( - maxSlot = slot + MaxLookAheadSlots + maxSlot = startSlot + MaxLookAheadSlots source = prng.NewMT19937_64() validatorWeights = validatorsToWeight(validators) @@ -223,7 +223,7 @@ func (w *windower) MinDelayForProposer( return 0, err } - for slot := slot; slot < maxSlot; slot++ { + for slot := startSlot; slot < maxSlot; slot++ { seed := postDurangoSeed(w.chainSource, blockHeight, slot) source.Seed(seed) indices, err := sampler.Sample(1) From 867f122c8eb0b86ad0c532ea7413016d550bdf5c Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 17:34:04 -0500 Subject: [PATCH 104/111] nit --- vms/proposervm/block.go | 1 + 1 file changed, 1 insertion(+) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index bd971ea9ba58..7fdb42189742 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -203,6 +203,7 @@ func (p *postForkCommonComponents) buildChild( return nil, err } + // After Durango, we never allow unsigned blocks. shouldBuildUnsignedBlock := false if p.vm.IsDurangoActivated(parentTimestamp) { err = p.shouldBuildBlockPostDurango( From 01bd6c58ca7d4957346a883e9ed80219c63d5022 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 18:16:58 -0500 Subject: [PATCH 105/111] rework code flow --- vms/proposervm/proposer/windower.go | 145 +++++++++++++--------------- 1 file changed, 69 insertions(+), 76 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index a1db7556471d..d77a060ba2a6 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -109,34 +109,25 @@ func New(state validators.State, subnetID, chainID ids.ID) Windower { } func (w *windower) Proposers(ctx context.Context, blockHeight, pChainHeight uint64, maxWindows int) ([]ids.NodeID, error) { - validators, err := w.sortedValidators(ctx, pChainHeight) - if err != nil { - return nil, err - } - // Note: The 32-bit prng is used here for legacy reasons. All other usages // of a prng in this file should use the 64-bit version. - var ( - seed = preDurangoSeed(w.chainSource, blockHeight) - source = prng.NewMT19937() - validatorWeights = validatorsToWeight(validators) - ) - - sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) - if err := sampler.Initialize(validatorWeights); err != nil { + source := prng.NewMT19937() + sampler, validators, err := w.makeSampler(ctx, pChainHeight, source) + if err != nil { return nil, err } var totalWeight uint64 - for _, weight := range validatorWeights { - totalWeight, err = math.Add64(totalWeight, weight) + for _, validator := range validators { + totalWeight, err = math.Add64(totalWeight, validator.weight) if err != nil { return nil, err } } + source.Seed(w.chainSource ^ blockHeight) + numToSample := int(math.Min(uint64(maxWindows), totalWeight)) - source.Seed(seed) indices, err := sampler.Sample(numToSample) if err != nil { return nil, err @@ -175,28 +166,19 @@ func (w *windower) ExpectedProposer( pChainHeight, slot uint64, ) (ids.NodeID, error) { - validators, err := w.sortedValidators(ctx, pChainHeight) + source := prng.NewMT19937_64() + sampler, validators, err := w.makeSampler(ctx, pChainHeight, source) if err != nil { return ids.EmptyNodeID, err } - var ( - seed = postDurangoSeed(w.chainSource, blockHeight, slot) - source = prng.NewMT19937_64() - validatorWeights = validatorsToWeight(validators) + return w.expectedProposer( + validators, + source, + sampler, + blockHeight, + slot, ) - - sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) - if err := sampler.Initialize(validatorWeights); err != nil { - return ids.EmptyNodeID, err - } - - source.Seed(seed) - indices, err := sampler.Sample(1) - if err != nil { - return ids.EmptyNodeID, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) - } - return validators[indices[0]].id, nil } func (w *windower) MinDelayForProposer( @@ -206,32 +188,26 @@ func (w *windower) MinDelayForProposer( nodeID ids.NodeID, startSlot uint64, ) (time.Duration, error) { - validators, err := w.sortedValidators(ctx, pChainHeight) + source := prng.NewMT19937_64() + sampler, validators, err := w.makeSampler(ctx, pChainHeight, source) if err != nil { return 0, err } - var ( - maxSlot = startSlot + MaxLookAheadSlots - - source = prng.NewMT19937_64() - validatorWeights = validatorsToWeight(validators) - sampler = sampler.NewDeterministicWeightedWithoutReplacement(source) - ) - - if err := sampler.Initialize(validatorWeights); err != nil { - return 0, err - } - + maxSlot := startSlot + MaxLookAheadSlots for slot := startSlot; slot < maxSlot; slot++ { - seed := postDurangoSeed(w.chainSource, blockHeight, slot) - source.Seed(seed) - indices, err := sampler.Sample(1) + expectedNodeID, err := w.expectedProposer( + validators, + source, + sampler, + blockHeight, + slot, + ) if err != nil { - return 0, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) + return 0, err } - if validators[indices[0]].id == nodeID { + if expectedNodeID == nodeID { return time.Duration(slot) * WindowDuration, nil } } @@ -240,14 +216,33 @@ func (w *windower) MinDelayForProposer( return time.Duration(maxSlot) * WindowDuration, nil } +func (w *windower) makeSampler( + ctx context.Context, + pChainHeight uint64, + source sampler.Source, +) (sampler.WeightedWithoutReplacement, []validatorData, error) { + validators, err := w.sortedValidators(ctx, pChainHeight) + if err != nil { + return nil, nil, err + } + + weights := make([]uint64, len(validators)) + for i, validator := range validators { + weights[i] = validator.weight + } + + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) + return sampler, validators, sampler.Initialize(weights) +} + +// Get the canconical representation of the validator set at the provided +// p-chain height. func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, error) { - // get the validator set by the p-chain height validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) if err != nil { return nil, err } - // convert the map of validators to a slice validators := make([]validatorData, 0, len(validatorsMap)) for k, v := range validatorsMap { validators = append(validators, validatorData{ @@ -256,37 +251,35 @@ func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([ }) } - // canonically sort validators - // Note: validators are sorted by ID, sorting by weight would not create a - // canonically sorted list + // Note: validators are sorted by ID. Sorting by weight would not create a + // canonically sorted list. utils.Sort(validators) return validators, nil } +func (w *windower) expectedProposer( + validators []validatorData, + source *prng.MT19937_64, + sampler sampler.WeightedWithoutReplacement, + blockHeight, + slot uint64, +) (ids.NodeID, error) { + // Slot is reversed to utilize a different state space in the seed than the + // height. If the slot was not reversed the state space would collide; + // biasing the seed generation. For example, without reversing the slot + // height=0 and slot=1 would equal height=1 and slot=0. + source.Seed(w.chainSource ^ blockHeight ^ bits.Reverse64(slot)) + indices, err := sampler.Sample(1) + if err != nil { + return ids.EmptyNodeID, fmt.Errorf("%w, %w", err, ErrNoProposersAvailable) + } + return validators[indices[0]].id, nil +} + func TimeToSlot(baseTime, targetTime time.Time) uint64 { if targetTime.Before(baseTime) { return 0 } return uint64(targetTime.Sub(baseTime) / WindowDuration) } - -func validatorsToWeight(validators []validatorData) []uint64 { - weights := make([]uint64, len(validators)) - for i, validator := range validators { - weights[i] = validator.weight - } - return weights -} - -func preDurangoSeed(chainSource, height uint64) uint64 { - return chainSource ^ height -} - -func postDurangoSeed(chainSource, height, slot uint64) uint64 { - // Slot is reversed to utilize a different state space in the seed than the - // height. If the slot was not reversed the state space would collide, - // biasing the seed generation. For example, without reversing the slot - // postDurangoSeed(0,0,1) would equal postDurangoSeed(0,1,0). - return chainSource ^ height ^ bits.Reverse64(slot) -} From 3ecd893b84a860f75aa0adfb874e52fb0ae102e7 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 18:23:08 -0500 Subject: [PATCH 106/111] nit --- vms/proposervm/proposer/windower.go | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index d77a060ba2a6..96da7790eec6 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -221,26 +221,11 @@ func (w *windower) makeSampler( pChainHeight uint64, source sampler.Source, ) (sampler.WeightedWithoutReplacement, []validatorData, error) { - validators, err := w.sortedValidators(ctx, pChainHeight) - if err != nil { - return nil, nil, err - } - - weights := make([]uint64, len(validators)) - for i, validator := range validators { - weights[i] = validator.weight - } - - sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) - return sampler, validators, sampler.Initialize(weights) -} - -// Get the canconical representation of the validator set at the provided -// p-chain height. -func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([]validatorData, error) { + // Get the canconical representation of the validator set at the provided + // p-chain height. validatorsMap, err := w.state.GetValidatorSet(ctx, pChainHeight, w.subnetID) if err != nil { - return nil, err + return nil, nil, err } validators := make([]validatorData, 0, len(validatorsMap)) @@ -255,7 +240,13 @@ func (w *windower) sortedValidators(ctx context.Context, pChainHeight uint64) ([ // canonically sorted list. utils.Sort(validators) - return validators, nil + weights := make([]uint64, len(validators)) + for i, validator := range validators { + weights[i] = validator.weight + } + + sampler := sampler.NewDeterministicWeightedWithoutReplacement(source) + return sampler, validators, sampler.Initialize(weights) } func (w *windower) expectedProposer( From d1c4a7a082436156b02e8aeacc08e40ad145935a Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 19:53:32 -0500 Subject: [PATCH 107/111] nit --- vms/proposervm/block.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 7fdb42189742..1e53b4f45a11 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -142,7 +142,8 @@ func (p *postForkCommonComponents) Verify( ) } - shouldHaveProposer := true // post Durango this is always the case + // After Durango, we never allow unsigned blocks. + shouldHaveProposer := true if p.vm.IsDurangoActivated(parentTimestamp) { err := p.verifyPostDurangoBlockDelay(ctx, parentTimestamp, parentPChainHeight, child) if err != nil { From 9dd949911b3857155418f7c37b6e4da9f0e6fe86 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 19:58:59 -0500 Subject: [PATCH 108/111] nit --- vms/proposervm/proposer/windower.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index 96da7790eec6..c8522338d400 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -268,9 +268,9 @@ func (w *windower) expectedProposer( return validators[indices[0]].id, nil } -func TimeToSlot(baseTime, targetTime time.Time) uint64 { - if targetTime.Before(baseTime) { +func TimeToSlot(start, now time.Time) uint64 { + if now.Before(start) { return 0 } - return uint64(targetTime.Sub(baseTime) / WindowDuration) + return uint64(now.Sub(start) / WindowDuration) } From e6b7c1ebc011f7ce9fc2d28865d70bf3cbc9e7d6 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 20:16:25 -0500 Subject: [PATCH 109/111] nit improve test --- vms/proposervm/proposer/windower_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index 57a37f6782ba..e1a4693ea71f 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -384,6 +384,11 @@ func TestProposerDistribution(t *testing.T) { ) proposerFrequency := make(map[ids.NodeID]int) + for _, validatorID := range validatorIDs { + // Initialize the map to 0s to include validators that are never sampled + // in the analysis. + proposerFrequency[validatorID] = 0 + } for chainHeight := uint64(0); chainHeight < numChainHeights; chainHeight++ { for slot := uint64(0); slot < numSlots; slot++ { proposerID, err := w.ExpectedProposer(dummyCtx, chainHeight, pChainHeight, slot) From 6cfd98513504ab7fa0d902e6d5159b9b680be505 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 20:29:45 -0500 Subject: [PATCH 110/111] add todo --- vms/proposervm/block.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/vms/proposervm/block.go b/vms/proposervm/block.go index 1e53b4f45a11..94969a048caa 100644 --- a/vms/proposervm/block.go +++ b/vms/proposervm/block.go @@ -434,6 +434,9 @@ func (p *postForkCommonComponents) shouldBuildBlockPostDurango( // We need to reschedule the block builder to the next time we can try to // build a block. + // + // TODO: After Durango activates, restructure this logic to separate + // updating the scheduler from verifying the proposerID. nextStartTime, err := p.vm.getPostDurangoSlotTime( ctx, parentHeight+1, From ef5715e47d79217f6c9e9e5663e4a8ec0a219493 Mon Sep 17 00:00:00 2001 From: Stephen Buttolph Date: Fri, 15 Dec 2023 20:49:37 -0500 Subject: [PATCH 111/111] Add benchmarks --- snow/validators/test_state.go | 2 +- utils/sampler/rand_test.go | 20 ++++++++++++++++++++ vms/proposervm/proposer/windower.go | 2 +- vms/proposervm/proposer/windower_test.go | 23 ++++++++++++++++++++++- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/snow/validators/test_state.go b/snow/validators/test_state.go index b27e6d972613..eb6af391a1d8 100644 --- a/snow/validators/test_state.go +++ b/snow/validators/test_state.go @@ -23,7 +23,7 @@ var ( var _ State = (*TestState)(nil) type TestState struct { - T *testing.T + T testing.TB CantGetMinimumHeight, CantGetCurrentHeight, diff --git a/utils/sampler/rand_test.go b/utils/sampler/rand_test.go index 362093a695ac..e822d5876cbf 100644 --- a/utils/sampler/rand_test.go +++ b/utils/sampler/rand_test.go @@ -12,6 +12,8 @@ import ( "github.com/stretchr/testify/require" "github.com/thepudds/fzgen/fuzzer" + + "gonum.org/v1/gonum/mathext/prng" ) type testSource struct { @@ -208,3 +210,21 @@ func FuzzRNG(f *testing.F) { require.Len(stdSource.nums, len(source.nums)) }) } + +func BenchmarkSeed32(b *testing.B) { + source := prng.NewMT19937() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + source.Seed(0) + } +} + +func BenchmarkSeed64(b *testing.B) { + source := prng.NewMT19937_64() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + source.Seed(0) + } +} diff --git a/vms/proposervm/proposer/windower.go b/vms/proposervm/proposer/windower.go index c8522338d400..6903db785e29 100644 --- a/vms/proposervm/proposer/windower.go +++ b/vms/proposervm/proposer/windower.go @@ -81,7 +81,7 @@ type Windower interface { // [MinDelayForProposer] specifies how long [nodeID] needs to wait for its // slot to start. Delay is specified as starting from slot zero start. // (which is parent timestamp). For efficiency reasons, we cap the slot - // search to [MaxLookAheadWindow] slots. + // search to [MaxLookAheadSlots]. MinDelayForProposer( ctx context.Context, blockHeight, diff --git a/vms/proposervm/proposer/windower_test.go b/vms/proposervm/proposer/windower_test.go index e1a4693ea71f..bf8786b8b735 100644 --- a/vms/proposervm/proposer/windower_test.go +++ b/vms/proposervm/proposer/windower_test.go @@ -333,6 +333,27 @@ func TestMinDelayForProposer(t *testing.T) { } } +func BenchmarkMinDelayForProposer(b *testing.B) { + require := require.New(b) + + _, vdrState := makeValidators(b, 10) + w := New(vdrState, subnetID, fixedChainID) + + var ( + dummyCtx = context.Background() + pChainHeight uint64 = 0 + chainHeight uint64 = 1 + nodeID = ids.GenerateTestNodeID() // Ensure to exhaust the search + slot uint64 = 0 + ) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, err := w.MinDelayForProposer(dummyCtx, chainHeight, pChainHeight, nodeID, slot) + require.NoError(err) + } +} + func TestTimeToSlot(t *testing.T) { parentTime := time.Now() tests := []struct { @@ -419,7 +440,7 @@ func TestProposerDistribution(t *testing.T) { require.Less(maxSTDDeviation, 3.) } -func makeValidators(t *testing.T, count int) ([]ids.NodeID, *validators.TestState) { +func makeValidators(t testing.TB, count int) ([]ids.NodeID, *validators.TestState) { validatorIDs := make([]ids.NodeID, count) for i := range validatorIDs { validatorIDs[i] = ids.BuildTestNodeID([]byte{byte(i) + 1})