Merge pull request #80 from ngtuna/m1-down

masternode should also count to his turn in case some of his friends are down
This commit is contained in:
Tuna 2018-07-19 17:43:07 +07:00 committed by GitHub
commit abf4f09b6b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 54 additions and 11 deletions

View file

@ -48,7 +48,6 @@ const (
inmemorySnapshots = 128 // Number of recent vote snapshots to keep in memory
inmemorySignatures = 4096 // Number of recent block signatures to keep in memory
wiggleTime = 500 * time.Millisecond // Random delay (per signer) to allow concurrent signers
)
type Masternode struct {
@ -405,7 +404,9 @@ func (c *Clique) GetMasternodes(chain consensus.ChainReader, header *types.Heade
return masternodes
}
func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header, cur common.Address) (bool, error) {
func (c *Clique) GetPeriod() uint64 { return c.config.Period }
func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header, cur common.Address) (int, int, bool, error) {
pre := common.Address{}
// masternode[0] has chance to create block 1
var err error
@ -413,16 +414,19 @@ func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header
if header.Number.Uint64() != 0 {
pre, err = ecrecover(header, snap.sigcache)
if err != nil {
return false, err
return 0, 0, false, err
}
preIndex = position(masternodes, pre)
}
curIndex := position(masternodes, cur)
log.Info("Debugging info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", cur, "position", curIndex)
log.Info("Masternodes cycle info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", cur, "position", curIndex)
for i, s := range masternodes {
fmt.Printf("%d - %s\n", i, s.String())
}
return (preIndex+1)%len(masternodes) == curIndex, nil
if (preIndex+1)%len(masternodes) == curIndex {
return preIndex, curIndex, true, nil
}
return preIndex, curIndex, false, nil
}
// snapshot retrieves the authorization snapshot at a given point in time.

View file

@ -1243,7 +1243,6 @@ func (st *insertStats) report(chain []*types.Block, index int, cache common.Stor
context = append(context, []interface{}{"ignored", st.ignored}...)
}
log.Info("Imported new chain segment", context...)
*st = insertStats{startTime: now, lastIndex: index + 1}
}
}

View file

@ -51,6 +51,8 @@ const (
chainHeadChanSize = 10
// chainSideChanSize is the size of channel listening to ChainSideEvent.
chainSideChanSize = 10
// Timeout waiting for M1
m1Timeout = 1
)
// Agent can register themself with the worker
@ -415,6 +417,24 @@ func (self *worker) makeCurrent(parent *types.Block, header *types.Header) error
return nil
}
func abs(x int64) int64 {
if x < 0 {
return -x
}
return x
}
func hop(len, pre, cur int) int {
switch {
case pre < cur:
return cur - (pre + 1)
case pre > cur:
return (len - pre) + (cur - 1)
default:
return len - 1
}
}
func (self *worker) commitNewWork() {
self.mu.Lock()
defer self.mu.Unlock()
@ -439,15 +459,35 @@ func (self *worker) commitNewWork() {
log.Error("Failed when trying to commit new work", "err", err)
return
}
ok, err := clique.YourTurn(masternodes, snap, parent.Header(), self.coinbase)
preIndex, curIndex, ok, err := clique.YourTurn(masternodes, snap, parent.Header(), self.coinbase)
if err != nil {
log.Error("Failed when trying to commit new work", "err", err)
return
}
if !ok {
log.Info("Not our turn to commit block. Wait for next time")
log.Info("Not my turn to commit block. Waiting...")
// in case some nodes are down
if preIndex == -1 {
// first block
return
}
h := hop(len(masternodes), preIndex, curIndex)
gap := int64(c.GetPeriod()) * int64(h)
log.Info("Distance from the parent block", "seconds", gap, "hops", h)
L:
select {
case newBlock := <-self.chainHeadCh:
if newBlock.Block.NumberU64() > parent.NumberU64() {
log.Info("New block has came already. Skip this turn", "new block", newBlock.Block.NumberU64(), "current block", parent.NumberU64())
self.chainHeadCh <- newBlock
return
}
case <-time.After(time.Duration(gap+m1Timeout) * time.Second):
// wait enough. It's my turn
log.Info("Wait enough. It's my turn", "waited seconds", gap+m1Timeout)
break L
}
}
}
}