mirror of https://github.com/certusone/dc4bc.git
wip
This commit is contained in:
parent
9fbc54cf34
commit
0037421ff0
|
@ -8,7 +8,6 @@ import (
|
||||||
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
||||||
"github.com/depools/dc4bc/fsm/types/requests"
|
"github.com/depools/dc4bc/fsm/types/requests"
|
||||||
"reflect"
|
"reflect"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
|
@ -100,39 +99,31 @@ func (m *DKGProposalFSM) actionCommitConfirmationReceived(inEvent fsm.Event, arg
|
||||||
|
|
||||||
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitCommits(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitCommits(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||||
var (
|
var (
|
||||||
isContainsError, isContainsExpired bool
|
isContainsError bool
|
||||||
)
|
)
|
||||||
|
|
||||||
m.payloadMu.Lock()
|
m.payloadMu.Lock()
|
||||||
defer m.payloadMu.Unlock()
|
defer m.payloadMu.Unlock()
|
||||||
|
|
||||||
tm := time.Now()
|
if m.payload.DKGProposalPayload.IsExpired() {
|
||||||
|
outEvent = eventDKGCommitsConfirmationCancelByErrorInternal
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
||||||
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
||||||
if participant.Status == internal.CommitAwaitConfirmation {
|
|
||||||
if participant.UpdatedAt.Add(config.DkgConfirmationDeadline).Before(tm) {
|
|
||||||
isContainsExpired = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if participant.Status == internal.CommitConfirmationError {
|
if participant.Status == internal.CommitConfirmationError {
|
||||||
isContainsError = true
|
isContainsError = true
|
||||||
} else if participant.Status == internal.CommitConfirmed {
|
} else if participant.Status == internal.CommitConfirmed {
|
||||||
unconfirmedParticipants--
|
unconfirmedParticipants--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if isContainsError {
|
if isContainsError {
|
||||||
outEvent = eventDKGCommitsConfirmationCancelByTimeoutInternal
|
outEvent = eventDKGCommitsConfirmationCancelByTimeoutInternal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isContainsExpired {
|
|
||||||
outEvent = eventDKGCommitsConfirmationCancelByErrorInternal
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The are no declined and timed out participants, check for all confirmations
|
// The are no declined and timed out participants, check for all confirmations
|
||||||
if unconfirmedParticipants > 0 {
|
if unconfirmedParticipants > 0 {
|
||||||
return
|
return
|
||||||
|
@ -194,39 +185,31 @@ func (m *DKGProposalFSM) actionDealConfirmationReceived(inEvent fsm.Event, args
|
||||||
|
|
||||||
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitDeals(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitDeals(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||||
var (
|
var (
|
||||||
isContainsError, isContainsExpired bool
|
isContainsError bool
|
||||||
)
|
)
|
||||||
|
|
||||||
m.payloadMu.Lock()
|
m.payloadMu.Lock()
|
||||||
defer m.payloadMu.Unlock()
|
defer m.payloadMu.Unlock()
|
||||||
|
|
||||||
tm := time.Now()
|
if m.payload.DKGProposalPayload.IsExpired() {
|
||||||
|
outEvent = eventDKGDealsConfirmationCancelByTimeoutInternal
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
||||||
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
||||||
if participant.Status == internal.DealAwaitConfirmation {
|
|
||||||
if participant.UpdatedAt.Add(config.DkgConfirmationDeadline).Before(tm) {
|
|
||||||
isContainsExpired = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if participant.Status == internal.DealConfirmationError {
|
if participant.Status == internal.DealConfirmationError {
|
||||||
isContainsError = true
|
isContainsError = true
|
||||||
} else if participant.Status == internal.DealConfirmed {
|
} else if participant.Status == internal.DealConfirmed {
|
||||||
unconfirmedParticipants--
|
unconfirmedParticipants--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if isContainsError {
|
if isContainsError {
|
||||||
outEvent = eventDKGDealsConfirmationCancelByErrorInternal
|
outEvent = eventDKGDealsConfirmationCancelByErrorInternal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isContainsExpired {
|
|
||||||
outEvent = eventDKGDealsConfirmationCancelByTimeoutInternal
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The are no declined and timed out participants, check for all confirmations
|
// The are no declined and timed out participants, check for all confirmations
|
||||||
if unconfirmedParticipants > 0 {
|
if unconfirmedParticipants > 0 {
|
||||||
return
|
return
|
||||||
|
@ -288,39 +271,31 @@ func (m *DKGProposalFSM) actionResponseConfirmationReceived(inEvent fsm.Event, a
|
||||||
|
|
||||||
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitResponses(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitResponses(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||||
var (
|
var (
|
||||||
isContainsError, isContainsExpired bool
|
isContainsError bool
|
||||||
)
|
)
|
||||||
|
|
||||||
m.payloadMu.Lock()
|
m.payloadMu.Lock()
|
||||||
defer m.payloadMu.Unlock()
|
defer m.payloadMu.Unlock()
|
||||||
|
|
||||||
tm := time.Now()
|
if m.payload.DKGProposalPayload.IsExpired() {
|
||||||
|
outEvent = eventDKGResponseConfirmationCancelByTimeoutInternal
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
||||||
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
||||||
if participant.Status == internal.ResponseAwaitConfirmation {
|
|
||||||
if participant.UpdatedAt.Add(config.DkgConfirmationDeadline).Before(tm) {
|
|
||||||
isContainsExpired = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if participant.Status == internal.ResponseConfirmationError {
|
if participant.Status == internal.ResponseConfirmationError {
|
||||||
isContainsError = true
|
isContainsError = true
|
||||||
} else if participant.Status == internal.ResponseConfirmed {
|
} else if participant.Status == internal.ResponseConfirmed {
|
||||||
unconfirmedParticipants--
|
unconfirmedParticipants--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if isContainsError {
|
if isContainsError {
|
||||||
outEvent = eventDKGResponseConfirmationCancelByErrorInternal
|
outEvent = eventDKGResponseConfirmationCancelByErrorInternal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isContainsExpired {
|
|
||||||
outEvent = eventDKGResponseConfirmationCancelByTimeoutInternal
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The are no declined and timed out participants, check for all confirmations
|
// The are no declined and timed out participants, check for all confirmations
|
||||||
if unconfirmedParticipants > 0 {
|
if unconfirmedParticipants > 0 {
|
||||||
return
|
return
|
||||||
|
@ -382,23 +357,21 @@ func (m *DKGProposalFSM) actionMasterKeyConfirmationReceived(inEvent fsm.Event,
|
||||||
|
|
||||||
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitMasterKey(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
func (m *DKGProposalFSM) actionValidateDkgProposalAwaitMasterKey(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||||
var (
|
var (
|
||||||
isContainsError, isContainsExpired bool
|
isContainsError bool
|
||||||
masterKeys [][]byte
|
masterKeys [][]byte
|
||||||
)
|
)
|
||||||
|
|
||||||
m.payloadMu.Lock()
|
m.payloadMu.Lock()
|
||||||
defer m.payloadMu.Unlock()
|
defer m.payloadMu.Unlock()
|
||||||
|
|
||||||
tm := time.Now()
|
if m.payload.DKGProposalPayload.IsExpired() {
|
||||||
|
outEvent = eventDKGMasterKeyConfirmationCancelByTimeoutInternal
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
||||||
|
|
||||||
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
||||||
if participant.Status == internal.MasterKeyAwaitConfirmation {
|
|
||||||
if participant.UpdatedAt.Add(config.DkgConfirmationDeadline).Before(tm) {
|
|
||||||
isContainsExpired = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if participant.Status == internal.MasterKeyConfirmationError {
|
if participant.Status == internal.MasterKeyConfirmationError {
|
||||||
isContainsError = true
|
isContainsError = true
|
||||||
} else if participant.Status == internal.MasterKeyConfirmed {
|
} else if participant.Status == internal.MasterKeyConfirmed {
|
||||||
|
@ -406,18 +379,12 @@ func (m *DKGProposalFSM) actionValidateDkgProposalAwaitMasterKey(inEvent fsm.Eve
|
||||||
unconfirmedParticipants--
|
unconfirmedParticipants--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if isContainsError {
|
if isContainsError {
|
||||||
outEvent = eventDKGMasterKeyConfirmationCancelByErrorInternal
|
outEvent = eventDKGMasterKeyConfirmationCancelByErrorInternal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isContainsExpired {
|
|
||||||
outEvent = eventDKGMasterKeyConfirmationCancelByTimeoutInternal
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Temporary simplest match master keys
|
// Temporary simplest match master keys
|
||||||
if len(masterKeys) > 1 {
|
if len(masterKeys) > 1 {
|
||||||
for i, masterKey := range masterKeys {
|
for i, masterKey := range masterKeys {
|
||||||
|
|
|
@ -19,7 +19,7 @@ type DumpedMachineStatePayload struct {
|
||||||
SignatureProposalPayload *SignatureConfirmation
|
SignatureProposalPayload *SignatureConfirmation
|
||||||
DKGProposalPayload *DKGConfirmation
|
DKGProposalPayload *DKGConfirmation
|
||||||
SigningProposalPayload *SigningConfirmation
|
SigningProposalPayload *SigningConfirmation
|
||||||
pubKeys map[string]ed25519.PublicKey
|
PubKeys map[string]ed25519.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signature quorum
|
// Signature quorum
|
||||||
|
@ -118,23 +118,23 @@ func (p *DumpedMachineStatePayload) SigningQuorumUpdate(id int, participant *Sig
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *DumpedMachineStatePayload) SetAddrHexPubKey(addr string, key ed25519.PublicKey) {
|
func (p *DumpedMachineStatePayload) SetAddrHexPubKey(addr string, pubKey ed25519.PublicKey) {
|
||||||
if p.pubKeys == nil {
|
if p.PubKeys == nil {
|
||||||
p.pubKeys = make(map[string]ed25519.PublicKey)
|
p.PubKeys = make(map[string]ed25519.PublicKey)
|
||||||
}
|
}
|
||||||
hexKey := hex.EncodeToString([]byte(addr))
|
hexAddr := hex.EncodeToString([]byte(addr))
|
||||||
p.pubKeys[hexKey] = key
|
p.PubKeys[hexAddr] = pubKey
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *DumpedMachineStatePayload) GetPubKeyByAddr(addr string) (ed25519.PublicKey, error) {
|
func (p *DumpedMachineStatePayload) GetPubKeyByAddr(addr string) (ed25519.PublicKey, error) {
|
||||||
if p.pubKeys == nil {
|
if p.PubKeys == nil {
|
||||||
return nil, errors.New("{pubKeys} not initialized")
|
return nil, errors.New("{PubKeys} not initialized")
|
||||||
}
|
}
|
||||||
if addr == "" {
|
if addr == "" {
|
||||||
return nil, errors.New("{addr} cannot be empty")
|
return nil, errors.New("{addr} cannot be empty")
|
||||||
}
|
}
|
||||||
pubKey, ok := p.pubKeys[addr]
|
pubKey, ok := p.PubKeys[addr]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("cannot find public key by {addr}")
|
return nil, errors.New("cannot find public key by {addr}")
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,10 @@ type SignatureProposalParticipant struct {
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *SignatureConfirmation) IsExpired() bool {
|
||||||
|
return c.ExpiresAt.Before(c.UpdatedAt)
|
||||||
|
}
|
||||||
|
|
||||||
// Unique alias for map iteration - Public Key Fingerprint
|
// Unique alias for map iteration - Public Key Fingerprint
|
||||||
// Excludes array merge and rotate operations
|
// Excludes array merge and rotate operations
|
||||||
type SignatureProposalQuorum map[int]*SignatureProposalParticipant
|
type SignatureProposalQuorum map[int]*SignatureProposalParticipant
|
||||||
|
@ -90,6 +94,10 @@ type DKGConfirmation struct {
|
||||||
ExpiresAt time.Time
|
ExpiresAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *DKGConfirmation) IsExpired() bool {
|
||||||
|
return c.ExpiresAt.Before(c.UpdatedAt)
|
||||||
|
}
|
||||||
|
|
||||||
type DKGProposalParticipantStatus uint8
|
type DKGProposalParticipantStatus uint8
|
||||||
|
|
||||||
func (s DKGParticipantStatus) String() string {
|
func (s DKGParticipantStatus) String() string {
|
||||||
|
@ -135,6 +143,10 @@ type SigningConfirmation struct {
|
||||||
ExpiresAt time.Time
|
ExpiresAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *SigningConfirmation) IsExpired() bool {
|
||||||
|
return c.ExpiresAt.Before(c.UpdatedAt)
|
||||||
|
}
|
||||||
|
|
||||||
type SigningProposalQuorum map[int]*SigningProposalParticipant
|
type SigningProposalQuorum map[int]*SigningProposalParticipant
|
||||||
|
|
||||||
type SigningParticipantStatus uint8
|
type SigningParticipantStatus uint8
|
||||||
|
|
|
@ -3,8 +3,6 @@ package signature_proposal_fsm
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/depools/dc4bc/fsm/config"
|
"github.com/depools/dc4bc/fsm/config"
|
||||||
"github.com/depools/dc4bc/fsm/fsm"
|
"github.com/depools/dc4bc/fsm/fsm"
|
||||||
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
||||||
|
@ -131,39 +129,32 @@ func (m *SignatureProposalFSM) actionProposalResponseByParticipant(inEvent fsm.E
|
||||||
|
|
||||||
func (m *SignatureProposalFSM) actionValidateSignatureProposal(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
func (m *SignatureProposalFSM) actionValidateSignatureProposal(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||||
var (
|
var (
|
||||||
isContainsDeclined, isContainsExpired bool
|
isContainsDeclined bool
|
||||||
)
|
)
|
||||||
|
|
||||||
m.payloadMu.Lock()
|
m.payloadMu.Lock()
|
||||||
defer m.payloadMu.Unlock()
|
defer m.payloadMu.Unlock()
|
||||||
|
|
||||||
tm := time.Now()
|
if m.payload.SignatureProposalPayload.IsExpired() {
|
||||||
|
outEvent = eventSetValidationCanceledByTimeout
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
unconfirmedParticipants := m.payload.SigQuorumCount()
|
unconfirmedParticipants := m.payload.SigQuorumCount()
|
||||||
|
|
||||||
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
|
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
|
||||||
if participant.Status == internal.SigConfirmationAwaitConfirmation {
|
|
||||||
if participant.UpdatedAt.Add(config.SignatureProposalConfirmationDeadline).Before(tm) {
|
|
||||||
isContainsExpired = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if participant.Status == internal.SigConfirmationConfirmed {
|
if participant.Status == internal.SigConfirmationConfirmed {
|
||||||
unconfirmedParticipants--
|
unconfirmedParticipants--
|
||||||
} else if participant.Status == internal.SigConfirmationDeclined {
|
} else if participant.Status == internal.SigConfirmationDeclined {
|
||||||
isContainsDeclined = true
|
isContainsDeclined = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if isContainsDeclined {
|
if isContainsDeclined {
|
||||||
outEvent = eventSetValidationCanceledByParticipant
|
outEvent = eventSetValidationCanceledByParticipant
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if isContainsExpired {
|
|
||||||
outEvent = eventSetValidationCanceledByTimeout
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The are no declined and timed out participants, check for all confirmations
|
// The are no declined and timed out participants, check for all confirmations
|
||||||
if unconfirmedParticipants > 0 {
|
if unconfirmedParticipants > 0 {
|
||||||
return
|
return
|
||||||
|
|
Loading…
Reference in New Issue