Skip to content

Commit

Permalink
Merge pull request #95 from nspcc-dev/improve-external-api
Browse files Browse the repository at this point in the history
Improve external api
  • Loading branch information
AnnaShaleva authored Feb 13, 2024
2 parents 3c9c1c8 + 902e6b5 commit 1483c28
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 19 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ concerning dBFT's time depending behaviour.

## Usage
A client of the library must implement its own event loop.
The library provides 4 callbacks:
The library provides 5 callbacks that change the state of the consensus
process:
- `Start()` which initializes internal dBFT structures
- `Reset()` which reinitializes the consensus process
- `OnTransaction()` which must be called everytime new transaction appears
- `OnReceive()` which must be called everytime new payload is received
- `OnTimer()` which must be called everytime timer fires
Expand All @@ -59,7 +61,7 @@ callback which is called at the start of every epoch. In the simple case where v
it can return the same value everytime it is called.
3. `ProcessBlock` is a callback which is called synchronously every time new block is accepted.
It can or can not persist block; it also may keep the blockchain state unchanged. dBFT will NOT
be initialized at the next height by itself to collect the next block until the `InitializeConsensus`
be initialized at the next height by itself to collect the next block until `Reset`
is called. In other words, it's the caller's responsibility to initialize dBFT at the next height even
after block collection at the current height. It's also the caller's responsibility to update the
blockchain state before the next height initialization so that other callbacks including
Expand Down
4 changes: 2 additions & 2 deletions check.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func (d *DBFT[H, A]) checkCommit() {
d.ProcessBlock(d.block)

// Do not initialize consensus process immediately. It's the caller's duty to
// start the new block acceptance process and call InitializeConsensus at the
// start the new block acceptance process and call Reset at the
// new height.
}

Expand Down Expand Up @@ -102,5 +102,5 @@ func (d *DBFT[H, A]) checkChangeView(view byte) {
}
}

d.InitializeConsensus(view, d.lastBlockTimestamp)
d.initializeConsensus(view, d.lastBlockTimestamp)
}
2 changes: 1 addition & 1 deletion context.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Context[H crypto.Hash, A crypto.Address] struct {
// blockProcessed denotes whether Config.ProcessBlock callback was called for the current
// height. If so, then no second call must happen. After new block is received by the user,
// dBFT stops any new transaction or messages processing as far as timeouts handling till
// the next call to InitializeConsensus.
// the next call to Reset.
blockProcessed bool

// BlockIndex is current block index.
Expand Down
32 changes: 18 additions & 14 deletions dbft.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import (
)

type (
// DBFT is a wrapper over Context containing service configuration and
// some other parameters not directly related to dBFT's state machine.
// DBFT is a dBFT implementation, it includes [Context] (main state)
// and [Config] (service configuration). Data exposed from these fields
// is supposed to be read-only, state is changed via methods of this
// structure.
DBFT[H crypto.Hash, A crypto.Address] struct {
Context[H, A]
Config[H, A]
Expand All @@ -22,13 +24,6 @@ type (
cache cache[H, A]
recovering bool
}
// Service is an interface for dBFT consensus.
Service[H crypto.Hash, A crypto.Address] interface {
Start(uint64)
OnTransaction(block.Transaction[H])
OnReceive(payload.ConsensusPayload[H, A])
OnTimeout(timer.HV)
}
)

// New returns new DBFT instance with specified H and A generic parameters
Expand Down Expand Up @@ -74,16 +69,25 @@ func (d *DBFT[H, A]) addTransaction(tx block.Transaction[H]) {
}
}

// Start initializes dBFT instance and starts protocol if node is primary. It
// accepts a timestamp of the previous block.
// Start initializes dBFT instance and starts the protocol if node is primary.
// It accepts the timestamp of the previous block. It should be called once
// per DBFT lifetime.
func (d *DBFT[H, A]) Start(ts uint64) {
d.cache = newCache[H, A]()
d.InitializeConsensus(0, ts)
d.initializeConsensus(0, ts)
d.start()
}

// InitializeConsensus initializes dBFT instance.
func (d *DBFT[H, A]) InitializeConsensus(view byte, ts uint64) {
// Reset reinitializes dBFT instance with the given timestamp of the previous
// block. It's used if the current consensus state is outdated which happens
// after new block is processed by ledger (the block can come from dBFT or be
// received by other means). The height is to be derived from the configured
// CurrentHeight callback and view will be set to 0.
func (d *DBFT[H, A]) Reset(ts uint64) {
d.initializeConsensus(0, ts)
}

func (d *DBFT[H, A]) initializeConsensus(view byte, ts uint64) {
d.reset(view, ts)

var role string
Expand Down

0 comments on commit 1483c28

Please sign in to comment.