get masternodes set from latest checkpoint block header instead of fr… …

This commit is contained in:
MestryOmkar 2018-10-10 14:15:15 +05:30
parent 5b26898ad5
commit f814908442
5 changed files with 64 additions and 30 deletions

View file

@ -377,13 +377,16 @@ func startNode(ctx *cli.Context, stack *node.Node) {
if err != nil { if err != nil {
log.Warn("Can't get cap of a masternode candidate. Will ignore him", "address", candidate, "error", err) log.Warn("Can't get cap of a masternode candidate. Will ignore him", "address", candidate, "error", err)
} }
ms = append(ms, clique.Masternode{Address: candidate, Stake: v.Int64()}) ms = append(ms, clique.Masternode{Address: candidate, Stake: v.String()})
}
//// order by cap
//sort.Slice(ms, func(i, j int) bool {
// return ms[i].Stake > ms[j].Stake
//})
log.Info("Ordered list of masternode candidates")
for _, m := range ms {
fmt.Printf("address: %s, stake: %s\n", m.Address.String(), m.Stake)
} }
// order by cap
sort.Slice(ms, func(i, j int) bool {
return ms[i].Stake > ms[j].Stake
})
log.Info("Ordered list of masternode candidates", "candidates", ms)
if len(ms) == 0 { if len(ms) == 0 {
log.Info("No masternode candidates found. Keep the current masternodes set for the next epoch") log.Info("No masternode candidates found. Keep the current masternodes set for the next epoch")
} else { } else {
@ -399,4 +402,4 @@ func startNode(ctx *cli.Context, stack *node.Node) {
} }
}() }()
} }
} }

View file

@ -25,6 +25,7 @@ import (
"sync" "sync"
"time" "time"
"fmt"
"github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
@ -52,7 +53,7 @@ const (
type Masternode struct { type Masternode struct {
Address common.Address Address common.Address
Stake int64 Stake string
} }
// Clique proof-of-authority protocol constants. // Clique proof-of-authority protocol constants.
@ -394,7 +395,7 @@ func position(list []common.Address, x common.Address) int {
return -1 return -1
} }
func YourTurn(snap *Snapshot, header *types.Header, cur common.Address) (bool, error) { func YourTurn(masternodes []common.Address, snap *Snapshot, header *types.Header, cur common.Address) (bool, error) {
if header.Number.Uint64() == 0 { if header.Number.Uint64() == 0 {
// Not check signer for genesis block. // Not check signer for genesis block.
return true, nil return true, nil
@ -404,10 +405,21 @@ func YourTurn(snap *Snapshot, header *types.Header, cur common.Address) (bool, e
if err != nil { if err != nil {
return false, err return false, err
} }
preIndex := position(snap.signers(), pre) preIndex := position(masternodes, pre)
curIndex := position(snap.signers(), cur) curIndex := position(masternodes, cur)
log.Info("Debugging info", "number of masternodes", len(snap.signers()), "previous", pre, "position", preIndex, "current", cur, "position", curIndex) log.Info("Debugging info", "number of masternodes", len(masternodes), "previous", pre, "position", preIndex, "current", cur, "position", curIndex)
return (preIndex+1)%len(snap.signers()) == curIndex, nil for i, s := range masternodes {
fmt.Printf("%d - %s\n", i, s.String())
}
return (preIndex+1)%len(masternodes) == curIndex, nil
}
func GetExtraVanity() int {
return extraVanity
}
func GetExtraSeal() int {
return extraSeal
} }
// snapshot retrieves the authorization snapshot at a given point in time. // snapshot retrieves the authorization snapshot at a given point in time.
@ -610,6 +622,29 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro
return nil return nil
} }
func (c *Clique) UpdateMasternodes(chain consensus.ChainReader, header *types.Header, ms []Masternode) error {
number := header.Number.Uint64()
log.Trace("take snapshot", "number", number, "hash", header.Hash())
snap, err := c.snapshot(chain, number, header.Hash(), nil)
if err != nil {
return err
}
currentSigners := snap.signers()
proposedSigners := make(map[common.Address]struct{})
// count all addresses in ms to be masternode
for _, m := range ms {
proposedSigners[m.Address] = struct{}{}
c.proposals[m.Address] = true
}
// deactivate current masternodes which aren't in ms
for _, s := range currentSigners {
if _, ok := proposedSigners[s]; !ok {
c.proposals[s] = false
}
}
return nil
}
// Finalize implements consensus.Engine, ensuring no uncles are set, nor block // Finalize implements consensus.Engine, ensuring no uncles are set, nor block
// rewards given, and returns the final block. // rewards given, and returns the final block.
func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) { func (c *Clique) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction, uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {

View file

@ -62,7 +62,7 @@ const (
// BlockChainVersion ensures that an incompatible database forces a resync from scratch. // BlockChainVersion ensures that an incompatible database forces a resync from scratch.
BlockChainVersion = 3 BlockChainVersion = 3
M1Gap = 10 M1Gap = 3
) )
// CacheConfig contains the configuration values for the trie caching/pruning // CacheConfig contains the configuration values for the trie caching/pruning

View file

@ -238,7 +238,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
} }
} }
return nil return nil
} }
} }
@ -428,23 +428,10 @@ func (s *Ethereum) UpdateMasternodes(ms []clique.Masternode) error {
return errors.New("not clique") return errors.New("not clique")
} }
c := s.engine.(*clique.Clique) c := s.engine.(*clique.Clique)
snap, err := c.GetSnapshot(s.blockchain, s.blockchain.CurrentHeader()) err := c.UpdateMasternodes(s.blockchain, s.blockchain.CurrentHeader(), ms)
if err != nil { if err != nil {
return err return err
} }
snap.Signers = make(map[common.Address]struct{})
for i, m := range ms {
if i == NumOfMasternodes {
break
}
snap.Signers[m.Address] = struct{}{}
}
err = c.StoreSnapshot(snap)
if err != nil {
return err
}
log.Trace("Stored masternodes snapshot to db", "number", snap.Number, "hash", snap.Hash)
return nil return nil
} }

View file

@ -421,13 +421,22 @@ func (self *worker) commitNewWork() {
// check if we are right after parent's coinbase in the list // check if we are right after parent's coinbase in the list
// only go with Clique // only go with Clique
if self.config.Clique != nil { if self.config.Clique != nil {
// get masternodes set from latest checkpoint
lastCheckpointNumber := parent.NumberU64() - (parent.NumberU64() % self.config.Clique.Epoch)
preCheckpointHeader := self.chain.GetHeaderByNumber(lastCheckpointNumber)
extraVanity := clique.GetExtraVanity()
extraSeal := clique.GetExtraSeal()
masternodes := make([]common.Address, (len(preCheckpointHeader.Extra)-extraVanity-extraSeal)/common.AddressLength)
for i := 0; i < len(masternodes); i++ {
copy(masternodes[i][:], preCheckpointHeader.Extra[extraVanity+i*common.AddressLength:])
}
c := self.engine.(*clique.Clique) c := self.engine.(*clique.Clique)
snap, err := c.GetSnapshot(self.chain, parent.Header()) snap, err := c.GetSnapshot(self.chain, parent.Header())
if err != nil { if err != nil {
log.Error("Failed when trying to commit new work", "err", err) log.Error("Failed when trying to commit new work", "err", err)
return return
} }
ok, err := clique.YourTurn(snap, parent.Header(), self.coinbase) ok, err := clique.YourTurn(masternodes, snap, parent.Header(), self.coinbase)
if err != nil { if err != nil {
log.Error("Failed when trying to commit new work", "err", err) log.Error("Failed when trying to commit new work", "err", err)
return return