Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

dbft: use previous block timestamp for view 0 initialization #64

Merged
merged 1 commit into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions check.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (d *DBFT) checkCommit() {

d.ProcessBlock(d.block)

d.InitializeConsensus(0)
d.InitializeConsensus(0, d.Timestamp)
}

func (d *DBFT) checkChangeView(view byte) {
Expand All @@ -99,5 +99,5 @@ func (d *DBFT) checkChangeView(view byte) {
}
}

d.InitializeConsensus(view)
d.InitializeConsensus(view, d.lastBlockTimestamp)
}
14 changes: 8 additions & 6 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,9 @@ type Context struct {
// if this node never heard from validator i, LastSeenMessage[i] will be -1.
LastSeenMessage []*timer.HV

lastBlockTime time.Time
lastBlockIndex uint32
lastBlockTimestamp uint64 // ns-precision timestamp from the last header (used for the next block timestamp calculations).
lastBlockTime time.Time // Wall clock time of when the last block was first seen (used for timer adjustments).
lastBlockIndex uint32
}

// N returns total number of validators.
Expand Down Expand Up @@ -169,8 +170,10 @@ func (c *Context) MoreThanFNodesCommittedOrLost() bool {
return c.CountCommitted()+c.CountFailed() > c.F()
}

func (c *Context) reset(view byte) {
func (c *Context) reset(view byte, ts uint64) {
c.MyIndex = -1
c.lastBlockTimestamp = ts

if view == 0 {
c.PrevHash = c.Config.CurrentBlockHash()
c.BlockIndex = c.Config.CurrentHeight() + 1
Expand Down Expand Up @@ -238,10 +241,9 @@ func (c *Context) Fill() {
validators := c.Config.GetValidators(txx...)
c.NextConsensus = c.Config.GetConsensusAddress(validators...)

if now := c.getTimestamp(); now > c.Timestamp+c.Config.TimestampIncrement {
c.Timestamp = c.lastBlockTimestamp + c.Config.TimestampIncrement
if now := c.getTimestamp(); now > c.Timestamp {
c.Timestamp = now
} else {
c.Timestamp += c.Config.TimestampIncrement
}
}

Expand Down
13 changes: 7 additions & 6 deletions dbft.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type (

// Service is an interface for dBFT consensus.
Service interface {
Start()
Start(uint64)
OnTransaction(block.Transaction)
OnReceive(payload.ConsensusPayload)
OnTimeout(timer.HV)
Expand Down Expand Up @@ -75,16 +75,17 @@ func (d *DBFT) addTransaction(tx block.Transaction) {
}
}

// Start initializes dBFT instance and starts protocol if node is primary.
func (d *DBFT) Start() {
// Start initializes dBFT instance and starts protocol if node is primary. It
// accepts a timestamp of the previous block.
func (d *DBFT) Start(ts uint64) {
d.cache = newCache()
d.InitializeConsensus(0)
d.InitializeConsensus(0, ts)
d.start()
}

// InitializeConsensus initializes dBFT instance.
func (d *DBFT) InitializeConsensus(view byte) {
d.reset(view)
func (d *DBFT) InitializeConsensus(view byte, ts uint64) {
d.reset(view, ts)

var role string

Expand Down
24 changes: 12 additions & 12 deletions dbft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ func TestDBFT_OnStartPrimarySendPrepareRequest(t *testing.T) {
s.currHeight = 0
service := New(s.getOptions()...)

service.Start()
service.Start(0)
require.Nil(t, s.tryRecv())
})

t.Run("primary send PrepareRequest on start", func(t *testing.T) {
s.currHeight = 1
service := New(s.getOptions()...)

service.Start()
service.Start(0)
p := s.tryRecv()
require.NotNil(t, p)
require.Equal(t, payload.PrepareRequestType, p.Type())
Expand Down Expand Up @@ -93,7 +93,7 @@ func TestDBFT_SingleNode(t *testing.T) {
s.currHeight = 2
service := New(s.getOptions()...)

service.Start()
service.Start(0)
p := s.tryRecv()
require.NotNil(t, p)
require.Equal(t, payload.PrepareRequestType, p.Type())
Expand Down Expand Up @@ -135,7 +135,7 @@ func TestDBFT_OnReceiveRequestSendResponse(t *testing.T) {

p := s.getPrepareRequest(5, txs[0].Hash())

service.Start()
service.Start(0)
service.OnReceive(p)

resp := s.tryRecv()
Expand Down Expand Up @@ -164,7 +164,7 @@ func TestDBFT_OnReceiveRequestSendResponse(t *testing.T) {
service := New(s.getOptions()...)
txs := []testTx{10}

service.Start()
service.Start(0)

for i := range service.LastSeenMessage {
service.LastSeenMessage[i] = &timer.HV{Height: s.currHeight + 1}
Expand Down Expand Up @@ -193,7 +193,7 @@ func TestDBFT_OnReceiveRequestSendResponse(t *testing.T) {
txs := []testTx{1, 2}
s.pool.Add(txs[0])

service.Start()
service.Start(0)

t.Run("wrong primary index", func(t *testing.T) {
p := s.getPrepareRequest(4, txs[0].Hash())
Expand Down Expand Up @@ -239,7 +239,7 @@ func TestDBFT_CommitOnTransaction(t *testing.T) {
s.currHeight = 1

srv := New(s.getOptions()...)
srv.Start()
srv.Start(0)
require.Nil(t, s.tryRecv())

tx := testTx(42)
Expand All @@ -259,7 +259,7 @@ func TestDBFT_CommitOnTransaction(t *testing.T) {
}
s1.pool.Add(tx)
srv1 := New(s1.getOptions()...)
srv1.Start()
srv1.Start(0)
srv1.OnReceive(req)
srv1.OnReceive(s1.getPrepareResponse(1, req.Hash()))
srv1.OnReceive(s1.getPrepareResponse(3, req.Hash()))
Expand All @@ -281,7 +281,7 @@ func TestDBFT_OnReceiveCommit(t *testing.T) {
t.Run("send commit after enough responses", func(t *testing.T) {
s.currHeight = 1
service := New(s.getOptions()...)
service.Start()
service.Start(0)

req := s.tryRecv()
require.NotNil(t, req)
Expand Down Expand Up @@ -341,7 +341,7 @@ func TestDBFT_OnReceiveRecoveryRequest(t *testing.T) {
t.Run("send recovery message", func(t *testing.T) {
s.currHeight = 1
service := New(s.getOptions()...)
service.Start()
service.Start(0)

req := s.tryRecv()
require.NotNil(t, req)
Expand All @@ -363,7 +363,7 @@ func TestDBFT_OnReceiveRecoveryRequest(t *testing.T) {

other := s.copyWithIndex(3)
srv2 := New(other.getOptions()...)
srv2.Start()
srv2.Start(0)
srv2.OnReceive(rm)

r2 := other.tryRecv()
Expand All @@ -386,7 +386,7 @@ func TestDBFT_OnReceiveChangeView(t *testing.T) {
t.Run("change view correctly", func(t *testing.T) {
s.currHeight = 6
service := New(s.getOptions()...)
service.Start()
service.Start(0)

resp := s.getChangeView(1, 1)
service.OnReceive(resp)
Expand Down
2 changes: 1 addition & 1 deletion simulation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func main() {

// Run implements simple event loop.
func (n *simNode) Run(ctx context.Context) {
n.d.Start()
n.d.Start(0)

for {
select {
Expand Down