From ca65d2dee0e6ce937c63876291714156193c11ff Mon Sep 17 00:00:00 2001 From: oopcode Date: Sun, 15 Dec 2019 22:20:50 +0300 Subject: [PATCH 1/7] feat: proper evidence --- go.mod | 2 +- lib/dealer/dkg_dealer.go | 78 +++++++++++++++++++++++++--------------- lib/offChain/dkg.go | 6 ++-- lib/onChain/dkg.go | 2 +- lib/types/dkg.go | 7 ++++ lib/types/interface.go | 3 +- 6 files changed, 62 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index e44dc1a..09f9b75 100644 --- a/go.mod +++ b/go.mod @@ -13,4 +13,4 @@ require ( replace golang.org/x/crypto => github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5 -replace github.com/tendermint/tendermint => github.com/dgamingfoundation/tendermint v0.27.4-0.20191113121517-26e7e4991bbf +replace github.com/tendermint/tendermint => ../tendermint diff --git a/lib/dealer/dkg_dealer.go b/lib/dealer/dkg_dealer.go index 13d52e2..e2811d2 100644 --- a/lib/dealer/dkg_dealer.go +++ b/lib/dealer/dkg_dealer.go @@ -28,8 +28,7 @@ type Dealer interface { GetState() DealerState Transit() error GenerateTransitions() - GetLosers() []*tmtypes.Validator - PopLosers() []*tmtypes.Validator + GetLosers() []*types.DKGLoser HandleDKGPubKey(msg *alias.DKGData) error SetTransitions(t []transition) SendDeals() (err error, ready bool) @@ -80,7 +79,7 @@ type DKGDealer struct { complaints *messageStore reconstructCommits *messageStore - losers []crypto.Address + losers []*types.DKGLoser } type DealerState struct { @@ -191,20 +190,8 @@ func (d *DKGDealer) SetTransitions(t []transition) { d.transitions = t } -func (d *DKGDealer) GetLosers() []*tmtypes.Validator { - var out []*tmtypes.Validator - for _, loser := range d.losers { - _, validator := d.validators.GetByAddress(loser) - out = append(out, validator) - } - - return out -} - -func (d *DKGDealer) PopLosers() []*tmtypes.Validator { - out := d.GetLosers() - d.losers = nil - return out +func (d *DKGDealer) GetLosers() []*types.DKGLoser { + return d.losers } ////////////////////////////////////////////////////////////////////////////// @@ -219,11 +206,16 @@ func (d *DKGDealer) HandleDKGPubKey(msg *alias.DKGData) error { pubKey = d.suiteG2.Point() ) if err := dec.Decode(pubKey); err != nil { - d.losers = append(d.losers, crypto.Address(msg.Addr)) + _, validator := d.validators.GetByAddress(msg.Addr) + d.losers = append(d.losers, &types.DKGLoser{ + Height: 0, + Reason: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) return fmt.Errorf("dkgState: failed to decode public key from %s: %v", msg.Addr, err) } // TODO: check if we want to slash validators who send duplicate keys - // (we probably do). + // TODO (we probably do). d.pubKeys.Add(&PK2Addr{PK: pubKey, Addr: crypto.Address(msg.Addr)}) if err := d.Transit(); err != nil { @@ -313,7 +305,12 @@ func (d *DKGDealer) HandleDKGDeal(msg *alias.DKGData) error { } ) if err := dec.Decode(deal); err != nil { - d.losers = append(d.losers, crypto.Address(msg.Addr)) + _, validator := d.validators.GetByAddress(msg.Addr) + d.losers = append(d.losers, &types.DKGLoser{ + Height: 0, + Reason: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) return fmt.Errorf("failed to decode deal: %v", err) } @@ -395,7 +392,12 @@ func (d *DKGDealer) HandleDKGResponse(msg *alias.DKGData) error { resp = &dkg.Response{} ) if err := dec.Decode(resp); err != nil { - d.losers = append(d.losers, crypto.Address(msg.Addr)) + _, validator := d.validators.GetByAddress(msg.Addr) + d.losers = append(d.losers, &types.DKGLoser{ + Height: 0, + Reason: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) return fmt.Errorf("failed to decode deal: %v", err) } @@ -503,7 +505,12 @@ func (d *DKGDealer) HandleDKGJustification(msg *alias.DKGData) error { dec := gob.NewDecoder(bytes.NewBuffer(msg.Data)) justification = &dkg.Justification{} if err := dec.Decode(justification); err != nil { - d.losers = append(d.losers, crypto.Address(msg.Addr)) + _, validator := d.validators.GetByAddress(msg.Addr) + d.losers = append(d.losers, &types.DKGLoser{ + Height: 0, + Reason: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) return fmt.Errorf("failed to decode deal: %v", err) } } @@ -586,13 +593,11 @@ func (d DKGDealer) GetCommits() (*dkg.SecretCommits, error) { qualSet[idx] = true } - for idx, pk2addr := range d.pubKeys { + for idx, _ := range d.pubKeys { if !qualSet[idx] { - d.losers = append(d.losers, pk2addr.Addr) + return nil, errors.New("some of participants failed to complete phase I") } } - - return nil, errors.New("some of participants failed to complete phase I") } commits, err := d.instance.SecretCommits() @@ -616,7 +621,12 @@ func (d *DKGDealer) HandleDKGCommit(msg *alias.DKGData) error { commits.Commitments = append(commits.Commitments, d.suiteG2.Point()) } if err := dec.Decode(commits); err != nil { - d.losers = append(d.losers, crypto.Address(msg.Addr)) + _, validator := d.validators.GetByAddress(msg.Addr) + d.losers = append(d.losers, &types.DKGLoser{ + Height: 0, + Reason: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) return fmt.Errorf("failed to decode commit: %v", err) } d.commits.add(msg.GetAddrString(), commits) @@ -689,7 +699,12 @@ func (d *DKGDealer) HandleDKGComplaint(msg *alias.DKGData) error { complaint.Deal.Commitments = append(complaint.Deal.Commitments, d.suiteG2.Point()) } if err := dec.Decode(complaint); err != nil { - d.losers = append(d.losers, crypto.Address(msg.Addr)) + _, validator := d.validators.GetByAddress(msg.Addr) + d.losers = append(d.losers, &types.DKGLoser{ + Height: 0, + Reason: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) return fmt.Errorf("failed to decode complaint: %v", err) } } @@ -750,7 +765,12 @@ func (d *DKGDealer) HandleDKGReconstructCommit(msg *alias.DKGData) error { dec := gob.NewDecoder(bytes.NewBuffer(msg.Data)) rc = &dkg.ReconstructCommits{} if err := dec.Decode(rc); err != nil { - d.losers = append(d.losers, crypto.Address(msg.Addr)) + _, validator := d.validators.GetByAddress(msg.Addr) + d.losers = append(d.losers, &types.DKGLoser{ + Height: 0, + Reason: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) return fmt.Errorf("failed to decode complaint: %v", err) } } diff --git a/lib/offChain/dkg.go b/lib/offChain/dkg.go index 5394f72..0953aa6 100644 --- a/lib/offChain/dkg.go +++ b/lib/offChain/dkg.go @@ -9,9 +9,9 @@ import ( dkgalias "github.com/dgamingfoundation/dkglib/lib/alias" "github.com/dgamingfoundation/dkglib/lib/blsShare" dkglib "github.com/dgamingfoundation/dkglib/lib/dealer" + "github.com/dgamingfoundation/dkglib/lib/types" dkgtypes "github.com/dgamingfoundation/dkglib/lib/types" "github.com/tendermint/tendermint/alias" - tmtypes "github.com/tendermint/tendermint/alias" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/events" "github.com/tendermint/tendermint/libs/log" @@ -259,7 +259,7 @@ func (m *OffChainDKG) GetPrivValidator() alias.PrivValidator { return m.privValidator } -func (m *OffChainDKG) GetLosers() []*tmtypes.Validator { +func (m *OffChainDKG) GetLosers() []*types.DKGLoser { m.mtx.Lock() defer m.mtx.Unlock() @@ -268,7 +268,7 @@ func (m *OffChainDKG) GetLosers() []*tmtypes.Validator { panic(fmt.Sprintf("failed to get dealer for current round ID (%d)", m.dkgRoundID)) } - return dealer.PopLosers() + return dealer.GetLosers() } type verifierFunc func(s string, i int) dkgtypes.Verifier diff --git a/lib/onChain/dkg.go b/lib/onChain/dkg.go index e25ea87..723edec 100644 --- a/lib/onChain/dkg.go +++ b/lib/onChain/dkg.go @@ -97,7 +97,7 @@ func (m *OnChainDKG) StartRound( return nil } -func (m *OnChainDKG) GetLosers() []*tmtypes.Validator { +func (m *OnChainDKG) GetLosers() []*types.DKGLoser { return m.dealer.GetLosers() } diff --git a/lib/types/dkg.go b/lib/types/dkg.go index ad52d4a..079bbdd 100644 --- a/lib/types/dkg.go +++ b/lib/types/dkg.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/dgamingfoundation/dkglib/lib/alias" + tmtypes "github.com/tendermint/tendermint/alias" ) var ( @@ -22,3 +23,9 @@ func (m *DKGDataMessage) ValidateBasic() error { func (m *DKGDataMessage) String() string { return fmt.Sprintf("[Proposal %+v]", m.Data) } + +type DKGLoser struct { + Height int64 + Reason DKGDataMessage + Validator *tmtypes.Validator +} diff --git a/lib/types/interface.go b/lib/types/interface.go index 25fe3dd..c732f61 100644 --- a/lib/types/interface.go +++ b/lib/types/interface.go @@ -1,7 +1,6 @@ package types import ( - tmtypes "github.com/tendermint/tendermint/alias" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/types" ) @@ -12,5 +11,5 @@ type DKG interface { SetVerifier(verifier Verifier) Verifier() Verifier MsgQueue() chan *DKGDataMessage - GetLosers() []*tmtypes.Validator + GetLosers() []*DKGLoser } From b31f469c6c564909d45604562471d1cda04a3743 Mon Sep 17 00:00:00 2001 From: oopcode Date: Sun, 15 Dec 2019 22:22:55 +0300 Subject: [PATCH 2/7] wip --- lib/basic/basic.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/basic/basic.go b/lib/basic/basic.go index df7958c..92f9942 100644 --- a/lib/basic/basic.go +++ b/lib/basic/basic.go @@ -14,7 +14,6 @@ import ( "github.com/dgamingfoundation/dkglib/lib/onChain" dkg "github.com/dgamingfoundation/dkglib/lib/types" "github.com/tendermint/go-amino" - tmtypes "github.com/tendermint/tendermint/alias" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/events" "github.com/tendermint/tendermint/libs/log" @@ -151,6 +150,7 @@ func (m *DKGBasic) MsgQueue() chan *dkg.DKGDataMessage { return m.offChain.MsgQueue() } -func (m *DKGBasic) GetLosers() []*tmtypes.Validator { - return append(m.offChain.GetLosers(), m.onChain.GetLosers()...) +func (m *DKGBasic) GetLosers() []*dkg.DKGLoser { + // We only report verifiable on-chain losers. + return m.onChain.GetLosers() } From 3709662b8c80d55219a23761e25a97c48fe1d1c1 Mon Sep 17 00:00:00 2001 From: Andrej Zavgorodnij Date: Wed, 18 Dec 2019 13:07:32 +0300 Subject: [PATCH 3/7] added basic checks and refactored loser type --- lib/alias/dkg.go | 1 + lib/dealer/dkg_dealer.go | 145 +++++++++++++++++++++++++++++---------- lib/types/dkg.go | 13 +++- 3 files changed, 121 insertions(+), 38 deletions(-) diff --git a/lib/alias/dkg.go b/lib/alias/dkg.go index 52a3661..287991c 100644 --- a/lib/alias/dkg.go +++ b/lib/alias/dkg.go @@ -58,5 +58,6 @@ func (m *DKGData) GetAddrString() string { } func (m *DKGData) ValidateBasic() error { + // TODO: at least check the signature. return nil } diff --git a/lib/dealer/dkg_dealer.go b/lib/dealer/dkg_dealer.go index e2811d2..081e0c0 100644 --- a/lib/dealer/dkg_dealer.go +++ b/lib/dealer/dkg_dealer.go @@ -55,6 +55,9 @@ type Dealer interface { GetVerifier() (types.Verifier, error) SendMsgCb(*alias.DKGData) error VerifyMessage(msg types.DKGDataMessage) error + CheckLoserDuplicateData(loser *types.DKGLoser) bool + CheckLoserCorruptData(loser *types.DKGLoser) bool + CheckLoserCorruptJustification(loser *types.DKGLoser) bool } type DKGDealer struct { @@ -80,6 +83,8 @@ type DKGDealer struct { reconstructCommits *messageStore losers []*types.DKGLoser + + messagesHistory []*alias.DKGData } type DealerState struct { @@ -201,22 +206,27 @@ func (d *DKGDealer) GetLosers() []*types.DKGLoser { ////////////////////////////////////////////////////////////////////////////// func (d *DKGDealer) HandleDKGPubKey(msg *alias.DKGData) error { + d.messagesHistory = append(d.messagesHistory, msg) var ( - dec = gob.NewDecoder(bytes.NewBuffer(msg.Data)) - pubKey = d.suiteG2.Point() + dec = gob.NewDecoder(bytes.NewBuffer(msg.Data)) + pubKey = d.suiteG2.Point() + _, validator = d.validators.GetByAddress(msg.Addr) ) if err := dec.Decode(pubKey); err != nil { - _, validator := d.validators.GetByAddress(msg.Addr) d.losers = append(d.losers, &types.DKGLoser{ - Height: 0, - Reason: types.DKGDataMessage{Data: msg}, + Type: types.LoserTypeCorruptData, + Data: types.DKGDataMessage{Data: msg}, Validator: validator, }) return fmt.Errorf("dkgState: failed to decode public key from %s: %v", msg.Addr, err) } - // TODO: check if we want to slash validators who send duplicate keys - // TODO (we probably do). - d.pubKeys.Add(&PK2Addr{PK: pubKey, Addr: crypto.Address(msg.Addr)}) + if !d.pubKeys.Add(&PK2Addr{PK: pubKey, Addr: msg.Addr}) { + d.losers = append(d.losers, &types.DKGLoser{ + Type: types.LoserTypeDuplicateData, + Data: types.DKGDataMessage{Data: msg}, + Validator: validator, + }) + } if err := d.Transit(); err != nil { return fmt.Errorf("failed to Transit: %v", err) @@ -231,18 +241,18 @@ func (d *DKGDealer) SendDeals() (error, bool) { } d.eventFirer.FireEvent(types.EventDKGPubKeyReceived, nil) - messages, err := d.GetDeals() + dealMessages, err := d.GetDeals() if err != nil { return fmt.Errorf("failed to get deals: %v", err), true } - for _, msg := range messages { + for _, msg := range dealMessages { if err = d.SendMsgCb(msg); err != nil { return fmt.Errorf("failed to sign message: %v", err), true } } - d.logger.Info("dkgState: sending deals", "deals", len(messages)) + d.logger.Info("dkgState: sending deals", "deals", len(dealMessages)) return err, true } @@ -296,6 +306,7 @@ func (d *DKGDealer) GetDeals() ([]*alias.DKGData, error) { } func (d *DKGDealer) HandleDKGDeal(msg *alias.DKGData) error { + d.messagesHistory = append(d.messagesHistory, msg) var ( dec = gob.NewDecoder(bytes.NewBuffer(msg.Data)) deal = &dkg.Deal{ // We need to initialize everything down to the kyber.Point to avoid nil panics. @@ -307,8 +318,8 @@ func (d *DKGDealer) HandleDKGDeal(msg *alias.DKGData) error { if err := dec.Decode(deal); err != nil { _, validator := d.validators.GetByAddress(msg.Addr) d.losers = append(d.losers, &types.DKGLoser{ - Height: 0, - Reason: types.DKGDataMessage{Data: msg}, + Type: types.LoserTypeCorruptData, + Data: types.DKGDataMessage{Data: msg}, Validator: validator, }) return fmt.Errorf("failed to decode deal: %v", err) @@ -322,6 +333,7 @@ func (d *DKGDealer) HandleDKGDeal(msg *alias.DKGData) error { d.logger.Info("dkgState: deal is intended for us, storing") if _, exists := d.deals[msg.GetAddrString()]; exists { + // TODO: do we want to blame for duplicate data here? return nil } @@ -387,6 +399,7 @@ func (d *DKGDealer) GetResponses() ([]*alias.DKGData, error) { } func (d *DKGDealer) HandleDKGResponse(msg *alias.DKGData) error { + d.messagesHistory = append(d.messagesHistory, msg) var ( dec = gob.NewDecoder(bytes.NewBuffer(msg.Data)) resp = &dkg.Response{} @@ -394,8 +407,8 @@ func (d *DKGDealer) HandleDKGResponse(msg *alias.DKGData) error { if err := dec.Decode(resp); err != nil { _, validator := d.validators.GetByAddress(msg.Addr) d.losers = append(d.losers, &types.DKGLoser{ - Height: 0, - Reason: types.DKGDataMessage{Data: msg}, + Type: types.LoserTypeCorruptData, + Data: types.DKGDataMessage{Data: msg}, Validator: validator, }) return fmt.Errorf("failed to decode deal: %v", err) @@ -500,6 +513,8 @@ func (d *DKGDealer) GetJustifications() ([]*alias.DKGData, error) { } func (d *DKGDealer) HandleDKGJustification(msg *alias.DKGData) error { + d.messagesHistory = append(d.messagesHistory, msg) + var justification *dkg.Justification if msg.Data != nil { dec := gob.NewDecoder(bytes.NewBuffer(msg.Data)) @@ -507,8 +522,8 @@ func (d *DKGDealer) HandleDKGJustification(msg *alias.DKGData) error { if err := dec.Decode(justification); err != nil { _, validator := d.validators.GetByAddress(msg.Addr) d.losers = append(d.losers, &types.DKGLoser{ - Height: 0, - Reason: types.DKGDataMessage{Data: msg}, + Type: types.LoserTypeCorruptData, + Data: types.DKGDataMessage{Data: msg}, Validator: validator, }) return fmt.Errorf("failed to decode deal: %v", err) @@ -565,12 +580,20 @@ func (d *DKGDealer) IsJustificationsReady() bool { } func (d DKGDealer) GetCommits() (*dkg.SecretCommits, error) { - for _, peerJustifications := range d.justifications.data { + for addr, peerJustifications := range d.justifications.data { for _, just := range peerJustifications { justification := just.(*dkg.Justification) if justification != nil { d.logger.Info("dkgState: processing non-empty justification", "from", justification.Index) + _, validator := d.validators.GetByAddress([]byte(addr)) if err := d.instance.ProcessJustification(justification); err != nil { + d.losers = append(d.losers, &types.DKGLoser{ + Type: types.LoserTypeCorruptJustification, + // TODO: we need to provide the signature from original message + // for the evidence to be provable, and this info is lost when + // we add the justification to the messageStore. + Validator: validator, + }) return nil, fmt.Errorf("failed to ProcessJustification: %v", err) } } else { @@ -615,18 +638,14 @@ func (d DKGDealer) GetCommits() (*dkg.SecretCommits, error) { ////////////////////////////////////////////////////////////////////////////// func (d *DKGDealer) HandleDKGCommit(msg *alias.DKGData) error { + d.messagesHistory = append(d.messagesHistory, msg) + dec := gob.NewDecoder(bytes.NewBuffer(msg.Data)) commits := &dkg.SecretCommits{} for i := 0; i < msg.NumEntities; i++ { commits.Commitments = append(commits.Commitments, d.suiteG2.Point()) } if err := dec.Decode(commits); err != nil { - _, validator := d.validators.GetByAddress(msg.Addr) - d.losers = append(d.losers, &types.DKGLoser{ - Height: 0, - Reason: types.DKGDataMessage{Data: msg}, - Validator: validator, - }) return fmt.Errorf("failed to decode commit: %v", err) } d.commits.add(msg.GetAddrString(), commits) @@ -689,6 +708,8 @@ func (d *DKGDealer) ProcessCommits() (error, bool) { } func (d *DKGDealer) HandleDKGComplaint(msg *alias.DKGData) error { + d.messagesHistory = append(d.messagesHistory, msg) + var complaint *dkg.ComplaintCommits if msg.Data != nil { dec := gob.NewDecoder(bytes.NewBuffer(msg.Data)) @@ -699,12 +720,6 @@ func (d *DKGDealer) HandleDKGComplaint(msg *alias.DKGData) error { complaint.Deal.Commitments = append(complaint.Deal.Commitments, d.suiteG2.Point()) } if err := dec.Decode(complaint); err != nil { - _, validator := d.validators.GetByAddress(msg.Addr) - d.losers = append(d.losers, &types.DKGLoser{ - Height: 0, - Reason: types.DKGDataMessage{Data: msg}, - Validator: validator, - }) return fmt.Errorf("failed to decode complaint: %v", err) } } @@ -760,17 +775,13 @@ func (d *DKGDealer) ProcessComplaints() (error, bool) { } func (d *DKGDealer) HandleDKGReconstructCommit(msg *alias.DKGData) error { + d.messagesHistory = append(d.messagesHistory, msg) + var rc *dkg.ReconstructCommits if msg.Data != nil { dec := gob.NewDecoder(bytes.NewBuffer(msg.Data)) rc = &dkg.ReconstructCommits{} if err := dec.Decode(rc); err != nil { - _, validator := d.validators.GetByAddress(msg.Addr) - d.losers = append(d.losers, &types.DKGLoser{ - Height: 0, - Reason: types.DKGDataMessage{Data: msg}, - Validator: validator, - }) return fmt.Errorf("failed to decode complaint: %v", err) } } @@ -849,6 +860,68 @@ func (d *DKGDealer) VerifyMessage(msg types.DKGDataMessage) error { return nil } +func (d *DKGDealer) CheckLoserDuplicateData(loser *types.DKGLoser) bool { + var ( + count int + msg = loser.Data.Data + ) + for _, historyMsg := range d.messagesHistory { + if bytes.Equal(historyMsg.Addr, msg.Addr) && historyMsg.Type == msg.Type { + // TODO: check if participants can have zero indices, and if so, + // make ToIndex nullable. + if historyMsg.ToIndex > 0 && historyMsg.ToIndex == msg.ToIndex { + count++ + } + } + } + + return count > 1 +} + +func (d *DKGDealer) CheckLoserCorruptData(loser *types.DKGLoser) bool { + var msg = loser.Data.Data + + if err := msg.ValidateBasic(); err != nil { + // We can not be sure that the message was actually sent by this user. + return false + } + + // TODO: implement other types checks. + var dec = gob.NewDecoder(bytes.NewBuffer(msg.Data)) + switch loser.Data.Data.Type { + case alias.DKGPubKey: + val := d.suiteG2.Point() + if err := dec.Decode(val); err != nil { + return true + } + case alias.DKGDeal: + val := &dkg.Deal{ // We need to initialize everything down to the kyber.Point to avoid nil panics. + Deal: &vss.EncryptedDeal{ + DHKey: d.suiteG2.Point(), + }, + } + if err := dec.Decode(val); err != nil { + return true + } + case alias.DKGResponse: + val := &dkg.Response{} + if err := dec.Decode(val); err != nil { + return true + } + case alias.DKGJustification: + val := &dkg.Justification{} + if err := dec.Decode(val); err != nil { + return true + } + } + return false +} + +func (d *DKGDealer) CheckLoserCorruptJustification(loser *types.DKGLoser) bool { + // TODO: implement. + return false +} + func (d *DKGDealer) SendMsgCb(msg *alias.DKGData) error { return d.sendMsgCb(msg) } diff --git a/lib/types/dkg.go b/lib/types/dkg.go index 079bbdd..c7bd667 100644 --- a/lib/types/dkg.go +++ b/lib/types/dkg.go @@ -12,6 +12,15 @@ var ( ErrDKGVerifierNotReady = errors.New("verifier not ready yet") ) +type LoserType string + +const ( + LoserTypeCorruptData LoserType = "loser_type_corrupt_data" + LoserTypeDuplicateData LoserType = "loser_type_duplicate_data" + LoserTypeCorruptJustification LoserType = "loser_type_corrupt_justification" + LoserTypeMissingJustification LoserType = "loser_type_missing_justification" +) + type DKGDataMessage struct { Data *alias.DKGData } @@ -25,7 +34,7 @@ func (m *DKGDataMessage) String() string { } type DKGLoser struct { - Height int64 - Reason DKGDataMessage + Type LoserType + Data DKGDataMessage Validator *tmtypes.Validator } From 6b8661e54349541047c70ca926d396c3e63c8ab1 Mon Sep 17 00:00:00 2001 From: Andrej Zavgorodnij Date: Wed, 18 Dec 2019 15:00:48 +0300 Subject: [PATCH 4/7] finalizing --- lib/basic/basic.go | 16 ++++++++++++++++ lib/dealer/dkg_dealer.go | 17 +++++++++++++++++ lib/offChain/dkg.go | 16 ++++++++++++++++ lib/onChain/dkg.go | 4 ++++ lib/types/interface.go | 4 ++++ 5 files changed, 57 insertions(+) diff --git a/lib/basic/basic.go b/lib/basic/basic.go index 92f9942..14a0677 100644 --- a/lib/basic/basic.go +++ b/lib/basic/basic.go @@ -154,3 +154,19 @@ func (m *DKGBasic) GetLosers() []*dkg.DKGLoser { // We only report verifiable on-chain losers. return m.onChain.GetLosers() } + +func (m *DKGBasic) CheckLoserDuplicateData(loser *DKGLoser) bool { + return m.onChain.GetDealer().CheckLoserDuplicateData(loser) +} + +func (m *DKGBasic) CheckLoserMissingData(loser *DKGLoser) bool { + return m.onChain.GetDealer().CheckLoserMissingData(loser) +} + +func (m *DKGBasic) CheckLoserCorruptData(loser *DKGLoser) bool { + return m.onChain.GetDealer().CheckLoserCorruptData(loser) +} + +func (m *DKGBasic) CheckLoserCorruptJustification(loser *DKGLoser) bool { + return m.onChain.GetDealer().CheckLoserCorruptJustification(loser) +} diff --git a/lib/dealer/dkg_dealer.go b/lib/dealer/dkg_dealer.go index 081e0c0..ff9c6ff 100644 --- a/lib/dealer/dkg_dealer.go +++ b/lib/dealer/dkg_dealer.go @@ -871,6 +871,8 @@ func (d *DKGDealer) CheckLoserDuplicateData(loser *types.DKGLoser) bool { // make ToIndex nullable. if historyMsg.ToIndex > 0 && historyMsg.ToIndex == msg.ToIndex { count++ + } else { + count++ } } } @@ -878,6 +880,21 @@ func (d *DKGDealer) CheckLoserDuplicateData(loser *types.DKGLoser) bool { return count > 1 } +func (d *DKGDealer) CheckLoserMissingData(loser *types.DKGLoser) bool { + var msg = loser.Data.Data + for _, historyMsg := range d.messagesHistory { + if bytes.Equal(historyMsg.Addr, msg.Addr) && historyMsg.Type == msg.Type { + // TODO: check if participants can have zero indices, and if so, + // make ToIndex nullable. + if historyMsg.ToIndex > 0 && historyMsg.ToIndex == msg.ToIndex { + return true + } + } + } + + return false +} + func (d *DKGDealer) CheckLoserCorruptData(loser *types.DKGLoser) bool { var msg = loser.Data.Data diff --git a/lib/offChain/dkg.go b/lib/offChain/dkg.go index 0953aa6..f8673ec 100644 --- a/lib/offChain/dkg.go +++ b/lib/offChain/dkg.go @@ -271,6 +271,22 @@ func (m *OffChainDKG) GetLosers() []*types.DKGLoser { return dealer.GetLosers() } +func (m *OffChainDKG) CheckLoserDuplicateData(loser *types.DKGLoser) bool { + return false +} + +func (m *OffChainDKG) CheckLoserMissingData(loser *types.DKGLoser) bool { + return false +} + +func (m *OffChainDKG) CheckLoserCorruptData(loser *types.DKGLoser) bool { + return false +} + +func (m *OffChainDKG) CheckLoserCorruptJustification(loser *types.DKGLoser) bool { + return false +} + type verifierFunc func(s string, i int) dkgtypes.Verifier func GetVerifier(T, N int) verifierFunc { diff --git a/lib/onChain/dkg.go b/lib/onChain/dkg.go index 723edec..93da619 100644 --- a/lib/onChain/dkg.go +++ b/lib/onChain/dkg.go @@ -32,6 +32,10 @@ func NewOnChainDKG(cli *context.Context, txBldr *authtxb.TxBuilder) *OnChainDKG } } +func (m *OnChainDKG) GetDealer() dealer.Dealer { + return m.dealer +} + func (m *OnChainDKG) GetVerifier() (types.Verifier, error) { return m.dealer.GetVerifier() } diff --git a/lib/types/interface.go b/lib/types/interface.go index c732f61..ab87231 100644 --- a/lib/types/interface.go +++ b/lib/types/interface.go @@ -12,4 +12,8 @@ type DKG interface { Verifier() Verifier MsgQueue() chan *DKGDataMessage GetLosers() []*DKGLoser + CheckLoserDuplicateData(loser *DKGLoser) bool + CheckLoserMissingData(loser *DKGLoser) bool + CheckLoserCorruptData(loser *DKGLoser) bool + CheckLoserCorruptJustification(loser *DKGLoser) bool } From 41293b4d52e35d4f40010e9778cd2114f50a96c7 Mon Sep 17 00:00:00 2001 From: Andrej Zavgorodnij Date: Wed, 18 Dec 2019 16:03:29 +0300 Subject: [PATCH 5/7] fixes & better interfaces --- go.mod | 2 ++ lib/basic/basic.go | 17 +++++++++-------- lib/dealer/dkg_dealer.go | 1 + lib/types/dkg.go | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 09f9b75..d52d31d 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,11 @@ module github.com/dgamingfoundation/dkglib go 1.12 require ( + github.com/VividCortex/gohistogram v1.0.0 // indirect github.com/cosmos/cosmos-sdk v0.28.2-0.20190827131926-5aacf454e1b6 github.com/dgamingfoundation/cosmos-utils/client v0.0.0-20191105143510-3ddb0501dfbd github.com/dgamingfoundation/tendermint v0.27.3 + github.com/stumble/gorocksdb v0.0.3 // indirect github.com/tendermint/go-amino v0.15.1 github.com/tendermint/tendermint v0.32.6 go.dedis.ch/kyber/v3 v3.0.4 diff --git a/lib/basic/basic.go b/lib/basic/basic.go index 14a0677..e551238 100644 --- a/lib/basic/basic.go +++ b/lib/basic/basic.go @@ -12,12 +12,13 @@ import ( "github.com/dgamingfoundation/cosmos-utils/client/utils" "github.com/dgamingfoundation/dkglib/lib/offChain" "github.com/dgamingfoundation/dkglib/lib/onChain" + "github.com/dgamingfoundation/dkglib/lib/types" dkg "github.com/dgamingfoundation/dkglib/lib/types" "github.com/tendermint/go-amino" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/libs/events" "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tendermint/types" + sdk "github.com/tendermint/tendermint/types" ) type DKGBasic struct { @@ -72,7 +73,7 @@ func (m *MockFirer) FireEvent(event string, data events.EventData) {} func (m *DKGBasic) HandleOffChainShare( dkgMsg *dkg.DKGDataMessage, height int64, - validators *types.ValidatorSet, + validators *sdk.ValidatorSet, pubKey crypto.PubKey, ) bool { @@ -108,7 +109,7 @@ func (m *DKGBasic) HandleOffChainShare( return false } -func (m *DKGBasic) runOnChainDKG(validators *types.ValidatorSet, logger log.Logger) bool { +func (m *DKGBasic) runOnChainDKG(validators *sdk.ValidatorSet, logger log.Logger) bool { err := m.onChain.StartRound( validators, m.offChain.GetPrivValidator(), @@ -134,7 +135,7 @@ func (m *DKGBasic) runOnChainDKG(validators *types.ValidatorSet, logger log.Logg } } -func (m *DKGBasic) CheckDKGTime(height int64, validators *types.ValidatorSet) { +func (m *DKGBasic) CheckDKGTime(height int64, validators *sdk.ValidatorSet) { m.offChain.CheckDKGTime(height, validators) } @@ -155,18 +156,18 @@ func (m *DKGBasic) GetLosers() []*dkg.DKGLoser { return m.onChain.GetLosers() } -func (m *DKGBasic) CheckLoserDuplicateData(loser *DKGLoser) bool { +func (m *DKGBasic) CheckLoserDuplicateData(loser *types.DKGLoser) bool { return m.onChain.GetDealer().CheckLoserDuplicateData(loser) } -func (m *DKGBasic) CheckLoserMissingData(loser *DKGLoser) bool { +func (m *DKGBasic) CheckLoserMissingData(loser *types.DKGLoser) bool { return m.onChain.GetDealer().CheckLoserMissingData(loser) } -func (m *DKGBasic) CheckLoserCorruptData(loser *DKGLoser) bool { +func (m *DKGBasic) CheckLoserCorruptData(loser *types.DKGLoser) bool { return m.onChain.GetDealer().CheckLoserCorruptData(loser) } -func (m *DKGBasic) CheckLoserCorruptJustification(loser *DKGLoser) bool { +func (m *DKGBasic) CheckLoserCorruptJustification(loser *types.DKGLoser) bool { return m.onChain.GetDealer().CheckLoserCorruptJustification(loser) } diff --git a/lib/dealer/dkg_dealer.go b/lib/dealer/dkg_dealer.go index ff9c6ff..b840390 100644 --- a/lib/dealer/dkg_dealer.go +++ b/lib/dealer/dkg_dealer.go @@ -56,6 +56,7 @@ type Dealer interface { SendMsgCb(*alias.DKGData) error VerifyMessage(msg types.DKGDataMessage) error CheckLoserDuplicateData(loser *types.DKGLoser) bool + CheckLoserMissingData(loser *types.DKGLoser) bool CheckLoserCorruptData(loser *types.DKGLoser) bool CheckLoserCorruptJustification(loser *types.DKGLoser) bool } diff --git a/lib/types/dkg.go b/lib/types/dkg.go index c7bd667..835e2d0 100644 --- a/lib/types/dkg.go +++ b/lib/types/dkg.go @@ -16,9 +16,9 @@ type LoserType string const ( LoserTypeCorruptData LoserType = "loser_type_corrupt_data" + LoserTypeMissingData LoserType = "loser_type_missing_data" LoserTypeDuplicateData LoserType = "loser_type_duplicate_data" LoserTypeCorruptJustification LoserType = "loser_type_corrupt_justification" - LoserTypeMissingJustification LoserType = "loser_type_missing_justification" ) type DKGDataMessage struct { From aadc847babb5f13c5eadee9b2d45c5444d66b263 Mon Sep 17 00:00:00 2001 From: Andrej Zavgorodnij Date: Wed, 18 Dec 2019 16:11:05 +0300 Subject: [PATCH 6/7] fixed go.mod --- go.mod | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index d52d31d..678a6f4 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/VividCortex/gohistogram v1.0.0 // indirect github.com/cosmos/cosmos-sdk v0.28.2-0.20190827131926-5aacf454e1b6 github.com/dgamingfoundation/cosmos-utils/client v0.0.0-20191105143510-3ddb0501dfbd - github.com/dgamingfoundation/tendermint v0.27.3 + github.com/dgamingfoundation/tendermint v0.27.4-0.20191209175603-06d02b9bd67a github.com/stumble/gorocksdb v0.0.3 // indirect github.com/tendermint/go-amino v0.15.1 github.com/tendermint/tendermint v0.32.6 @@ -16,3 +16,5 @@ require ( replace golang.org/x/crypto => github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5 replace github.com/tendermint/tendermint => ../tendermint + +replace github.com/dgamingfoundation/tendermint => ../tendermint From 468646ea94cd4b01e481fe0c9060e0b4ae9b40cb Mon Sep 17 00:00:00 2001 From: Andrej Zavgorodnij Date: Wed, 25 Dec 2019 13:30:04 +0300 Subject: [PATCH 7/7] added isready --- lib/basic/basic.go | 8 ++++++++ lib/offChain/dkg.go | 8 ++++++++ lib/types/interface.go | 1 + 3 files changed, 17 insertions(+) diff --git a/lib/basic/basic.go b/lib/basic/basic.go index e551238..58a6718 100644 --- a/lib/basic/basic.go +++ b/lib/basic/basic.go @@ -66,6 +66,14 @@ func NewDKGBasic( }, nil } +func (m *DKGBasic) IsReady() bool { + if m == nil { + return false + } + + return true +} + type MockFirer struct{} func (m *MockFirer) FireEvent(event string, data events.EventData) {} diff --git a/lib/offChain/dkg.go b/lib/offChain/dkg.go index f8673ec..16ccb95 100644 --- a/lib/offChain/dkg.go +++ b/lib/offChain/dkg.go @@ -287,6 +287,14 @@ func (m *OffChainDKG) CheckLoserCorruptJustification(loser *types.DKGLoser) bool return false } +func (m *OffChainDKG) IsReady() bool { + if m == nil { + return false + } + + return true +} + type verifierFunc func(s string, i int) dkgtypes.Verifier func GetVerifier(T, N int) verifierFunc { diff --git a/lib/types/interface.go b/lib/types/interface.go index ab87231..47a4954 100644 --- a/lib/types/interface.go +++ b/lib/types/interface.go @@ -6,6 +6,7 @@ import ( ) type DKG interface { + IsReady() bool HandleOffChainShare(dkgMsg *DKGDataMessage, height int64, validators *types.ValidatorSet, pubKey crypto.PubKey) (switchToOnChain bool) CheckDKGTime(height int64, validators *types.ValidatorSet) SetVerifier(verifier Verifier)