Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix: cache certificate by height #730

Merged
merged 5 commits into from
Oct 5, 2023
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 consensus/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ func (s *commitState) decide() {
precommits := s.log.PrecommitVoteSet(s.round)
votes := precommits.BlockVotes(certBlock.Hash())
cert := s.makeCertificate(votes)
err := s.state.CommitBlock(s.height, certBlock, cert)
err := s.state.CommitBlock(certBlock, cert)
if err != nil {
s.logger.Error("committing block failed", "block", certBlock, "error", err)
} else {
s.logger.Info("block committed, schedule new height", "hash", certBlock.Hash().ShortString())
}

// Now we can announce the committed block and certificate
s.announceNewBlock(s.height, certBlock, cert)
s.announceNewBlock(certBlock, cert)

s.enterNewState(s.newHeightState)
}
Expand Down
4 changes: 2 additions & 2 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,10 @@ func (cs *consensus) broadcastVote(v *vote.Vote) {
message.NewVoteMessage(v))
}

func (cs *consensus) announceNewBlock(h uint32, b *block.Block, c *certificate.Certificate) {
func (cs *consensus) announceNewBlock(blk *block.Block, cert *certificate.Certificate) {
go cs.mediator.OnBlockAnnounce(cs)
cs.broadcaster(cs.valKey.Address(),
message.NewBlockAnnounceMessage(h, b, c))
message.NewBlockAnnounceMessage(blk, cert))
}

func (cs *consensus) makeCertificate(votes map[crypto.Address]*vote.Vote) *certificate.Certificate {
Expand Down
18 changes: 8 additions & 10 deletions consensus/consensus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,18 +323,18 @@ func (td *testData) commitBlockForAllStates(t *testing.T) (*block.Block, *certif

sig := bls.SignatureAggregate(sig1, sig2, sig4)
cert := certificate.NewCertificate(height+1, 0, []int32{0, 1, 2, 3}, []int32{2}, sig)
block := p.Block()
blk := p.Block()

err = td.consX.state.CommitBlock(height+1, block, cert)
err = td.consX.state.CommitBlock(blk, cert)
assert.NoError(t, err)
err = td.consY.state.CommitBlock(height+1, block, cert)
err = td.consY.state.CommitBlock(blk, cert)
assert.NoError(t, err)
err = td.consB.state.CommitBlock(height+1, block, cert)
err = td.consB.state.CommitBlock(blk, cert)
assert.NoError(t, err)
err = td.consP.state.CommitBlock(height+1, block, cert)
err = td.consP.state.CommitBlock(blk, cert)
assert.NoError(t, err)

return block, cert
return blk, cert
}

func (td *testData) makeProposal(t *testing.T, height uint32, round int16) *proposal.Proposal {
Expand Down Expand Up @@ -619,17 +619,15 @@ func TestNonActiveValidator(t *testing.T) {

t.Run("non-active instances should move to new height", func(t *testing.T) {
b1, cert1 := td.commitBlockForAllStates(t)
b2, cert2 := td.commitBlockForAllStates(t)

nonActiveCons.MoveToNewHeight()
td.checkHeightRound(t, nonActiveCons, 1, 0)

assert.NoError(t, nonActiveCons.state.CommitBlock(1, b1, cert1))
assert.NoError(t, nonActiveCons.state.CommitBlock(2, b2, cert2))
assert.NoError(t, nonActiveCons.state.CommitBlock(b1, cert1))

nonActiveCons.MoveToNewHeight()
td.newHeightTimeout(nonActiveCons)
td.checkHeightRound(t, nonActiveCons, 3, 0)
td.checkHeightRound(t, nonActiveCons, 2, 0)
})
}

Expand Down
36 changes: 18 additions & 18 deletions consensus/cp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func TestInvalidJustInitZero(t *testing.T) {
h := uint32(1)
r := int16(0)
just := &vote.JustInitZero{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
}

t.Run("invalid value: one", func(t *testing.T) {
Expand Down Expand Up @@ -230,7 +230,7 @@ func TestInvalidJustInitZero(t *testing.T) {
err := td.consX.checkJust(v)
assert.ErrorIs(t, err, invalidJustificationError{
JustType: just.Type(),
Reason: fmt.Sprintf("certificate height is invalid (expected 1 got %v)", just.QCert.Height()),
Reason: fmt.Sprintf("certificate has an unexpected committers: %v", just.QCert.Committers()),
})
})
}
Expand All @@ -242,7 +242,7 @@ func TestInvalidJustPreVoteHard(t *testing.T) {
h := uint32(1)
r := int16(0)
just := &vote.JustPreVoteHard{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
}

t.Run("invalid value: abstain", func(t *testing.T) {
Expand Down Expand Up @@ -271,7 +271,7 @@ func TestInvalidJustPreVoteHard(t *testing.T) {
err := td.consX.checkJust(v)
assert.ErrorIs(t, err, invalidJustificationError{
JustType: just.Type(),
Reason: fmt.Sprintf("certificate height is invalid (expected 1 got %v)", just.QCert.Height()),
Reason: fmt.Sprintf("certificate has an unexpected committers: %v", just.QCert.Committers()),
})
})
}
Expand All @@ -283,7 +283,7 @@ func TestInvalidJustPreVoteSoft(t *testing.T) {
h := uint32(1)
r := int16(0)
just := &vote.JustPreVoteSoft{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
}

t.Run("invalid value: abstain", func(t *testing.T) {
Expand Down Expand Up @@ -312,7 +312,7 @@ func TestInvalidJustPreVoteSoft(t *testing.T) {
err := td.consX.checkJust(v)
assert.ErrorIs(t, err, invalidJustificationError{
JustType: just.Type(),
Reason: fmt.Sprintf("certificate height is invalid (expected 1 got %v)", just.QCert.Height()),
Reason: fmt.Sprintf("certificate has an unexpected committers: %v", just.QCert.Committers()),
})
})
}
Expand All @@ -324,7 +324,7 @@ func TestInvalidJustMainVoteNoConflict(t *testing.T) {
h := uint32(1)
r := int16(0)
just := &vote.JustMainVoteNoConflict{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
}

t.Run("invalid value: abstain", func(t *testing.T) {
Expand All @@ -343,7 +343,7 @@ func TestInvalidJustMainVoteNoConflict(t *testing.T) {
err := td.consX.checkJust(v)
assert.ErrorIs(t, err, invalidJustificationError{
JustType: just.Type(),
Reason: fmt.Sprintf("certificate height is invalid (expected 1 got %v)", just.QCert.Height()),
Reason: fmt.Sprintf("certificate has an unexpected committers: %v", just.QCert.Committers()),
})
})
}
Expand All @@ -358,7 +358,7 @@ func TestInvalidJustMainVoteConflict(t *testing.T) {
t.Run("invalid value: zero", func(t *testing.T) {
just := &vote.JustMainVoteConflict{
Just0: &vote.JustInitZero{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
},
Just1: &vote.JustInitOne{},
}
Expand All @@ -374,7 +374,7 @@ func TestInvalidJustMainVoteConflict(t *testing.T) {
t.Run("invalid value: one", func(t *testing.T) {
just := &vote.JustMainVoteConflict{
Just0: &vote.JustInitZero{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
},
Just1: &vote.JustInitOne{},
}
Expand All @@ -390,7 +390,7 @@ func TestInvalidJustMainVoteConflict(t *testing.T) {
t.Run("invalid value: unexpected justification (just0)", func(t *testing.T) {
just := &vote.JustMainVoteConflict{
Just0: &vote.JustPreVoteSoft{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
},
Just1: &vote.JustInitOne{},
}
Expand All @@ -406,10 +406,10 @@ func TestInvalidJustMainVoteConflict(t *testing.T) {
t.Run("invalid value: unexpected justification", func(t *testing.T) {
just := &vote.JustMainVoteConflict{
Just0: &vote.JustInitZero{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
},
Just1: &vote.JustPreVoteSoft{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
},
}
v := vote.NewCPMainVote(td.RandHash(), h, r, 1, vote.CPValueAbstain, just, td.valKeys[tIndexB].Address())
Expand All @@ -423,7 +423,7 @@ func TestInvalidJustMainVoteConflict(t *testing.T) {

t.Run("invalid certificate", func(t *testing.T) {
just0 := &vote.JustInitZero{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
}
just := &vote.JustMainVoteConflict{
Just0: just0,
Expand All @@ -434,26 +434,26 @@ func TestInvalidJustMainVoteConflict(t *testing.T) {
err := td.consX.checkJust(v)
assert.ErrorIs(t, err, invalidJustificationError{
JustType: just0.Type(),
Reason: fmt.Sprintf("certificate height is invalid (expected 1 got %v)", just0.QCert.Height()),
Reason: fmt.Sprintf("certificate has an unexpected committers: %v", just0.QCert.Committers()),
})
})

t.Run("invalid certificate", func(t *testing.T) {
just0 := &vote.JustPreVoteSoft{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
}
just := &vote.JustMainVoteConflict{
Just0: just0,
Just1: &vote.JustPreVoteSoft{
QCert: td.GenerateTestCertificate(),
QCert: td.GenerateTestCertificate(h),
},
}
v := vote.NewCPMainVote(td.RandHash(), h, r, 1, vote.CPValueAbstain, just, td.valKeys[tIndexB].Address())

err := td.consX.checkJust(v)
assert.ErrorIs(t, err, invalidJustificationError{
JustType: just0.Type(),
Reason: fmt.Sprintf("certificate height is invalid (expected 1 got %v)", just0.QCert.Height()),
Reason: fmt.Sprintf("certificate has an unexpected committers: %v", just0.QCert.Committers()),
})
})
}
22 changes: 12 additions & 10 deletions consensus/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ func TestManager(t *testing.T) {
valKeys[4] = ts.RandValKey()
broadcastCh := make(chan message.Message, 500)

state.TestStore.SaveBlock(ts.RandHeight(), ts.GenerateTestBlock(), ts.GenerateTestCertificate())
height := ts.RandHeight()
blk, cert := ts.GenerateTestBlock(height)
state.TestStore.SaveBlock(blk, cert)

Mgr := NewManager(testConfig(), state, valKeys, rewardAddrs, broadcastCh)
mgr := Mgr.(*manager)
Expand All @@ -77,7 +79,7 @@ func TestManager(t *testing.T) {

assert.False(t, mgr.HasActiveInstance())
mgr.MoveToNewHeight()
curHeight := state.TestStore.LastHeight + 1
curHeight, _ := mgr.HeightRound()

newHeightTimeout(consA)

Expand Down Expand Up @@ -165,13 +167,13 @@ func TestManager(t *testing.T) {

assert.Len(t, mgr.upcomingVotes, 3)

err := state.CommitBlock(curHeight,
ts.GenerateTestBlockWithTime(util.Now().Add(1*time.Hour)), ts.GenerateTestCertificate())
blk, cert := ts.GenerateTestBlockWithTime(curHeight, util.Now().Add(1*time.Hour))
err := state.CommitBlock(blk, cert)
assert.NoError(t, err)
curHeight++

err = state.CommitBlock(curHeight,
ts.GenerateTestBlockWithTime(util.Now().Add(1*time.Hour)), ts.GenerateTestCertificate())
blk, cert = ts.GenerateTestBlockWithTime(curHeight, util.Now().Add(2*time.Hour))
err = state.CommitBlock(blk, cert)
assert.NoError(t, err)
curHeight++

Expand Down Expand Up @@ -200,13 +202,13 @@ func TestManager(t *testing.T) {

assert.Len(t, mgr.upcomingProposals, 3)

err := state.CommitBlock(curHeight,
ts.GenerateTestBlockWithTime(util.Now().Add(1*time.Hour)), ts.GenerateTestCertificate())
blk, cert := ts.GenerateTestBlockWithTime(curHeight, util.Now().Add(1*time.Hour))
err := state.CommitBlock(blk, cert)
assert.NoError(t, err)
curHeight++

err = state.CommitBlock(curHeight,
ts.GenerateTestBlockWithTime(util.Now().Add(1*time.Hour)), ts.GenerateTestCertificate())
blk, cert = ts.GenerateTestBlockWithTime(curHeight, util.Now().Add(2*time.Hour))
err = state.CommitBlock(blk, cert)
assert.NoError(t, err)

mgr.MoveToNewHeight()
Expand Down
26 changes: 13 additions & 13 deletions consensus/propose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,43 +23,43 @@ func TestSetProposalInvalidProposer(t *testing.T) {
assert.Nil(t, td.consY.RoundProposal(0))

addr := td.valKeys[tIndexB].Address()
b := td.GenerateTestBlockWithProposer(addr)
p := proposal.NewProposal(1, 0, b)
blk, _ := td.GenerateTestBlockWithProposer(1, addr)
invalidProp := proposal.NewProposal(1, 0, blk)

td.consY.SetProposal(p)
td.consY.SetProposal(invalidProp)
assert.Nil(t, td.consY.RoundProposal(0))

td.HelperSignProposal(td.valKeys[tIndexB], p) // Invalid signature
td.consY.SetProposal(p)
td.HelperSignProposal(td.valKeys[tIndexB], invalidProp)
td.consY.SetProposal(invalidProp)
assert.Nil(t, td.consY.RoundProposal(0))
}

func TestSetProposalInvalidBlock(t *testing.T) {
td := setup(t)

addr := td.valKeys[tIndexB].Address()
invBlock := td.GenerateTestBlockWithProposer(addr)
p := proposal.NewProposal(1, 2, invBlock)
td.HelperSignProposal(td.valKeys[tIndexB], p)
blk, _ := td.GenerateTestBlockWithProposer(1, addr)
invProp := proposal.NewProposal(1, 2, blk)
td.HelperSignProposal(td.valKeys[tIndexB], invProp)

td.enterNewHeight(td.consP)
td.enterNextRound(td.consP)
td.enterNextRound(td.consP)

td.consP.SetProposal(p)
td.consP.SetProposal(invProp)
assert.Nil(t, td.consP.RoundProposal(2))
}

func TestSetProposalInvalidHeight(t *testing.T) {
td := setup(t)

addr := td.valKeys[tIndexB].Address()
invBlock := td.GenerateTestBlockWithProposer(addr)
p := proposal.NewProposal(2, 0, invBlock)
td.HelperSignProposal(td.valKeys[tIndexB], p)
blk, _ := td.GenerateTestBlockWithProposer(2, addr)
invProp := proposal.NewProposal(2, 0, blk)
td.HelperSignProposal(td.valKeys[tIndexB], invProp)

td.enterNewHeight(td.consY)
td.consY.SetProposal(p)
td.consY.SetProposal(invProp)
assert.Nil(t, td.consY.RoundProposal(2))
}

Expand Down
10 changes: 5 additions & 5 deletions sandbox/sandbox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ func setup(t *testing.T) *testData {
}

lastHeight := uint32(21)
for i := uint32(1); i < lastHeight; i++ {
b := ts.GenerateTestBlock()
c := ts.GenerateTestCertificate()
mockStore.SaveBlock(i, b, c)
for height := uint32(1); height < lastHeight; height++ {
blk, cert := ts.GenerateTestBlock(height)
mockStore.SaveBlock(blk, cert)
}
sandbox := NewSandbox(mockStore.LastHeight,
mockStore, params, committee, totalPower).(*sandbox)
Expand Down Expand Up @@ -375,7 +374,8 @@ func TestPowerDelta(t *testing.T) {
func TestVerifyProof(t *testing.T) {
td := setup(t)

lastHeight, _ := td.store.LastCertificate()
lastCert := td.store.LastCertificate()
lastHeight := lastCert.Height()
vals := td.sandbox.committee.Validators()

// Try to evaluate a valid sortition
Expand Down
8 changes: 4 additions & 4 deletions state/execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ func TestProposeBlock(t *testing.T) {
td.moveToNextHeightForAllStates(t)
}
b1, c1 := td.makeBlockAndCertificate(t, 0, td.valKey1, td.valKey2, td.valKey3)
assert.NoError(t, td.state1.CommitBlock(curHeight+1, b1, c1))
assert.NoError(t, td.state2.CommitBlock(curHeight+1, b1, c1))
assert.NoError(t, td.state1.CommitBlock(b1, c1))
assert.NoError(t, td.state2.CommitBlock(b1, c1))
assert.Equal(t, td.state1.LastBlockHeight(), curHeight+1)

invSubsidyTx := tx.NewSubsidyTx(1, td.valKey2.Address(),
Expand All @@ -46,7 +46,7 @@ func TestProposeBlock(t *testing.T) {
assert.Equal(t, b2.Header().PrevBlockHash(), b1.Hash())
assert.Equal(t, b2.Transactions()[1:], block.Txs{trx1, trx2})
assert.True(t, b2.Transactions()[0].IsSubsidyTx())
assert.NoError(t, td.state1.CommitBlock(curHeight+2, b2, c2))
assert.NoError(t, td.state1.CommitBlock(b2, c2))

assert.Equal(t, td.state1.TotalPower(), int64(1000000004))
assert.Equal(t, td.state1.committee.TotalPower(), int64(4))
Expand All @@ -56,7 +56,7 @@ func TestExecuteBlock(t *testing.T) {
td := setup(t)

b1, c1 := td.makeBlockAndCertificate(t, 0, td.valKey1, td.valKey2, td.valKey3)
assert.NoError(t, td.state1.CommitBlock(1, b1, c1))
assert.NoError(t, td.state1.CommitBlock(b1, c1))

proposerAddr := td.RandAccAddress()
rewardAddr := td.RandAccAddress()
Expand Down
Loading