diff --git a/cmd/XDC/main.go b/cmd/XDC/main.go index fc07f31813..7d92aa6702 100644 --- a/cmd/XDC/main.go +++ b/cmd/XDC/main.go @@ -377,13 +377,16 @@ func startNode(ctx *cli.Context, stack *node.Node) { if err != nil { 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 { log.Info("No masternode candidates found. Keep the current masternodes set for the next epoch") } else { @@ -399,4 +402,4 @@ func startNode(ctx *cli.Context, stack *node.Node) { } }() } -} +} \ No newline at end of file diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 65d4eb560c..51174c4789 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -25,6 +25,7 @@ import ( "sync" "time" + "fmt" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -52,7 +53,7 @@ const ( type Masternode struct { Address common.Address - Stake int64 + Stake string } // Clique proof-of-authority protocol constants. @@ -394,7 +395,7 @@ func position(list []common.Address, x common.Address) int { 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 { // Not check signer for genesis block. return true, nil @@ -404,10 +405,21 @@ func YourTurn(snap *Snapshot, header *types.Header, cur common.Address) (bool, e if err != nil { return false, err } - preIndex := position(snap.signers(), pre) - curIndex := position(snap.signers(), cur) - log.Info("Debugging info", "number of masternodes", len(snap.signers()), "previous", pre, "position", preIndex, "current", cur, "position", curIndex) - return (preIndex+1)%len(snap.signers()) == curIndex, nil + 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) + 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. @@ -610,6 +622,29 @@ func (c *Clique) Prepare(chain consensus.ChainReader, header *types.Header) erro 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 // 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) { diff --git a/core/blockchain.go b/core/blockchain.go index 6da1cd0119..d79ebd2a3c 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -62,7 +62,7 @@ const ( // BlockChainVersion ensures that an incompatible database forces a resync from scratch. BlockChainVersion = 3 - M1Gap = 10 + M1Gap = 3 ) // CacheConfig contains the configuration values for the trie caching/pruning diff --git a/eth/backend.go b/eth/backend.go index 58ef2a40bc..dc44639756 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -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") } 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 { 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 } diff --git a/miner/worker.go b/miner/worker.go index 8f4c43df2c..557f915b91 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -421,13 +421,22 @@ func (self *worker) commitNewWork() { // check if we are right after parent's coinbase in the list // only go with Clique 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) snap, err := c.GetSnapshot(self.chain, parent.Header()) if err != nil { log.Error("Failed when trying to commit new work", "err", err) return } - ok, err := clique.YourTurn(snap, parent.Header(), self.coinbase) + 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