Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 24 additions & 9 deletions consensus/consensus_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/harmony-one/harmony/crypto/hash"
"github.com/harmony-one/harmony/internal/chain"
nodeconfig "github.com/harmony-one/harmony/internal/configs/node"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/utils"
"github.com/harmony-one/harmony/multibls"
"github.com/harmony-one/harmony/p2p"
Expand Down Expand Up @@ -338,6 +339,26 @@ func (consensus *Consensus) UpdateConsensusInformation(reason string) Mode {
return consensus.updateConsensusInformation(reason)
}

func blockPeriodForConsensusUpdate(
config *params.ChainConfig, currentEpoch, nextEpoch *big.Int, isLastBlockInEpoch bool,
) time.Duration {
// Startup and resync must retain the current epoch's cadence. Once the last
// block is committed, the next proposal belongs to the next epoch.
epoch := currentEpoch
if isLastBlockInEpoch {
epoch = nextEpoch
}

blockPeriod := 5 * time.Second
if config.IsTwoSeconds(epoch) {
blockPeriod = 2 * time.Second
}
if config.IsOneSecond(epoch) {
blockPeriod = time.Second
}
return blockPeriod
}

func (consensus *Consensus) updateConsensusInformation(reason string) Mode {
curHeader := consensus.Blockchain().CurrentHeader()
curEpoch := curHeader.Epoch()
Expand All @@ -358,15 +379,9 @@ func (consensus *Consensus) updateConsensusInformation(reason string) Mode {
}
}

consensus.BlockPeriod = 5 * time.Second

// Enable 2s block time at the twoSecondsEpoch
if consensus.Blockchain().Config().IsTwoSeconds(nextEpoch) {
consensus.BlockPeriod = 2 * time.Second
}
if consensus.Blockchain().Config().IsOneSecond(nextEpoch) {
consensus.BlockPeriod = 1 * time.Second
}
consensus.BlockPeriod = blockPeriodForConsensusUpdate(
consensus.Blockchain().Config(), curEpoch, nextEpoch, curHeader.IsLastBlockInEpoch(),
)

isFirstTimeStaking := consensus.Blockchain().Config().IsStaking(nextEpoch) &&
curHeader.IsLastBlockInEpoch() && !consensus.Blockchain().Config().IsStaking(curEpoch)
Expand Down
62 changes: 62 additions & 0 deletions consensus/consensus_service_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package consensus

import (
"math/big"
"testing"
"time"

"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/params"
"github.com/harmony-one/harmony/internal/registry"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -90,3 +93,62 @@ func TestErrors(t *testing.T) {
require.True(t, errors.Is(e2, e1))
})
}

func TestBlockPeriodForConsensusUpdate(t *testing.T) {
config := *params.TestnetChainConfig
config.TwoSecondsEpoch = big.NewInt(10)
config.IsOneSecondEpoch = big.NewInt(20)

tests := []struct {
name string
currentEpoch int64
nextEpoch int64
isLastBlockInEpoch bool
want time.Duration
}{
{
name: "before two second activation",
currentEpoch: 9,
nextEpoch: 10,
want: 5 * time.Second,
},
{
name: "two second activation boundary",
currentEpoch: 9,
nextEpoch: 10,
isLastBlockInEpoch: true,
want: 2 * time.Second,
},
{
name: "mid epoch before one second activation",
currentEpoch: 19,
nextEpoch: 20,
want: 2 * time.Second,
},
{
name: "one second activation boundary",
currentEpoch: 19,
nextEpoch: 20,
isLastBlockInEpoch: true,
want: time.Second,
},
{
name: "after one second activation",
currentEpoch: 20,
nextEpoch: 21,
want: time.Second,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got := blockPeriodForConsensusUpdate(
&config,
big.NewInt(test.currentEpoch),
big.NewInt(test.nextEpoch),
test.isLastBlockInEpoch,
)
require.Equal(t, test.want, got)
})
}
}