diff options
author | Jimmy Hu <jimmy.hu@dexon.org> | 2019-04-15 18:19:46 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-15 18:19:46 +0800 |
commit | 4a8d6480f7ab074bc032d68df6ee8df5876ef3cc (patch) | |
tree | 54fdb27d6254ecc56f27b7819e9e554c2b1e9f63 | |
parent | d77c1aa22cb6f2b76af3edf4995159b843838441 (diff) | |
download | dexon-4a8d6480f7ab074bc032d68df6ee8df5876ef3cc.tar.gz dexon-4a8d6480f7ab074bc032d68df6ee8df5876ef3cc.tar.zst dexon-4a8d6480f7ab074bc032d68df6ee8df5876ef3cc.zip |
core: implement DKG success (#362)
* vendor: sync to latest core
* core: implmenet dkg success
* cmd: govtool: add DKGSuccess
19 files changed, 391 insertions, 72 deletions
diff --git a/.gitignore b/.gitignore index f3ec219c7..1e62cbb81 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,7 @@ profile.cov test/Dexon.* test/*.log dex/transactions.rlp + +# consensus +vendor/github.com/dexon-foundation/mcl/lib/*.dylib +vendor/github.com/dexon-foundation/bls/lib/*.dylib diff --git a/cmd/govtool/main.go b/cmd/govtool/main.go index 239c95003..1425b9faf 100644 --- a/cmd/govtool/main.go +++ b/cmd/govtool/main.go @@ -90,6 +90,16 @@ func decodeInput(ctx *cli.Context) error { utils.Fatalf("%s", err) } fmt.Println(finalize) + case "addDKGSuccess": + var Success []byte + if err := method.Inputs.Unpack(&Success, arguments); err != nil { + utils.Fatalf("%s", err) + } + var success dkgTypes.Success + if err := rlp.DecodeBytes(Success, &success); err != nil { + utils.Fatalf("%s", err) + } + fmt.Println(success) case "report": args := struct { Type *big.Int diff --git a/core/governance.go b/core/governance.go index 39b2704e6..277b3bb89 100644 --- a/core/governance.go +++ b/core/governance.go @@ -310,6 +310,15 @@ func (g *Governance) IsDKGFinal(round uint64) bool { return count >= threshold } +func (g *Governance) IsDKGSuccess(round uint64) bool { + s := g.GetStateForDKGAtRound(round) + if s == nil { + return false + } + return s.DKGSuccessesCount().Uint64() >= + uint64(coreUtils.GetDKGValidThreshold(g.Configuration(round))) +} + func (g *Governance) MinGasPrice(round uint64) *big.Int { return g.GetStateForConfigAtRound(round).MinGasPrice() } diff --git a/core/vm/oracle_contract_abi.go b/core/vm/oracle_contract_abi.go index bd99c0cc7..dc44552a2 100644 --- a/core/vm/oracle_contract_abi.go +++ b/core/vm/oracle_contract_abi.go @@ -24,6 +24,25 @@ const GovernanceABIJSON = ` [ { "constant": true, + "inputs": [ + { + "name": "", + "type": "address" + } + ], + "name": "dkgSuccesses", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, "inputs": [], "name": "notarySetSize", "outputs": [ @@ -191,6 +210,20 @@ const GovernanceABIJSON = ` }, { "constant": true, + "inputs": [], + "name": "dkgSuccessesCount", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, "inputs": [ { "name": "", @@ -1030,6 +1063,20 @@ const GovernanceABIJSON = ` "constant": false, "inputs": [ { + "name": "Success", + "type": "bytes" + } + ], + "name": "addDKGSuccess", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { "name": "PublicKey", "type": "bytes" }, diff --git a/core/vm/oracle_contracts.go b/core/vm/oracle_contracts.go index 4878fd325..b36a05d15 100644 --- a/core/vm/oracle_contracts.go +++ b/core/vm/oracle_contracts.go @@ -78,6 +78,8 @@ const ( dkgReadysCountLoc dkgFinalizedLoc dkgFinalizedsCountLoc + dkgSuccessLoc + dkgSuccessesCountLoc ownerLoc minStakeLoc lockupPeriodLoc @@ -766,6 +768,37 @@ func (s *GovernanceState) ResetDKGFinalizedsCount() { s.setStateBigInt(big.NewInt(dkgFinalizedsCountLoc), big.NewInt(0)) } +// mapping(address => bool) public dkgSuccesses; +func (s *GovernanceState) DKGSuccess(addr common.Address) bool { + mapLoc := s.getMapLoc(big.NewInt(dkgSuccessLoc), addr.Bytes()) + return s.getStateBigInt(mapLoc).Cmp(big.NewInt(0)) != 0 +} +func (s *GovernanceState) PutDKGSuccess(addr common.Address, success bool) { + mapLoc := s.getMapLoc(big.NewInt(dkgSuccessLoc), addr.Bytes()) + res := big.NewInt(0) + if success { + res = big.NewInt(1) + } + s.setStateBigInt(mapLoc, res) +} +func (s *GovernanceState) ClearDKGSuccesses(dkgSet map[coreTypes.NodeID]struct{}) { + for id := range dkgSet { + s.PutDKGSuccess(IdToAddress(id), false) + } +} + +// uint256 public dkgSuccessesCount; +func (s *GovernanceState) DKGSuccessesCount() *big.Int { + return s.getStateBigInt(big.NewInt(dkgSuccessesCountLoc)) +} +func (s *GovernanceState) IncDKGSuccessesCount() { + s.setStateBigInt(big.NewInt(dkgSuccessesCountLoc), + new(big.Int).Add(s.getStateBigInt(big.NewInt(dkgSuccessesCountLoc)), big.NewInt(1))) +} +func (s *GovernanceState) ResetDKGSuccessesCount() { + s.setStateBigInt(big.NewInt(dkgSuccessesCountLoc), big.NewInt(0)) +} + // address public owner; func (s *GovernanceState) Owner() common.Address { val := s.getState(common.BigToHash(big.NewInt(ownerLoc))) @@ -1357,6 +1390,8 @@ func (g *GovernanceContract) clearDKG() { g.state.ResetDKGMPKReadysCount() g.state.ClearDKGFinalizeds(dkgSet) g.state.ResetDKGFinalizedsCount() + g.state.ClearDKGSuccesses(dkgSet) + g.state.ResetDKGSuccessesCount() } func (g *GovernanceContract) fineFailStopDKG(threshold int) { @@ -1628,6 +1663,40 @@ func (g *GovernanceContract) addDKGFinalize(finalize []byte) ([]byte, error) { return g.useGas(GovernanceActionGasCost) } +func (g *GovernanceContract) addDKGSuccess(success []byte) ([]byte, error) { + caller := g.contract.Caller() + + var dkgSuccess dkgTypes.Success + if err := rlp.DecodeBytes(success, &dkgSuccess); err != nil { + return nil, errExecutionReverted + } + round := big.NewInt(int64(dkgSuccess.Round)) + if round.Uint64() != g.evm.Round.Uint64()+1 { + return nil, errExecutionReverted + } + + if dkgSuccess.Reset != g.state.DKGResetCount(round).Uint64() { + return nil, errExecutionReverted + } + + // DKGFInalize must belongs to someone in DKG set. + if !g.inNotarySet(round, dkgSuccess.ProposerID) { + return nil, errExecutionReverted + } + + verified, _ := coreUtils.VerifyDKGSuccessSignature(&dkgSuccess) + if !verified { + return nil, errExecutionReverted + } + + if !g.state.DKGSuccess(caller) { + g.state.PutDKGSuccess(caller, true) + g.state.IncDKGSuccessesCount() + } + + return g.useGas(GovernanceActionGasCost) +} + func (g *GovernanceContract) updateConfiguration(cfg *rawConfigStruct) ([]byte, error) { // Only owner can update configuration. if g.contract.Caller() != g.state.Owner() { @@ -1974,9 +2043,9 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) { } // Extend the the current round. - // target = (80 + 100 * DKGResetCount)% + // target = (85 + 100 * DKGResetCount)% target := new(big.Int).Add( - big.NewInt(80), + big.NewInt(85), new(big.Int).Mul(big.NewInt(100), resetCount)) roundHeight := g.state.RoundHeight(round) @@ -1991,37 +2060,42 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) { targetBlockNum.Quo(targetBlockNum, big.NewInt(100)) targetBlockNum.Add(targetBlockNum, roundHeight) - // Check if current block over 80% of current round. + // Check if current block over 85%of current round. blockHeight := g.evm.Context.BlockNumber if blockHeight.Cmp(targetBlockNum) < 0 { return nil, errExecutionReverted } - // Check if next DKG did not success. - // Calculate 2f + 1 - threshold := 2*g.configNotarySetSize(g.evm.Round).Uint64()/3 + 1 tsigThreshold := coreUtils.GetDKGThreshold(&coreTypes.Config{ - NotarySetSize: uint32(g.configNotarySetSize(g.evm.Round).Uint64())}) - - // If 2f + 1 of DKG set is finalized, check if DKG succeeded. - if g.state.DKGFinalizedsCount().Uint64() >= threshold { - gpk, err := g.coreDKGUtils.NewGroupPublicKey(&g.state, nextRound, tsigThreshold) - if gpk, ok := gpk.(*dkgTypes.GroupPublicKey); ok { - nextRound := new(big.Int).Add(g.evm.Round, big.NewInt(1)) - if len(gpk.QualifyNodeIDs) < coreUtils.GetDKGValidThreshold(&coreTypes.Config{ - NotarySetSize: uint32(g.configNotarySetSize(nextRound).Uint64())}) { - err = dkgTypes.ErrNotReachThreshold + NotarySetSize: uint32(g.configNotarySetSize(nextRound).Uint64())}) + // Check if next DKG has not enough of success. + if g.state.DKGSuccessesCount().Uint64() >= + uint64(coreUtils.GetDKGValidThreshold(&coreTypes.Config{ + NotarySetSize: uint32(g.configNotarySetSize(nextRound).Uint64()), + })) { + // Check if next DKG did not success. + // Calculate 2f + 1 + threshold := 2*g.configNotarySetSize(nextRound).Uint64()/3 + 1 + + // If 2f + 1 of DKG set is finalized, check if DKG succeeded. + if g.state.DKGFinalizedsCount().Uint64() >= threshold { + gpk, err := g.coreDKGUtils.NewGroupPublicKey(&g.state, nextRound, tsigThreshold) + if gpk, ok := gpk.(*dkgTypes.GroupPublicKey); ok { + if len(gpk.QualifyNodeIDs) < coreUtils.GetDKGValidThreshold(&coreTypes.Config{ + NotarySetSize: uint32(g.configNotarySetSize(nextRound).Uint64())}) { + err = dkgTypes.ErrNotReachThreshold + } } - } - // DKG success. - if err == nil { - return nil, errExecutionReverted - } - switch err { - case dkgTypes.ErrNotReachThreshold, dkgTypes.ErrInvalidThreshold: - default: - return nil, errExecutionReverted + // DKG success. + if err == nil { + return nil, errExecutionReverted + } + switch err { + case dkgTypes.ErrNotReachThreshold, dkgTypes.ErrInvalidThreshold: + default: + return nil, errExecutionReverted + } } } @@ -2046,7 +2120,9 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) { prevCRS = crypto.Keccak256Hash(prevCRS[:]) } - dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(state, round, tsigThreshold) + dkgGPK, err := g.coreDKGUtils.NewGroupPublicKey(state, round, + coreUtils.GetDKGThreshold(&coreTypes.Config{ + NotarySetSize: uint32(g.configNotarySetSize(round).Uint64())})) if err != nil { return nil, errExecutionReverted } @@ -2058,19 +2134,17 @@ func (g *GovernanceContract) resetDKG(newSignedCRS []byte) ([]byte, error) { return nil, errExecutionReverted } - newRound := new(big.Int).Add(g.evm.Round, big.NewInt(1)) - // Clear DKG states for next round. g.clearDKG() - g.state.SetDKGRound(newRound) + g.state.SetDKGRound(nextRound) // Save new CRS into state and increase round. newCRS := crypto.Keccak256(newSignedCRS) crs := common.BytesToHash(newCRS) g.state.SetCRS(crs) - g.state.SetCRSRound(newRound) - g.state.emitCRSProposed(newRound, crs) + g.state.SetCRSRound(nextRound) + g.state.emitCRSProposed(nextRound, crs) // Increase reset count. g.state.IncDKGResetCount(nextRound) @@ -2124,6 +2198,12 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re return nil, errExecutionReverted } return g.addDKGFinalize(Finalize) + case "addDKGSuccess": + var Success []byte + if err := method.Inputs.Unpack(&Success, arguments); err != nil { + return nil, errExecutionReverted + } + return g.addDKGSuccess(Success) case "nodesLength": res, err := method.Outputs.Pack(g.state.LenNodes()) if err != nil { @@ -2266,6 +2346,24 @@ func (g *GovernanceContract) Run(evm *EVM, input []byte, contract *Contract) (re return nil, errExecutionReverted } return res, nil + case "dkgSuccesses": + addr := common.Address{} + if err := method.Inputs.Unpack(&addr, arguments); err != nil { + return nil, errExecutionReverted + } + finalized := g.state.DKGSuccess(addr) + res, err := method.Outputs.Pack(finalized) + if err != nil { + return nil, errExecutionReverted + } + return res, nil + case "dkgSuccessesCount": + count := g.state.DKGSuccessesCount() + res, err := method.Outputs.Pack(count) + if err != nil { + return nil, errExecutionReverted + } + return res, nil case "dkgMasterPublicKeys": offset := new(big.Int) if err := method.Inputs.Unpack(&offset, arguments); err != nil { @@ -2632,6 +2730,21 @@ func PackAddDKGFinalize(final *dkgTypes.Finalize) ([]byte, error) { return data, nil } +func PackAddDKGSuccess(final *dkgTypes.Success) ([]byte, error) { + method := GovernanceABI.Name2Method["addDKGSuccess"] + encoded, err := rlp.EncodeToBytes(final) + if err != nil { + return nil, err + } + + res, err := method.Inputs.Pack(encoded) + if err != nil { + return nil, err + } + data := append(method.Id(), res...) + return data, nil +} + func PackReportForkVote(vote1, vote2 *coreTypes.Vote) ([]byte, error) { method := GovernanceABI.Name2Method["report"] diff --git a/core/vm/oracle_contracts_test.go b/core/vm/oracle_contracts_test.go index 269421717..4fb05a34e 100644 --- a/core/vm/oracle_contracts_test.go +++ b/core/vm/oracle_contracts_test.go @@ -985,6 +985,8 @@ func (g *OracleContractsTestSuite) TestResetDKG() { g.s.ResetDKGMPKReadysCount() g.s.ClearDKGFinalizeds(dkgSet) g.s.ResetDKGFinalizedsCount() + g.s.ClearDKGSuccesses(dkgSet) + g.s.ResetDKGSuccessesCount() g.s.SetDKGRound(big.NewInt(int64(round))) } @@ -1034,6 +1036,9 @@ func (g *OracleContractsTestSuite) TestResetDKG() { // Prepare Finalized. g.s.PutDKGFinalized(addr, true) g.s.IncDKGFinalizedsCount() + // Prepare Success. + g.s.PutDKGSuccess(addr, true) + g.s.IncDKGSuccessesCount() } i += 1 } @@ -1050,6 +1055,10 @@ func (g *OracleContractsTestSuite) TestResetDKG() { for _, addr := range addrs[round] { g.Require().True(g.s.DKGFinalized(addr)) } + g.Require().Equal(int64(dkgSetSize), g.s.DKGSuccessesCount().Int64()) + for _, addr := range addrs[round] { + g.Require().True(g.s.DKGSuccess(addr)) + } } } @@ -1089,7 +1098,7 @@ func (g *OracleContractsTestSuite) TestResetDKG() { g.s.IncDKGFinalizedsCount() g.context.BlockNumber = big.NewInt( - roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*80/100) + roundHeight*int64(round) + roundHeight*int64(r) + roundHeight*85/100) _, addr := newPrefundAccount(g.stateDB) newCRS := randomBytes(common.HashLength, common.HashLength) input, err := GovernanceABI.ABI.Pack("resetDKG", newCRS) @@ -1115,6 +1124,11 @@ func (g *OracleContractsTestSuite) TestResetDKG() { for _, addr := range addrs[round+1] { g.Require().False(g.s.DKGFinalized(addr)) } + // Test if Success is purged. + g.Require().Equal(int64(0), g.s.DKGSuccessesCount().Int64()) + for _, addr := range addrs[round+1] { + g.Require().False(g.s.DKGSuccess(addr)) + } g.Require().Equal(int64(r+1), g.s.DKGResetCount(roundPlusOne).Int64()) diff --git a/dex/governance.go b/dex/governance.go index b8dcf1589..ec09969b0 100644 --- a/dex/governance.go +++ b/dex/governance.go @@ -177,6 +177,20 @@ func (d *DexconGovernance) AddDKGFinalize(final *dkgTypes.Finalize) { } } +// AddDKGSuccess adds a DKG success message. +func (d *DexconGovernance) AddDKGSuccess(success *dkgTypes.Success) { + data, err := vm.PackAddDKGSuccess(success) + if err != nil { + log.Error("Failed to pack addDKGSuccess input", "err", err) + return + } + + err = d.sendGovTx(context.Background(), data) + if err != nil { + log.Error("Failed to send addDKGSuccess tx", "err", err) + } +} + // ReportForkVote reports a node for forking votes. func (d *DexconGovernance) ReportForkVote(vote1, vote2 *coreTypes.Vote) { data, err := vm.PackReportForkVote(vote1, vote2) diff --git a/params/config.go b/params/config.go index 14b336dfa..9d428f544 100644 --- a/params/config.go +++ b/params/config.go @@ -26,10 +26,10 @@ import ( // Genesis hashes to enforce below configs on. var ( - MainnetGenesisHash = common.HexToHash("0x55f87cf5428a78a015d06088cb76b4f50afa7b081a45a25dbf0ae7ffb2366b98") - TestnetGenesisHash = common.HexToHash("0xd3fdd64dfeed341be98d39732f65c8b31dbb72a703c1b91083b6d2bf2f8f184f") - TaipeiGenesisHash = common.HexToHash("0xec0bff2d28a4cb4a2b6a689ee71f450ec56d0438d0fcb4ef18c4c6a231dc8df4") - YilanGenesisHash = common.HexToHash("0x6618f722c32f044ecd9ce09f02efc9757744762a6d7e12c4bd0aedc6b83ae92b") + MainnetGenesisHash = common.HexToHash("0xc8f6f69570e8eb740f3d74995702f4fc4dfa613ec56a0cebf941cc035606099b") + TestnetGenesisHash = common.HexToHash("0x7d8700a7a731162880adff4f21398a901c0b75d907bec8f4eac51460f94cb846") + TaipeiGenesisHash = common.HexToHash("0x5929cb70fe4ba22dce821b2efca737a1874a0f5a34f3ffb9a1e157516622e20b") + YilanGenesisHash = common.HexToHash("0xdcdafc044c24d728c6149ecfada746d8de6e59fc5d18063caf7950badc1df12e") ) var ( diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go index 4597fe92b..f65903d25 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go @@ -564,11 +564,13 @@ func (mgr *agreementMgr) baRoutineForOneRound( default: } nextHeight, nextTime = mgr.bcModule.nextBlock() - if isStop(restartPos) { - break - } - if nextHeight > restartPos.Height { - break + if nextHeight != notReadyHeight { + if isStop(restartPos) { + break + } + if nextHeight > restartPos.Height { + break + } } mgr.logger.Debug("BlockChain not ready!!!", "old", oldPos, "restart", restartPos, "next", nextHeight) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go index 1efd867e7..4fae221c7 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go @@ -21,6 +21,7 @@ import ( "bytes" "errors" "fmt" + "math" "sort" "sync" "time" @@ -49,6 +50,8 @@ var ( ErrMissingRandomness = errors.New("missing block randomness") ) +const notReadyHeight uint64 = math.MaxUint64 + type pendingBlockRecord struct { position types.Position block *types.Block @@ -384,6 +387,10 @@ func (bc *blockChain) nextBlock() (uint64, time.Time) { if tip == nil { return types.GenesisHeight, bc.dMoment } + if tip != bc.lastDelivered { + // If tip is not delivered, we should not proceed to next block. + return notReadyHeight, time.Time{} + } return tip.Position.Height + 1, tip.Timestamp.Add(config.minBlockInterval) } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go index e9e04a28c..4e70ff087 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go @@ -400,6 +400,7 @@ func (cc *configurationChain) runDKGPhaseNine(round uint64, reset uint64) error cc.db.PutDKGPrivateKey(round, reset, *signer.privateKey); err != nil { return err } + cc.dkg.proposeSuccess() cc.dkgResult.Lock() defer cc.dkgResult.Unlock() cc.dkgSigner[round] = signer diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go index 968b90e99..ba7d8fd60 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go @@ -496,6 +496,16 @@ func (recv *consensusDKGReceiver) ProposeDKGFinalize(final *typesDKG.Finalize) { recv.gov.AddDKGFinalize(final) } +// ProposeDKGSuccess propose a DKGSuccess message. +func (recv *consensusDKGReceiver) ProposeDKGSuccess(success *typesDKG.Success) { + if err := recv.signer.SignDKGSuccess(success); err != nil { + recv.logger.Error("Failed to sign DKG successize", "error", err) + return + } + recv.logger.Debug("Calling Governance.AddDKGSuccess", "success", success) + recv.gov.AddDKGSuccess(success) +} + // Consensus implements DEXON Consensus algorithm. type Consensus struct { // Node Info. @@ -818,6 +828,12 @@ func (con *Consensus) prepare(initBlock *types.Block) (err error) { "reset", e.Reset) return false } + if !con.gov.IsDKGSuccess(nextRound) { + con.logger.Error("Next DKG is not success, reset it", + "round", e.Round, + "reset", e.Reset) + return false + } gpk, err := typesDKG.NewGroupPublicKey( nextRound, con.gov.DKGMasterPublicKeys(nextRound), @@ -1132,6 +1148,10 @@ func (con *Consensus) generateBlockRandomness(blocks []*types.Block) { "block", block, "result", result) con.network.BroadcastAgreementResult(result) + if err := con.deliverFinalizedBlocks(); err != nil { + con.logger.Error("Failed to deliver finalized block", + "error", err) + } } }(block) } diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go index 0612bda4b..8383ad118 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go @@ -102,6 +102,9 @@ type dkgReceiver interface { // ProposeDKGFinalize propose a DKGFinalize message. ProposeDKGFinalize(final *typesDKG.Finalize) + + // ProposeDKGSuccess propose a DKGSuccess message. + ProposeDKGSuccess(final *typesDKG.Success) } type dkgProtocol struct { @@ -487,10 +490,13 @@ func (d *dkgProtocol) processPrivateShare( if _, exist := d.antiComplaintReceived[prvShare.ReceiverID]; !exist { d.antiComplaintReceived[prvShare.ReceiverID] = make(map[types.NodeID]struct{}) + } + if _, exist := + d.antiComplaintReceived[prvShare.ReceiverID][prvShare.ProposerID]; !exist { d.recv.ProposeDKGAntiNackComplaint(prvShare) + d.antiComplaintReceived[prvShare.ReceiverID][prvShare.ProposerID] = + struct{}{} } - d.antiComplaintReceived[prvShare.ReceiverID][prvShare.ProposerID] = - struct{}{} } return nil } @@ -511,6 +517,14 @@ func (d *dkgProtocol) proposeFinalize() { }) } +func (d *dkgProtocol) proposeSuccess() { + d.recv.ProposeDKGSuccess(&typesDKG.Success{ + ProposerID: d.ID, + Round: d.round, + Reset: d.reset, + }) +} + func (d *dkgProtocol) recoverShareSecret(qualifyIDs dkg.IDs) ( *dkgShareSecret, error) { if len(qualifyIDs) < d.threshold { diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go index c16c624e3..c88b3dcb4 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go @@ -141,6 +141,12 @@ type Governance interface { // IsDKGFinal checks if DKG is final. IsDKGFinal(round uint64) bool + // AddDKGSuccess adds a DKG success message. + AddDKGSuccess(success *typesDKG.Success) + + // IsDKGSuccess checks if DKG is success. + IsDKGSuccess(round uint64) bool + // ReportForkVote reports a node for forking votes. ReportForkVote(vote1, vote2 *types.Vote) diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go index 868f0da17..cb921e586 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go @@ -242,6 +242,11 @@ func (c *Complaint) DecodeRLP(s *rlp.Stream) error { return nil } +// IsNack returns true if it's a nack complaint in DKG protocol. +func (c *Complaint) IsNack() bool { + return len(c.PrivateShare.Signature.Signature) == 0 +} + // PartialSignature describe a partial signature in DKG protocol. type PartialSignature struct { ProposerID types.NodeID `json:"proposer_id"` @@ -251,7 +256,7 @@ type PartialSignature struct { Signature crypto.Signature `json:"signature"` } -// MPKReady describe a dig ready message in DKG protocol. +// MPKReady describe a dkg ready message in DKG protocol. type MPKReady struct { ProposerID types.NodeID `json:"proposer_id"` Round uint64 `json:"round"` @@ -275,7 +280,7 @@ func (ready *MPKReady) Equal(other *MPKReady) bool { bytes.Compare(ready.Signature.Signature, other.Signature.Signature) == 0 } -// Finalize describe a dig finalize message in DKG protocol. +// Finalize describe a dkg finalize message in DKG protocol. type Finalize struct { ProposerID types.NodeID `json:"proposer_id"` Round uint64 `json:"round"` @@ -299,9 +304,28 @@ func (final *Finalize) Equal(other *Finalize) bool { bytes.Compare(final.Signature.Signature, other.Signature.Signature) == 0 } -// IsNack returns true if it's a nack complaint in DKG protocol. -func (c *Complaint) IsNack() bool { - return len(c.PrivateShare.Signature.Signature) == 0 +// Success describe a dkg success message in DKG protocol. +type Success struct { + ProposerID types.NodeID `json:"proposer_id"` + Round uint64 `json:"round"` + Reset uint64 `json:"reset"` + Signature crypto.Signature `json:"signature"` +} + +func (s *Success) String() string { + return fmt.Sprintf("DKGSuccess{SP:%s Round:%d Reset:%d}", + s.ProposerID.String()[:6], + s.Round, + s.Reset) +} + +// Equal check equality of two Success instances. +func (s *Success) Equal(other *Success) bool { + return s.ProposerID.Equal(other.ProposerID) && + s.Round == other.Round && + s.Reset == other.Reset && + s.Signature.Type == other.Signature.Type && + bytes.Compare(s.Signature.Signature, other.Signature.Signature) == 0 } // GroupPublicKey is the result of DKG protocol. diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go index 496944dab..42ee6122e 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go @@ -325,6 +325,19 @@ func hashDKGFinalize(final *typesDKG.Finalize) common.Hash { ) } +func hashDKGSuccess(success *typesDKG.Success) common.Hash { + binaryRound := make([]byte, 8) + binary.LittleEndian.PutUint64(binaryRound, success.Round) + binaryReset := make([]byte, 8) + binary.LittleEndian.PutUint64(binaryReset, success.Reset) + + return crypto.Keccak256Hash( + success.ProposerID.Hash[:], + binaryRound, + binaryReset, + ) +} + // VerifyDKGFinalizeSignature verifies DKGFinalize signature. func VerifyDKGFinalizeSignature( final *typesDKG.Finalize) (bool, error) { @@ -339,6 +352,20 @@ func VerifyDKGFinalizeSignature( return true, nil } +// VerifyDKGSuccessSignature verifies DKGSuccess signature. +func VerifyDKGSuccessSignature( + success *typesDKG.Success) (bool, error) { + hash := hashDKGSuccess(success) + pubKey, err := crypto.SigToPub(hash, success.Signature) + if err != nil { + return false, err + } + if success.ProposerID != types.NewNodeID(pubKey) { + return false, nil + } + return true, nil +} + // Rehash hashes the hash again and again and again... func Rehash(hash common.Hash, count uint) common.Hash { result := hash diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go index 602d2da16..b1d4d230e 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go @@ -84,7 +84,7 @@ func (e RoundEventParam) NextTouchNodeSetCacheHeight() uint64 { // NextDKGResetHeight returns the height to reset DKG for next period. func (e RoundEventParam) NextDKGResetHeight() uint64 { - return e.BeginHeight + e.Config.RoundLength*8/10 + return e.BeginHeight + e.Config.RoundLength*85/100 } // NextDKGRegisterHeight returns the height to register DKG. diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go index 9904410c4..ff767437f 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go @@ -145,3 +145,10 @@ func (s *Signer) SignDKGFinalize(final *typesDKG.Finalize) (err error) { final.Signature, err = s.prvKey.Sign(hashDKGFinalize(final)) return } + +// SignDKGSuccess signs a DKG success message. +func (s *Signer) SignDKGSuccess(success *typesDKG.Success) (err error) { + success.ProposerID = s.proposerID + success.Signature, err = s.prvKey.Sign(hashDKGSuccess(success)) + return +} diff --git a/vendor/vendor.json b/vendor/vendor.json index eac81e0b8..3480eec30 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -141,16 +141,16 @@ { "checksumSHA1": "In6vBHYUsX7DUIGiFN2hQggBgvI=", "path": "github.com/dexon-foundation/dexon-consensus/common", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { - "checksumSHA1": "6anh4sqNQZY5ZD+cZoTIB+N4PRc=", + "checksumSHA1": "1RGs5z/8Kq82E69C8aRUAZT3U24=", "path": "github.com/dexon-foundation/dexon-consensus/core", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, @@ -165,64 +165,64 @@ { "checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { "checksumSHA1": "4besQaa0rm8jRUAJjpEaLZ/ZOYs=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { "checksumSHA1": "BhLKK8RveoLaeXc9UyUKMwQqchU=", "path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { "checksumSHA1": "3Ludp/1V4dMBZH/c1oIVjHj0CqY=", "path": "github.com/dexon-foundation/dexon-consensus/core/db", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { "checksumSHA1": "sO5twEFTdLvkMuQo+I3vyzm9T3o=", "path": "github.com/dexon-foundation/dexon-consensus/core/syncer", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { "checksumSHA1": "0BY+E0E2cM7IHIMqunXwoolDS5Y=", "path": "github.com/dexon-foundation/dexon-consensus/core/types", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { - "checksumSHA1": "lbG7yqVgzo2CV/CQPYjG78xp5jg=", + "checksumSHA1": "yEPSfn48GaJmDbd2OFY+QRhjJ0w=", "path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, { - "checksumSHA1": "C2r/uE8K53WIIA0FYYHIfR2xhng=", + "checksumSHA1": "7Ib134BAyLF1M/kREou4Zm7UUS4=", "path": "github.com/dexon-foundation/dexon-consensus/core/utils", - "revision": "2d26246247e2f7e616cc3d13b9d61308580e7d67", - "revisionTime": "2019-04-13T15:07:46Z", + "revision": "e9a1d3bca8353ee206d262ab1fad2d7e3e0b24a5", + "revisionTime": "2019-04-15T04:12:22Z", "version": "master", "versionExact": "master" }, |