aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2019-04-15 18:19:46 +0800
committerGitHub <noreply@github.com>2019-04-15 18:19:46 +0800
commit4a8d6480f7ab074bc032d68df6ee8df5876ef3cc (patch)
tree54fdb27d6254ecc56f27b7819e9e554c2b1e9f63
parentd77c1aa22cb6f2b76af3edf4995159b843838441 (diff)
downloaddexon-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
-rw-r--r--.gitignore4
-rw-r--r--cmd/govtool/main.go10
-rw-r--r--core/governance.go9
-rw-r--r--core/vm/oracle_contract_abi.go47
-rw-r--r--core/vm/oracle_contracts.go175
-rw-r--r--core/vm/oracle_contracts_test.go16
-rw-r--r--dex/governance.go14
-rw-r--r--params/config.go8
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go12
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go7
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go1
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go20
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go18
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/interfaces.go6
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go34
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/crypto.go27
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/signer.go7
-rw-r--r--vendor/vendor.json46
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"
},