aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go')
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go171
1 files changed, 86 insertions, 85 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go
index af9c3c42f..db13e7eba 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/lattice.go
@@ -49,16 +49,18 @@ type Lattice struct {
// NewLattice constructs an Lattice instance.
func NewLattice(
dMoment time.Time,
+ round uint64,
cfg *types.Config,
authModule *Authenticator,
app Application,
debug Debug,
db blockdb.BlockDatabase,
- logger common.Logger) (s *Lattice) {
+ logger common.Logger) *Lattice {
+
// Create genesis latticeDataConfig.
- dataConfig := newGenesisLatticeDataConfig(dMoment, cfg)
+ dataConfig := newGenesisLatticeDataConfig(dMoment, round, cfg)
toConfig := newGenesisTotalOrderingConfig(dMoment, cfg)
- s = &Lattice{
+ return &Lattice{
authModule: authModule,
app: app,
debug: debug,
@@ -68,51 +70,50 @@ func NewLattice(
ctModule: newConsensusTimestamp(dMoment, 0, cfg.NumChains),
logger: logger,
}
- return
}
-// PrepareBlock setup block's field based on current lattice status.
-func (s *Lattice) PrepareBlock(
+// PrepareBlock setups block's fields based on current status.
+func (l *Lattice) PrepareBlock(
b *types.Block, proposeTime time.Time) (err error) {
- s.lock.RLock()
- defer s.lock.RUnlock()
+ l.lock.RLock()
+ defer l.lock.RUnlock()
b.Timestamp = proposeTime
- if err = s.data.prepareBlock(b); err != nil {
+ if err = l.data.prepareBlock(b); err != nil {
return
}
- s.logger.Debug("Calling Application.PreparePayload", "position", b.Position)
- if b.Payload, err = s.app.PreparePayload(b.Position); err != nil {
+ l.logger.Debug("Calling Application.PreparePayload", "position", b.Position)
+ if b.Payload, err = l.app.PreparePayload(b.Position); err != nil {
return
}
- s.logger.Debug("Calling Application.PrepareWitness",
+ l.logger.Debug("Calling Application.PrepareWitness",
"height", b.Witness.Height)
- if b.Witness, err = s.app.PrepareWitness(b.Witness.Height); err != nil {
+ if b.Witness, err = l.app.PrepareWitness(b.Witness.Height); err != nil {
return
}
- if err = s.authModule.SignBlock(b); err != nil {
+ if err = l.authModule.SignBlock(b); err != nil {
return
}
return
}
-// PrepareEmptyBlock setup block's field based on current lattice status.
-func (s *Lattice) PrepareEmptyBlock(b *types.Block) (err error) {
- s.lock.RLock()
- defer s.lock.RUnlock()
- s.data.prepareEmptyBlock(b)
+// PrepareEmptyBlock setups block's fields based on current lattice status.
+func (l *Lattice) PrepareEmptyBlock(b *types.Block) (err error) {
+ l.lock.RLock()
+ defer l.lock.RUnlock()
+ l.data.prepareEmptyBlock(b)
if b.Hash, err = hashBlock(b); err != nil {
return
}
return
}
-// SanityCheck check if a block is valid.
+// SanityCheck checks the validity of a block.
//
-// If some acking blocks don't exists, Lattice would help to cache this block
-// and retry when lattice updated in Lattice.ProcessBlock.
-func (s *Lattice) SanityCheck(b *types.Block) (err error) {
+// If any acking blocks of this block does not exist, Lattice helps caching this
+// block and retries when Lattice.ProcessBlock is called.
+func (l *Lattice) SanityCheck(b *types.Block) (err error) {
if b.IsEmpty() {
// Only need to verify block's hash.
var hash common.Hash
@@ -124,7 +125,7 @@ func (s *Lattice) SanityCheck(b *types.Block) (err error) {
}
} else {
// Verify block's signature.
- if err = s.authModule.VerifyBlock(b); err != nil {
+ if err = l.authModule.VerifyBlock(b); err != nil {
return
}
}
@@ -139,13 +140,13 @@ func (s *Lattice) SanityCheck(b *types.Block) (err error) {
}
}
if err = func() (err error) {
- s.lock.RLock()
- defer s.lock.RUnlock()
- if err = s.data.sanityCheck(b); err != nil {
+ l.lock.RLock()
+ defer l.lock.RUnlock()
+ if err = l.data.sanityCheck(b); err != nil {
if _, ok := err.(*ErrAckingBlockNotExists); ok {
err = ErrRetrySanityCheckLater
}
- s.logger.Error("Sanity Check failed", "error", err)
+ l.logger.Error("Sanity Check failed", "error", err)
return
}
return
@@ -153,8 +154,8 @@ func (s *Lattice) SanityCheck(b *types.Block) (err error) {
return
}
// Verify data in application layer.
- s.logger.Debug("Calling Application.VerifyBlock", "block", b)
- switch s.app.VerifyBlock(b) {
+ l.logger.Debug("Calling Application.VerifyBlock", "block", b)
+ switch l.app.VerifyBlock(b) {
case types.VerifyInvalidBlock:
err = ErrInvalidBlock
case types.VerifyRetryLater:
@@ -163,31 +164,33 @@ func (s *Lattice) SanityCheck(b *types.Block) (err error) {
return
}
-// addBlockToLattice adds a block into lattice, and deliver blocks with the acks
-// already delivered.
+// addBlockToLattice adds a block into lattice, and delivers blocks with the
+// acks already delivered.
//
-// NOTE: assume the block passed sanity check.
-func (s *Lattice) addBlockToLattice(
+// NOTE: input block should pass sanity check.
+func (l *Lattice) addBlockToLattice(
input *types.Block) (outputBlocks []*types.Block, err error) {
- if tip := s.data.chains[input.Position.ChainID].tip; tip != nil {
+
+ if tip := l.data.chains[input.Position.ChainID].tip; tip != nil {
if !input.Position.Newer(&tip.Position) {
return
}
}
- s.pool.addBlock(input)
- // Replay tips in pool to check their validity.
+ l.pool.addBlock(input)
+ // Check tips in pool to check their validity for moving blocks from pool
+ // to lattice.
for {
hasOutput := false
- for i := uint32(0); i < uint32(len(s.pool)); i++ {
+ for i := uint32(0); i < uint32(len(l.pool)); i++ {
var tip *types.Block
- if tip = s.pool.tip(i); tip == nil {
+ if tip = l.pool.tip(i); tip == nil {
continue
}
- err = s.data.sanityCheck(tip)
+ err = l.data.sanityCheck(tip)
if err == nil {
var output []*types.Block
- if output, err = s.data.addBlock(tip); err != nil {
- s.logger.Error("Sanity Check failed", "error", err)
+ if output, err = l.data.addBlock(tip); err != nil {
+ l.logger.Error("Sanity Check failed", "error", err)
continue
}
hasOutput = true
@@ -197,7 +200,7 @@ func (s *Lattice) addBlockToLattice(
err = nil
continue
}
- s.pool.removeTip(i)
+ l.pool.removeTip(i)
}
if !hasOutput {
break
@@ -206,13 +209,13 @@ func (s *Lattice) addBlockToLattice(
for _, b := range outputBlocks {
// TODO(jimmy-dexon): change this name of classic DEXON algorithm.
- if s.debug != nil {
- s.debug.StronglyAcked(b.Hash)
+ if l.debug != nil {
+ l.debug.StronglyAcked(b.Hash)
}
- s.logger.Debug("Calling Application.BlockConfirmed", "block", input)
- s.app.BlockConfirmed(*b.Clone())
+ l.logger.Debug("Calling Application.BlockConfirmed", "block", input)
+ l.app.BlockConfirmed(*b.Clone())
// Purge blocks in pool with the same chainID and lower height.
- s.pool.purgeBlocks(b.Position.ChainID, b.Position.Height)
+ l.pool.purgeBlocks(b.Position.ChainID, b.Position.Height)
}
return
@@ -223,7 +226,7 @@ func (s *Lattice) addBlockToLattice(
// would be returned, too.
//
// NOTE: assume the block passed sanity check.
-func (s *Lattice) ProcessBlock(
+func (l *Lattice) ProcessBlock(
input *types.Block) (delivered []*types.Block, err error) {
var (
b *types.Block
@@ -232,10 +235,10 @@ func (s *Lattice) ProcessBlock(
deliveredMode uint32
)
- s.lock.Lock()
- defer s.lock.Unlock()
+ l.lock.Lock()
+ defer l.lock.Unlock()
- if inLattice, err = s.addBlockToLattice(input); err != nil {
+ if inLattice, err = l.addBlockToLattice(input); err != nil {
return
}
@@ -245,7 +248,7 @@ func (s *Lattice) ProcessBlock(
// Perform total ordering for each block added to lattice.
for _, b = range inLattice {
- toDelivered, deliveredMode, err = s.toModule.processBlock(b)
+ toDelivered, deliveredMode, err = l.toModule.processBlock(b)
if err != nil {
// All errors from total ordering is serious, should panic.
panic(err)
@@ -257,11 +260,11 @@ func (s *Lattice) ProcessBlock(
for idx := range toDelivered {
hashes[idx] = toDelivered[idx].Hash
}
- if s.debug != nil {
- s.debug.TotalOrderingDelivered(hashes, deliveredMode)
+ if l.debug != nil {
+ l.debug.TotalOrderingDelivered(hashes, deliveredMode)
}
- // Perform timestamp generation.
- if err = s.ctModule.processBlocks(toDelivered); err != nil {
+ // Perform consensus timestamp module.
+ if err = l.ctModule.processBlocks(toDelivered); err != nil {
return
}
delivered = append(delivered, toDelivered...)
@@ -269,49 +272,47 @@ func (s *Lattice) ProcessBlock(
return
}
-// NextPosition returns expected position of incoming block for that chain.
-func (s *Lattice) NextPosition(chainID uint32) types.Position {
- s.lock.RLock()
- defer s.lock.RUnlock()
-
- return s.data.nextPosition(chainID)
+// NextPosition returns expected position of incoming block for specified chain.
+func (l *Lattice) NextPosition(chainID uint32) types.Position {
+ l.lock.RLock()
+ defer l.lock.RUnlock()
+ return l.data.nextPosition(chainID)
}
-// PurgeBlocks from cache of blocks in memory, this is called when the caller
-// make sure those blocks are saved to db.
-func (s *Lattice) PurgeBlocks(blocks []*types.Block) error {
- s.lock.Lock()
- defer s.lock.Unlock()
-
- return s.data.purgeBlocks(blocks)
+// PurgeBlocks purges blocks' cache in memory, this is called when the caller
+// makes sure those blocks are already saved in db.
+func (l *Lattice) PurgeBlocks(blocks []*types.Block) error {
+ l.lock.Lock()
+ defer l.lock.Unlock()
+ return l.data.purgeBlocks(blocks)
}
-// AppendConfig add new configs for upcoming rounds. If you add a config for
-// round R, next time you can only add the config for round R+1.
-func (s *Lattice) AppendConfig(round uint64, config *types.Config) (err error) {
- s.lock.Lock()
- defer s.lock.Unlock()
+// AppendConfig adds a new config for upcoming rounds. If a config of round r is
+// added, only config in round r + 1 is allowed next.
+func (l *Lattice) AppendConfig(round uint64, config *types.Config) (err error) {
+ l.lock.Lock()
+ defer l.lock.Unlock()
- s.pool.resize(config.NumChains)
- if err = s.data.appendConfig(round, config); err != nil {
+ l.pool.resize(config.NumChains)
+ if err = l.data.appendConfig(round, config); err != nil {
return
}
- if err = s.toModule.appendConfig(round, config); err != nil {
+ if err = l.toModule.appendConfig(round, config); err != nil {
return
}
- if err = s.ctModule.appendConfig(round, config); err != nil {
+ if err = l.ctModule.appendConfig(round, config); err != nil {
return
}
return
}
// ProcessFinalizedBlock is used for syncing lattice data.
-func (s *Lattice) ProcessFinalizedBlock(input *types.Block) {
- defer func() { s.retryAdd = true }()
- s.lock.Lock()
- defer s.lock.Unlock()
- if err := s.data.addFinalizedBlock(input); err != nil {
+func (l *Lattice) ProcessFinalizedBlock(b *types.Block) {
+ defer func() { l.retryAdd = true }()
+ l.lock.Lock()
+ defer l.lock.Unlock()
+ if err := l.data.addFinalizedBlock(b); err != nil {
panic(err)
}
- s.pool.purgeBlocks(input.Position.ChainID, input.Position.Height)
+ l.pool.purgeBlocks(b.Position.ChainID, b.Position.Height)
}