@ -22,82 +22,6 @@ const (
BlockPeriod = 10 * time . Second
)
// WaitForConsensusReady listen for the readiness signal from consensus and generate new block for consensus.
func ( node * Node ) WaitForConsensusReady ( readySignal chan struct { } , stopChan chan struct { } , stoppedChan chan struct { } ) {
go func ( ) {
// Setup stoppedChan
defer close ( stoppedChan )
utils . GetLogInstance ( ) . Debug ( "Waiting for Consensus ready" )
time . Sleep ( 30 * time . Second ) // Wait for other nodes to be ready (test-only)
firstTime := true
var newBlock * types . Block
timeoutCount := 0
deadline := time . Now ( ) . Add ( BlockPeriod )
for {
// keep waiting for Consensus ready
select {
case <- readySignal :
time . Sleep ( 1000 * time . Millisecond ) // Delay a bit so validator is catched up (test-only).
case <- time . After ( ConsensusTimeOut * time . Second ) :
node . Consensus . ResetState ( )
timeoutCount ++
utils . GetLogInstance ( ) . Debug ( "Consensus timeout, retry!" , "count" , timeoutCount )
// FIXME: retry is not working, there is no retry logic here. It will only wait for new transaction.
case <- stopChan :
utils . GetLogInstance ( ) . Debug ( "Consensus propose new block: STOPPED!" )
return
}
for {
// threshold and firstTime are for the test-only built-in smart contract tx.
// TODO: remove in production
threshold := DefaultThreshold
if firstTime {
threshold = FirstTimeThreshold
firstTime = false
}
if len ( node . pendingTransactions ) >= threshold || ! time . Now ( ) . Before ( deadline ) {
deadline = time . Now ( ) . Add ( BlockPeriod )
utils . GetLogInstance ( ) . Debug ( "PROPOSING NEW BLOCK ------------------------------------------------" , "blockNum" , node . Blockchain ( ) . CurrentBlock ( ) . NumberU64 ( ) + 1 , "threshold" , threshold , "pendingTransactions" , len ( node . pendingTransactions ) )
// Normal tx block consensus
selectedTxs := node . getTransactionsForNewBlock ( MaxNumberOfTransactionsPerBlock )
if err := node . Worker . CommitTransactions ( selectedTxs ) ; err != nil {
ctxerror . Log15 ( utils . GetLogger ( ) . Error ,
ctxerror . New ( "cannot commit transacttions" ) .
WithCause ( err ) )
}
block , err := node . Worker . Commit ( )
if err != nil {
ctxerror . Log15 ( utils . GetLogInstance ( ) . Error ,
ctxerror . New ( "Failed committing new block" ) .
WithCause ( err ) )
} else if err := node . proposeShardState ( block ) ; err != nil {
ctxerror . Log15 ( utils . GetLogger ( ) . Error ,
ctxerror . New ( "cannot add shard state" ) .
WithCause ( err ) )
} else {
newBlock = block
utils . GetLogInstance ( ) . Debug ( "Successfully proposed new block" , "blockNum" , block . NumberU64 ( ) , "numTxs" , block . Transactions ( ) . Len ( ) )
threshold = DefaultThreshold
break
}
}
// If not enough transactions to run Consensus,
// periodically check whether we have enough transactions to package into block.
time . Sleep ( PeriodicBlock )
}
// Send the new block to Consensus so it can be confirmed.
if newBlock != nil {
utils . GetLogInstance ( ) . Debug ( "Consensus sending new block to block channel" )
node . BlockChannel <- newBlock
utils . GetLogInstance ( ) . Debug ( "Consensus sent new block to block channel" )
}
}
} ( )
}
// WaitForConsensusReadyv2 listen for the readiness signal from consensus and generate new block for consensus.
// only leader will receive the ready signal
// TODO: clean pending transactions for validators; or validators not prepare pending transactions