Skip to content

Commit

Permalink
Merge pull request #122 from nspcc-dev/upgrade-go
Browse files Browse the repository at this point in the history
Upgrade go
  • Loading branch information
AnnaShaleva authored Aug 15, 2024
2 parents befa250 + 4b821d6 commit b8b6211
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 47 deletions.
6 changes: 1 addition & 5 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,12 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go: [ '1.20', '1.21', '1.22']
go: [ '1.21', '1.22']
os: [ubuntu-latest, windows-2022, macos-14]
exclude:
# Only latest Go version for Windows and MacOS.
- os: windows-2022
go: '1.20'
- os: windows-2022
go: '1.21'
- os: macos-14
go: '1.20'
- os: macos-14
go: '1.21'
# Exclude latest Go version for Ubuntu as Coverage uses it.
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ New features:
Behaviour changes:

Improvements:
* minimum required Go version is 1.21 (#122)

Bugs fixed:

Expand Down
3 changes: 2 additions & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ type Config[H Hash] struct {
// NewBlockFromContext should allocate, fill from Context and return new block.Block.
NewBlockFromContext func(ctx *Context[H]) Block[H]
// RequestTx is a callback which is called when transaction contained
// in current block can't be found in memory pool.
// in current block can't be found in memory pool. The slice received by
// this callback MUST NOT be changed.
RequestTx func(h ...H)
// StopTxFlow is a callback which is called when the process no longer needs
// any transactions.
Expand Down
32 changes: 22 additions & 10 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,9 @@ func (c *Context[H]) reset(view byte, ts uint64) {
c.Validators = c.Config.GetValidators()

n := len(c.Validators)
c.LastChangeViewPayloads = make([]ConsensusPayload[H], n)
c.LastChangeViewPayloads = emptyReusableSlice(c.LastChangeViewPayloads, n)

if c.LastSeenMessage == nil {
c.LastSeenMessage = make([]*HeightView, n)
}
c.LastSeenMessage = emptyReusableSlice(c.LastSeenMessage, n)
c.blockProcessed = false
c.preBlockProcessed = false
} else {
Expand All @@ -252,16 +250,22 @@ func (c *Context[H]) reset(view byte, ts uint64) {
c.header = nil

n := len(c.Validators)
c.ChangeViewPayloads = make([]ConsensusPayload[H], n)
c.ChangeViewPayloads = emptyReusableSlice(c.ChangeViewPayloads, n)
if view == 0 {
c.PreCommitPayloads = make([]ConsensusPayload[H], n)
c.CommitPayloads = make([]ConsensusPayload[H], n)
c.PreCommitPayloads = emptyReusableSlice(c.PreCommitPayloads, n)
c.CommitPayloads = emptyReusableSlice(c.CommitPayloads, n)
}
c.PreparationPayloads = make([]ConsensusPayload[H], n)
c.PreparationPayloads = emptyReusableSlice(c.PreparationPayloads, n)

c.Transactions = make(map[H]Transaction[H])
if c.Transactions == nil { // Init.
c.Transactions = make(map[H]Transaction[H])
} else { // Regular use.
clear(c.Transactions)
}
c.TransactionHashes = nil
c.MissingTransactions = nil
if c.MissingTransactions != nil {
c.MissingTransactions = c.MissingTransactions[:0]
}
c.PrimaryIndex = c.GetPrimaryIndex(view)
c.ViewNumber = view

Expand All @@ -270,6 +274,14 @@ func (c *Context[H]) reset(view byte, ts uint64) {
}
}

func emptyReusableSlice[E any](s []E, n int) []E {
if len(s) == n {
clear(s)
return s
}
return make([]E, n)
}

// Fill initializes consensus when node is a speaker.
func (c *Context[H]) Fill() {
b := make([]byte, 8)
Expand Down
41 changes: 16 additions & 25 deletions dbft.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dbft

import (
"fmt"
"slices"
"sync"
"time"

Expand Down Expand Up @@ -150,9 +151,7 @@ func (d *DBFT[H]) initializeConsensus(view byte, ts uint64) {
var ts = d.Timer.Now()
var diff = ts.Sub(d.lastBlockTime)
timeout -= diff
if timeout < 0 {
timeout = 0
}
timeout = max(0, timeout)
}
d.changeTimer(timeout)
}
Expand All @@ -171,22 +170,17 @@ func (d *DBFT[H]) OnTransaction(tx Transaction[H]) {
return
}

for i := range d.MissingTransactions {
if tx.Hash() == d.MissingTransactions[i] {
d.addTransaction(tx)
// `addTransaction` checks for responses and commits. If this was the last transaction
// Context could be initialized on a new height, clearing this field.
if len(d.MissingTransactions) == 0 {
return
}
theLastOne := len(d.MissingTransactions) - 1
if i < theLastOne {
d.MissingTransactions[i] = d.MissingTransactions[theLastOne]
}
d.MissingTransactions = d.MissingTransactions[:theLastOne]
return
}
i := slices.Index(d.MissingTransactions, tx.Hash())
if i < 0 {
return
}
d.addTransaction(tx)
// `addTransaction` checks for responses and commits. If this was the last transaction
// Context could be initialized on a new height, clearing this field.
if len(d.MissingTransactions) == 0 {
return
}
d.MissingTransactions = slices.Delete(d.MissingTransactions, i, i+1)
}

// OnTimeout advances state machine as if timeout was fired.
Expand Down Expand Up @@ -340,24 +334,21 @@ func (d *DBFT[H]) onPrepareRequest(msg ConsensusPayload[H]) {
}

func (d *DBFT[H]) processMissingTx() {
missing := make([]H, 0, len(d.TransactionHashes)/2)

for _, h := range d.TransactionHashes {
if _, ok := d.Transactions[h]; ok {
continue
}
if tx := d.GetTx(h); tx == nil {
missing = append(missing, h)
d.MissingTransactions = append(d.MissingTransactions, h)
} else {
d.Transactions[h] = tx
}
}

if len(missing) != 0 {
d.MissingTransactions = missing
if len(d.MissingTransactions) != 0 {
d.Logger.Info("missing tx",
zap.Int("count", len(missing)))
d.RequestTx(missing...)
zap.Int("count", len(d.MissingTransactions)))
d.RequestTx(d.MissingTransactions...)
}
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/nspcc-dev/dbft

go 1.20
go 1.21

require (
github.com/stretchr/testify v1.9.0
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
github.com/twmb/murmur3 v1.1.8 h1:8Yt9taO/WN3l08xErzjeschgZU2QSrwm1kclYq+0aRg=
github.com/twmb/murmur3 v1.1.8/go.mod h1:Qq/R7NUyOfr65zD+6Q5IHKsJLwP7exErjN6lyyq3OSQ=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
Expand Down
10 changes: 5 additions & 5 deletions internal/simulation/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"net/http/pprof"
"os"
"os/signal"
"sort"
"slices"
"sync"
"syscall"
"time"
Expand Down Expand Up @@ -152,10 +152,10 @@ func updatePublicKeys(nodes []*simNode, n int) {
}

func sortValidators(pubs []dbft.PublicKey) {
sort.Slice(pubs, func(i, j int) bool {
p1, _ := pubs[i].(*crypto.ECDSAPub).MarshalBinary()
p2, _ := pubs[j].(*crypto.ECDSAPub).MarshalBinary()
return murmur3.Sum64(p1) < murmur3.Sum64(p2)
slices.SortFunc(pubs, func(a, b dbft.PublicKey) int {
p1, _ := a.(*crypto.ECDSAPub).MarshalBinary()
p2, _ := b.(*crypto.ECDSAPub).MarshalBinary()
return int(murmur3.Sum64(p2)) - int(murmur3.Sum64(p1))
})
}

Expand Down

0 comments on commit b8b6211

Please sign in to comment.