mirror of https://github.com/certusone/dc4bc.git
commit
9c9329b35d
132
fsm/fsm/fsm.go
132
fsm/fsm/fsm.go
|
@ -41,7 +41,7 @@ func (e *Event) String() string {
|
|||
return string(*e)
|
||||
}
|
||||
|
||||
func (e *Event) IsEmpty() bool {
|
||||
func (e Event) IsEmpty() bool {
|
||||
return e.String() == ""
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ type FSM struct {
|
|||
// May be mapping must require pair source + event?
|
||||
transitions map[trKey]*trEvent
|
||||
|
||||
autoTransitions map[State]*trEvent
|
||||
autoTransitions map[trAutoKeyEvent]*trEvent
|
||||
|
||||
callbacks Callbacks
|
||||
|
||||
|
@ -94,6 +94,11 @@ type trEvent struct {
|
|||
runMode EventRunMode
|
||||
}
|
||||
|
||||
type trAutoKeyEvent struct {
|
||||
state State
|
||||
runMode EventRunMode
|
||||
}
|
||||
|
||||
type EventDesc struct {
|
||||
Name Event
|
||||
|
||||
|
@ -138,7 +143,7 @@ func MustNewFSM(machineName string, initialState State, events []EventDesc, call
|
|||
currentState: initialState,
|
||||
initialState: initialState,
|
||||
transitions: make(map[trKey]*trEvent),
|
||||
autoTransitions: make(map[State]*trEvent),
|
||||
autoTransitions: make(map[trAutoKeyEvent]*trEvent),
|
||||
finStates: make(map[State]bool),
|
||||
callbacks: make(map[Event]Callback),
|
||||
}
|
||||
|
@ -217,14 +222,15 @@ func MustNewFSM(machineName string, initialState State, events []EventDesc, call
|
|||
panic("{AutoRunMode} not set for auto event")
|
||||
}
|
||||
|
||||
if _, ok := f.autoTransitions[sourceState]; ok {
|
||||
trAutoKey := trAutoKeyEvent{sourceState, event.AutoRunMode}
|
||||
if _, ok := f.autoTransitions[trAutoKey]; ok {
|
||||
panic(fmt.Sprintf(
|
||||
"auto event \"%s\" already exists for state \"%s\"",
|
||||
event.Name,
|
||||
sourceState,
|
||||
))
|
||||
}
|
||||
f.autoTransitions[sourceState] = trEvent
|
||||
f.autoTransitions[trAutoKey] = trEvent
|
||||
}
|
||||
|
||||
allSources[sourceState] = true
|
||||
|
@ -247,7 +253,7 @@ func MustNewFSM(machineName string, initialState State, events []EventDesc, call
|
|||
}
|
||||
|
||||
if _, ok := allEvents[event]; !ok {
|
||||
panic("callback has empty event")
|
||||
panic(fmt.Sprintf("callback has unused event \"%s\"", event))
|
||||
}
|
||||
|
||||
f.callbacks[event] = callback
|
||||
|
@ -273,7 +279,7 @@ func MustNewFSM(machineName string, initialState State, events []EventDesc, call
|
|||
func (f *FSM) DoInternal(event Event, args ...interface{}) (resp *Response, err error) {
|
||||
trEvent, ok := f.transitions[trKey{f.currentState, event}]
|
||||
if !ok {
|
||||
return nil, errors.New(fmt.Sprintf("cannot execute event \"%s\" for state \"%s\"", event, f.currentState))
|
||||
return nil, errors.New(fmt.Sprintf("cannot execute internal event \"%s\" for state \"%s\"", event, f.currentState))
|
||||
}
|
||||
|
||||
return f.do(trEvent, args...)
|
||||
|
@ -290,41 +296,55 @@ func (f *FSM) Do(event Event, args ...interface{}) (resp *Response, err error) {
|
|||
|
||||
return f.do(trEvent, args...)
|
||||
}
|
||||
|
||||
// Check and execute auto event
|
||||
func (f *FSM) processAutoEvent(mode EventRunMode, args ...interface{}) (exists bool, outEvent Event, response interface{}, err error) {
|
||||
autoEvent, exists := f.autoTransitions[trAutoKeyEvent{f.State(), mode}]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
if f.isCallbackExists(autoEvent.event) {
|
||||
outEvent, response, err = f.execCallback(autoEvent.event, args...)
|
||||
// Do not try change state on error
|
||||
if err != nil {
|
||||
return exists, "", response, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if outEvent.IsEmpty() || autoEvent.event == outEvent {
|
||||
err = f.SetState(autoEvent.event)
|
||||
} else {
|
||||
err = f.SetState(outEvent)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FSM) do(trEvent *trEvent, args ...interface{}) (resp *Response, err error) {
|
||||
var outEvent Event
|
||||
// f.eventMu.Lock()
|
||||
// defer f.eventMu.Unlock()
|
||||
|
||||
resp = &Response{}
|
||||
|
||||
// Process auto event
|
||||
if autoEvent, ok := f.autoTransitions[f.State()]; ok {
|
||||
autoEventResp := &Response{
|
||||
State: f.State(),
|
||||
isAutoEventExecuted, outEvent, data, err := f.processAutoEvent(EventRunBefore, args...)
|
||||
|
||||
if isAutoEventExecuted {
|
||||
resp.State = f.State()
|
||||
if data != nil {
|
||||
resp.Data = data
|
||||
}
|
||||
if autoEvent.runMode == EventRunBefore {
|
||||
if callback, ok := f.callbacks[autoEvent.event]; ok {
|
||||
outEvent, autoEventResp.Data, err = callback(autoEvent.event, args...)
|
||||
if err != nil {
|
||||
return autoEventResp, err
|
||||
}
|
||||
}
|
||||
if outEvent.IsEmpty() || autoEvent.event == outEvent {
|
||||
err = f.SetState(autoEvent.event)
|
||||
} else {
|
||||
err = f.SetState(outEvent)
|
||||
}
|
||||
if err != nil {
|
||||
return autoEventResp, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
outEvent = ""
|
||||
}
|
||||
|
||||
resp = &Response{
|
||||
State: f.State(),
|
||||
}
|
||||
|
||||
if callback, ok := f.callbacks[trEvent.event]; ok {
|
||||
outEvent, resp.Data, err = callback(trEvent.event, args...)
|
||||
if f.isCallbackExists(trEvent.event) {
|
||||
outEvent, resp.Data, err = f.execCallback(trEvent.event, args...)
|
||||
// Do not try change state on error
|
||||
if err != nil {
|
||||
return resp, err
|
||||
|
@ -334,32 +354,30 @@ func (f *FSM) do(trEvent *trEvent, args ...interface{}) (resp *Response, err err
|
|||
// Set state when callback executed
|
||||
if outEvent.IsEmpty() || trEvent.event == outEvent {
|
||||
err = f.SetState(trEvent.event)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
} else {
|
||||
err = f.SetState(outEvent)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
||||
resp.State = f.State()
|
||||
|
||||
// Process auto event
|
||||
if autoEvent, ok := f.autoTransitions[f.State()]; ok {
|
||||
autoEventResp := &Response{
|
||||
State: f.State(),
|
||||
isAutoEventExecuted, outEvent, data, err = f.processAutoEvent(EventRunAfter, args...)
|
||||
|
||||
if isAutoEventExecuted {
|
||||
resp.State = f.State()
|
||||
if data != nil {
|
||||
resp.Data = data
|
||||
}
|
||||
if autoEvent.runMode == EventRunAfter {
|
||||
if callback, ok := f.callbacks[autoEvent.event]; ok {
|
||||
outEvent, autoEventResp.Data, err = callback(autoEvent.event, args...)
|
||||
if err != nil {
|
||||
return autoEventResp, err
|
||||
}
|
||||
}
|
||||
if outEvent.IsEmpty() || autoEvent.event == outEvent {
|
||||
err = f.SetState(autoEvent.event)
|
||||
} else {
|
||||
err = f.SetState(outEvent)
|
||||
}
|
||||
if err != nil {
|
||||
return autoEventResp, err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
outEvent = ""
|
||||
}
|
||||
|
||||
resp.State = f.State()
|
||||
|
@ -382,7 +400,7 @@ func (f *FSM) SetState(event Event) error {
|
|||
|
||||
trEvent, ok := f.transitions[trKey{f.currentState, event}]
|
||||
if !ok {
|
||||
return errors.New(fmt.Sprintf("cannot execute event \"%s\" for state \"%s\"", event, f.currentState))
|
||||
return errors.New(fmt.Sprintf("cannot set state by event \"%s\" for state \"%s\"", event, f.currentState))
|
||||
}
|
||||
|
||||
f.currentState = trEvent.dstState
|
||||
|
@ -457,6 +475,16 @@ func (f *FSM) StatesSourcesList() (states []State) {
|
|||
return
|
||||
}
|
||||
|
||||
func (f *FSM) isCallbackExists(event Event) bool {
|
||||
_, exists := f.callbacks[event]
|
||||
return exists
|
||||
}
|
||||
|
||||
func (f *FSM) execCallback(event Event, args ...interface{}) (Event, interface{}, error) {
|
||||
callback, _ := f.callbacks[event]
|
||||
return callback(event, args...)
|
||||
}
|
||||
|
||||
func (f *FSM) IsFinState(state State) bool {
|
||||
_, exists := f.finStates[state]
|
||||
return exists
|
||||
|
|
|
@ -114,12 +114,14 @@ func Init(machines ...MachineProvider) *FSMPool {
|
|||
p.states[state] = initMachineName
|
||||
continue
|
||||
}
|
||||
}
|
||||
if name, exists := p.states[state]; exists && name != machineName {
|
||||
panic(fmt.Sprintf("duplicate state for machines \"%s\"", state))
|
||||
} else {
|
||||
if name, exists := p.states[state]; exists && name != machineName {
|
||||
panic(fmt.Sprintf("duplicate state for machines \"%s\"", state))
|
||||
}
|
||||
|
||||
p.states[state] = machineName
|
||||
}
|
||||
|
||||
p.states[state] = machineName
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,17 +162,3 @@ func (p *FSMPool) MachineByState(state fsm.State) (MachineProvider, error) {
|
|||
}
|
||||
return machine, nil
|
||||
}
|
||||
|
||||
/*func (p *FSMPool) Do(machine MachineProvider, event fsm.Event, args ...interface{}) (resp *fsm.Response, err error) {
|
||||
panic("llslsl")
|
||||
resp, err = machine.Do(event, args...)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if machine.IsFinState(resp.State) {
|
||||
log.Println("Final!!!!")
|
||||
}
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -11,94 +11,27 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Pub keys
|
||||
// Init
|
||||
|
||||
func (m *DKGProposalFSM) actionPubKeyConfirmationReceived(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
m.payloadMu.Lock()
|
||||
defer m.payloadMu.Unlock()
|
||||
|
||||
if len(args) != 1 {
|
||||
err = errors.New("{arg0} required {DKGProposalPubKeyConfirmationRequest}")
|
||||
func (m *DKGProposalFSM) actionInitDKGProposal(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
if m.payload.DKGProposalPayload != nil {
|
||||
return
|
||||
}
|
||||
|
||||
request, ok := args[0].(requests.DKGProposalPubKeyConfirmationRequest)
|
||||
|
||||
if !ok {
|
||||
err = errors.New("cannot cast {arg0} to type {DKGProposalPubKeyConfirmationRequest}")
|
||||
return
|
||||
m.payload.DKGProposalPayload = &internal.DKGConfirmation{
|
||||
Quorum: make(internal.DKGProposalQuorum),
|
||||
}
|
||||
|
||||
if err = request.Validate(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !m.payload.DKGQuorumExists(request.ParticipantId) {
|
||||
err = errors.New("{ParticipantId} not exist in quorum")
|
||||
return
|
||||
}
|
||||
|
||||
dkgProposalParticipant := m.payload.DKGQuorumGet(request.ParticipantId)
|
||||
|
||||
if dkgProposalParticipant.Status != internal.PubKeyAwaitConfirmation {
|
||||
err = errors.New(fmt.Sprintf("cannot confirm pubkey with {Status} = {\"%s\"}", dkgProposalParticipant.Status))
|
||||
return
|
||||
}
|
||||
|
||||
copy(dkgProposalParticipant.PubKey, request.PubKey)
|
||||
dkgProposalParticipant.UpdatedAt = &request.CreatedAt
|
||||
dkgProposalParticipant.Status = internal.PubKeyConfirmed
|
||||
|
||||
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (m *DKGProposalFSM) actionValidateDkgProposalPubKeys(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
var (
|
||||
isContainsError, isContainsExpired bool
|
||||
)
|
||||
|
||||
m.payloadMu.Lock()
|
||||
defer m.payloadMu.Unlock()
|
||||
|
||||
tm := time.Now()
|
||||
|
||||
unconfirmedParticipants := m.payload.DKGQuorumCount()
|
||||
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
||||
if participant.Status == internal.PubKeyAwaitConfirmation {
|
||||
if participant.UpdatedAt.Add(config.DkgConfirmationDeadline).Before(tm) {
|
||||
isContainsExpired = true
|
||||
}
|
||||
} else {
|
||||
if participant.Status == internal.PubKeyConfirmationError {
|
||||
isContainsError = true
|
||||
} else if participant.Status == internal.PubKeyConfirmed {
|
||||
unconfirmedParticipants--
|
||||
}
|
||||
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
|
||||
m.payload.DKGProposalPayload.Quorum[participant.ParticipantId] = &internal.DKGProposalParticipant{
|
||||
Title: participant.Title,
|
||||
Status: internal.CommitAwaitConfirmation,
|
||||
UpdatedAt: participant.UpdatedAt,
|
||||
}
|
||||
copy(m.payload.DKGProposalPayload.Quorum[participant.ParticipantId].PubKey, participant.DkgPubKey)
|
||||
}
|
||||
|
||||
if isContainsError {
|
||||
outEvent = eventDKGSetPubKeysConfirmationCanceledByErrorInternal
|
||||
return
|
||||
}
|
||||
|
||||
if isContainsExpired {
|
||||
outEvent = eventDKGSetPubKeysConfirmationCanceledByTimeoutInternal
|
||||
return
|
||||
}
|
||||
|
||||
// The are no declined and timed out participants, check for all confirmations
|
||||
if unconfirmedParticipants > 0 {
|
||||
return
|
||||
}
|
||||
|
||||
outEvent = eventDKGSetPubKeysConfirmedInternal
|
||||
|
||||
for _, participant := range m.payload.DKGProposalPayload.Quorum {
|
||||
participant.Status = internal.CommitAwaitConfirmation
|
||||
}
|
||||
// Remove m.payload.SignatureProposalPayload?
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -138,7 +71,7 @@ func (m *DKGProposalFSM) actionCommitConfirmationReceived(inEvent fsm.Event, arg
|
|||
}
|
||||
|
||||
copy(dkgProposalParticipant.Commit, request.Commit)
|
||||
dkgProposalParticipant.UpdatedAt = &request.CreatedAt
|
||||
dkgProposalParticipant.UpdatedAt = request.CreatedAt
|
||||
dkgProposalParticipant.Status = internal.CommitConfirmed
|
||||
|
||||
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
|
||||
|
@ -230,7 +163,7 @@ func (m *DKGProposalFSM) actionDealConfirmationReceived(inEvent fsm.Event, args
|
|||
}
|
||||
|
||||
copy(dkgProposalParticipant.Deal, request.Deal)
|
||||
dkgProposalParticipant.UpdatedAt = &request.CreatedAt
|
||||
dkgProposalParticipant.UpdatedAt = request.CreatedAt
|
||||
dkgProposalParticipant.Status = internal.DealConfirmed
|
||||
|
||||
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
|
||||
|
@ -322,7 +255,7 @@ func (m *DKGProposalFSM) actionResponseConfirmationReceived(inEvent fsm.Event, a
|
|||
}
|
||||
|
||||
copy(dkgProposalParticipant.Response, request.Response)
|
||||
dkgProposalParticipant.UpdatedAt = &request.CreatedAt
|
||||
dkgProposalParticipant.UpdatedAt = request.CreatedAt
|
||||
dkgProposalParticipant.Status = internal.ResponseConfirmed
|
||||
|
||||
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
|
||||
|
@ -414,7 +347,7 @@ func (m *DKGProposalFSM) actionMasterKeyConfirmationReceived(inEvent fsm.Event,
|
|||
}
|
||||
|
||||
copy(dkgProposalParticipant.MasterKey, request.MasterKey)
|
||||
dkgProposalParticipant.UpdatedAt = &request.CreatedAt
|
||||
dkgProposalParticipant.UpdatedAt = request.CreatedAt
|
||||
dkgProposalParticipant.Status = internal.MasterKeyConfirmed
|
||||
|
||||
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
|
||||
|
@ -525,21 +458,6 @@ func (m *DKGProposalFSM) actionConfirmationError(inEvent fsm.Event, args ...inte
|
|||
|
||||
// TODO: Move to methods
|
||||
switch inEvent {
|
||||
case EventDKGPubKeyConfirmationError:
|
||||
switch dkgProposalParticipant.Status {
|
||||
case internal.PubKeyAwaitConfirmation:
|
||||
dkgProposalParticipant.Status = internal.PubKeyConfirmationError
|
||||
case internal.PubKeyConfirmed:
|
||||
err = errors.New("{Status} already confirmed")
|
||||
case internal.PubKeyConfirmationError:
|
||||
err = errors.New(fmt.Sprintf("{Status} already has {\"%s\"}", internal.PubKeyConfirmationError))
|
||||
default:
|
||||
err = errors.New(fmt.Sprintf(
|
||||
"{Status} now is \"%s\" and cannot set to {\"%s\"}",
|
||||
dkgProposalParticipant.Status,
|
||||
internal.PubKeyConfirmationError,
|
||||
))
|
||||
}
|
||||
case EventDKGCommitConfirmationError:
|
||||
switch dkgProposalParticipant.Status {
|
||||
case internal.CommitAwaitConfirmation:
|
||||
|
@ -609,7 +527,7 @@ func (m *DKGProposalFSM) actionConfirmationError(inEvent fsm.Event, args ...inte
|
|||
}
|
||||
|
||||
dkgProposalParticipant.Error = request.Error
|
||||
dkgProposalParticipant.UpdatedAt = &request.CreatedAt
|
||||
dkgProposalParticipant.UpdatedAt = request.CreatedAt
|
||||
|
||||
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
|
||||
|
||||
|
|
|
@ -3,20 +3,14 @@ package dkg_proposal_fsm
|
|||
import (
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
||||
spf "github.com/depools/dc4bc/fsm/state_machines/signature_proposal_fsm"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
FsmName = "dkg_proposal_fsm"
|
||||
|
||||
StateDkgInitial = StateDkgPubKeysAwaitConfirmations
|
||||
|
||||
StateDkgPubKeysAwaitConfirmations = fsm.State("state_dkg_pub_keys_await_confirmations")
|
||||
// Canceled
|
||||
StateDkgPubKeysAwaitCanceled = fsm.State("state_dkg_pub_keys_await_canceled")
|
||||
StateDkgPubKeysAwaitCanceledByTimeout = fsm.State("state_dkg_pub_keys_await_canceled_by_timeout")
|
||||
// Confirmed
|
||||
// StateDkgPubKeysAwaitConfirmed = fsm.State("state_dkg_pub_keys_await_confirmed")
|
||||
StateDkgInitial = spf.StateSignatureProposalCollected
|
||||
|
||||
// Sending dkg commits
|
||||
StateDkgCommitsAwaitConfirmations = fsm.State("state_dkg_commits_await_confirmations")
|
||||
|
@ -24,7 +18,7 @@ const (
|
|||
StateDkgCommitsAwaitCanceled = fsm.State("state_dkg_commits_await_canceled")
|
||||
StateDkgCommitsAwaitCanceledByTimeout = fsm.State("state_dkg_commits_await_canceled_by_timeout")
|
||||
// Confirmed
|
||||
StateDkgCommitsAwaitConfirmed = fsm.State("state_dkg_commits_await_confirmed")
|
||||
StateDkgCommitsCollected = fsm.State("state_dkg_commits_collected")
|
||||
|
||||
// Sending dkg deals
|
||||
StateDkgDealsAwaitConfirmations = fsm.State("state_dkg_deals_await_confirmations")
|
||||
|
@ -32,31 +26,23 @@ const (
|
|||
StateDkgDealsAwaitCanceled = fsm.State("state_dkg_deals_await_canceled")
|
||||
StateDkgDealsAwaitCanceledByTimeout = fsm.State("state_dkg_deals_await_canceled_by_timeout")
|
||||
// Confirmed
|
||||
//StateDkgDealsAwaitConfirmed = fsm.State("state_dkg_deals_await_confirmed")
|
||||
//StateDkgDealsCollected = fsm.State("state_dkg_deals_collected")
|
||||
|
||||
StateDkgResponsesAwaitConfirmations = fsm.State("state_dkg_responses_await_confirmations")
|
||||
// Canceled
|
||||
StateDkgResponsesAwaitCanceled = fsm.State("state_dkg_responses_await_canceled")
|
||||
StateDkgResponsesAwaitCanceledByTimeout = fsm.State("state_dkg_responses_sending_canceled_by_timeout")
|
||||
// Confirmed
|
||||
StateDkgResponsesAwaitConfirmed = fsm.State("state_dkg_responses_await_confirmed")
|
||||
StateDkgResponsesCollected = fsm.State("state_dkg_responses_collected")
|
||||
|
||||
StateDkgMasterKeyAwaitConfirmations = fsm.State("state_dkg_master_key_await_confirmations")
|
||||
StateDkgMasterKeyAwaitCanceled = fsm.State("state_dkg_master_key_await_canceled")
|
||||
StateDkgMasterKeyAwaitCanceledByTimeout = fsm.State("state_dkg_master_key_await_canceled_by_timeout")
|
||||
|
||||
StateDkgMasterKeyCollected = fsm.State("state_dkg_master_key_collected")
|
||||
|
||||
// Events
|
||||
|
||||
eventAutoDKGInitialInternal = fsm.Event("event_dkg_init_internal")
|
||||
|
||||
EventDKGPubKeyConfirmationReceived = fsm.Event("event_dkg_pub_key_confirm_received")
|
||||
EventDKGPubKeyConfirmationError = fsm.Event("event_dkg_pub_key_confirm_canceled_by_error")
|
||||
|
||||
eventAutoDKGValidatePubKeysConfirmationInternal = fsm.Event("event_dkg_pub_keys_validate_internal")
|
||||
|
||||
eventDKGSetPubKeysConfirmationCanceledByTimeoutInternal = fsm.Event("event_dkg_pub_keys_confirm_canceled_by_timeout_internal")
|
||||
eventDKGSetPubKeysConfirmationCanceledByErrorInternal = fsm.Event("event_dkg_pub_keys_confirm_canceled_by_error_internal")
|
||||
eventDKGSetPubKeysConfirmedInternal = fsm.Event("event_dkg_pub_keys_confirmed_internal")
|
||||
EventDKGInitProcess = fsm.Event("event_dkg_init_process")
|
||||
|
||||
EventDKGCommitConfirmationReceived = fsm.Event("event_dkg_commit_confirm_received")
|
||||
EventDKGCommitConfirmationError = fsm.Event("event_dkg_commit_confirm_canceled_by_error")
|
||||
|
@ -107,20 +93,13 @@ func New() internal.DumpedMachineProvider {
|
|||
// Switch to pub keys required
|
||||
// {Name: eventDKGPubKeysSendingRequiredAuto, SrcState: []fsm.State{StateDkgInitial}, DstState: StateDkgPubKeysAwaitConfirmations, IsInternal: true, IsAuto: true, AutoRunMode: fsm.EventRunAfter},
|
||||
|
||||
// {Name: eventAutoDKGInitialInternal, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitConfirmations, IsInternal: true, IsAuto: true, AutoRunMode: fsm.EventRunBefore},
|
||||
// {Name: EventDKGInitProcess, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitConfirmations, IsInternal: true, IsAuto: true, AutoRunMode: fsm.EventRunBefore},
|
||||
|
||||
// Pub keys sending
|
||||
{Name: EventDKGPubKeyConfirmationReceived, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitConfirmations},
|
||||
// Canceled
|
||||
{Name: EventDKGPubKeyConfirmationError, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitCanceled},
|
||||
// StateDkgCommitsCollected = fsm.State("state_dkg_commits_collected")
|
||||
|
||||
{Name: eventAutoDKGValidatePubKeysConfirmationInternal, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitConfirmations, IsInternal: true, IsAuto: true},
|
||||
// {Name: eventAutoDKGInitInternal, SrcState: []fsm.State{StateDkgInitial}, DstState: StateDkgCommitsAwaitConfirmations, IsInternal: true, IsAuto: true, AutoRunMode: fsm.EventRunBefore},
|
||||
|
||||
{Name: eventDKGSetPubKeysConfirmationCanceledByTimeoutInternal, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitCanceledByTimeout, IsInternal: true},
|
||||
// Confirmed
|
||||
{Name: eventDKGSetPubKeysConfirmedInternal, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgCommitsAwaitConfirmations, IsInternal: true},
|
||||
|
||||
// Switch to commits required
|
||||
{Name: EventDKGInitProcess, SrcState: []fsm.State{StateDkgInitial}, DstState: StateDkgCommitsAwaitConfirmations},
|
||||
|
||||
// Commits
|
||||
{Name: EventDKGCommitConfirmationReceived, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgCommitsAwaitConfirmations},
|
||||
|
@ -166,10 +145,7 @@ func New() internal.DumpedMachineProvider {
|
|||
// {Name: EventDKGMasterKeyRequiredInternal, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: fsm.StateGlobalDone, IsInternal: true},
|
||||
},
|
||||
fsm.Callbacks{
|
||||
|
||||
EventDKGPubKeyConfirmationReceived: machine.actionPubKeyConfirmationReceived,
|
||||
EventDKGPubKeyConfirmationError: machine.actionConfirmationError,
|
||||
eventAutoDKGValidatePubKeysConfirmationInternal: machine.actionValidateDkgProposalPubKeys,
|
||||
EventDKGInitProcess: machine.actionInitDKGProposal,
|
||||
|
||||
EventDKGCommitConfirmationReceived: machine.actionCommitConfirmationReceived,
|
||||
EventDKGCommitConfirmationError: machine.actionConfirmationError,
|
||||
|
|
|
@ -7,19 +7,20 @@ import (
|
|||
|
||||
type SignatureConfirmation struct {
|
||||
Quorum SignatureProposalQuorum
|
||||
CreatedAt *time.Time
|
||||
ExpiresAt *time.Time
|
||||
CreatedAt time.Time
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
type SignatureProposalParticipant struct {
|
||||
// Public title for address, such as name, nickname, organization
|
||||
ParticipantId int
|
||||
Title string
|
||||
PublicKey *rsa.PublicKey
|
||||
// For validation user confirmation: sign(InvitationSecret, PublicKey) => user
|
||||
PubKey *rsa.PublicKey
|
||||
DkgPubKey []byte
|
||||
// For validation user confirmation: sign(InvitationSecret, PubKey) => user
|
||||
InvitationSecret string
|
||||
Status ParticipantStatus
|
||||
UpdatedAt *time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
// Unique alias for map iteration - Public Key Fingerprint
|
||||
|
@ -33,9 +34,6 @@ const (
|
|||
SignatureConfirmationConfirmed
|
||||
SignatureConfirmationDeclined
|
||||
SignatureConfirmationError
|
||||
PubKeyAwaitConfirmation
|
||||
PubKeyConfirmed
|
||||
PubKeyConfirmationError
|
||||
CommitAwaitConfirmation
|
||||
CommitConfirmed
|
||||
CommitConfirmationError
|
||||
|
@ -59,7 +57,7 @@ type DKGProposalParticipant struct {
|
|||
MasterKey []byte
|
||||
Status ParticipantStatus
|
||||
Error error
|
||||
UpdatedAt *time.Time
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type DKGProposalQuorum map[int]*DKGProposalParticipant
|
||||
|
@ -83,12 +81,6 @@ func (s ParticipantStatus) String() string {
|
|||
str = "SignatureConfirmationDeclined"
|
||||
case SignatureConfirmationError:
|
||||
str = "SignatureConfirmationError"
|
||||
case PubKeyAwaitConfirmation:
|
||||
str = "PubKeyAwaitConfirmation"
|
||||
case PubKeyConfirmed:
|
||||
str = "PubKeyConfirmed"
|
||||
case PubKeyConfirmationError:
|
||||
str = "PubKeyConfirmationError"
|
||||
case CommitAwaitConfirmation:
|
||||
str = "CommitAwaitConfirmation"
|
||||
case CommitConfirmed:
|
||||
|
|
|
@ -17,14 +17,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
testTransactionId = "d8a928b2043db77e340b523547bf16cb4aa483f0645fe0a290ed1f20aab76257"
|
||||
)
|
||||
|
||||
type testExternalParticipants struct {
|
||||
Title string
|
||||
PrivKey *rsa.PrivateKey
|
||||
PubKey *rsa.PublicKey
|
||||
Title string
|
||||
PrivKey *rsa.PrivateKey
|
||||
PubKey *rsa.PublicKey
|
||||
DkgPubKey []byte
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -34,7 +31,7 @@ var (
|
|||
|
||||
testParticipantsListRequest = requests.SignatureProposalParticipantsListRequest{
|
||||
Participants: []*requests.SignatureProposalParticipantsEntry{},
|
||||
CreatedAt: &tm,
|
||||
CreatedAt: tm,
|
||||
}
|
||||
|
||||
testFSMDump []byte
|
||||
|
@ -59,10 +56,15 @@ func init() {
|
|||
|
||||
fingerprint := base64.StdEncoding.EncodeToString(hash[:])
|
||||
|
||||
pubKeyMock := make([]byte, 128)
|
||||
|
||||
rand.Read(pubKeyMock)
|
||||
|
||||
participant := &testExternalParticipants{
|
||||
Title: fmt.Sprintf("User %d", i),
|
||||
PrivKey: key,
|
||||
PubKey: &key.PublicKey,
|
||||
Title: fmt.Sprintf("User %d", i),
|
||||
PrivKey: key,
|
||||
PubKey: &key.PublicKey,
|
||||
DkgPubKey: pubKeyMock,
|
||||
}
|
||||
testParticipants[fingerprint] = participant
|
||||
}
|
||||
|
@ -72,8 +74,9 @@ func init() {
|
|||
for _, participant := range testParticipants {
|
||||
|
||||
participantsForRequest = append(participantsForRequest, &requests.SignatureProposalParticipantsEntry{
|
||||
Title: participant.Title,
|
||||
PubKey: x509.MarshalPKCS1PublicKey(participant.PubKey),
|
||||
Title: participant.Title,
|
||||
PubKey: x509.MarshalPKCS1PublicKey(participant.PubKey),
|
||||
DkgPubKey: participant.DkgPubKey,
|
||||
})
|
||||
}
|
||||
testParticipantsListRequest.Participants = participantsForRequest
|
||||
|
@ -197,7 +200,7 @@ func Test_SignatureProposal_Positive(t *testing.T) {
|
|||
participantsMap[participant.ParticipantId] = participant
|
||||
}
|
||||
|
||||
tm = tm.Add(10 * time.Hour)
|
||||
tm = tm.Add(1 * time.Hour)
|
||||
|
||||
participantsCount := len(participantsMap)
|
||||
|
||||
|
@ -222,10 +225,10 @@ func Test_SignatureProposal_Positive(t *testing.T) {
|
|||
t.Fatalf("cannot encrypt {DecryptedInvitation} with private key")
|
||||
}
|
||||
|
||||
fsmResponse, dump, err = testFSMInstance.Do(spf.EventConfirmProposal, requests.SignatureProposalParticipantRequest{
|
||||
fsmResponse, dump, err = testFSMInstance.Do(spf.EventConfirmSignatureProposal, requests.SignatureProposalParticipantRequest{
|
||||
PubKeyFingerprint: participant.PubKeyFingerprint,
|
||||
DecryptedInvitation: string(encrypted),
|
||||
CreatedAt: &tm,
|
||||
CreatedAt: tm,
|
||||
})
|
||||
|
||||
compareErrNil(t, err)
|
||||
|
@ -236,45 +239,21 @@ func Test_SignatureProposal_Positive(t *testing.T) {
|
|||
|
||||
if participantCounter > 0 {
|
||||
compareState(t, spf.StateAwaitParticipantsConfirmations, fsmResponse.State)
|
||||
} else {
|
||||
compareState(t, dpf.StateDkgInitial, fsmResponse.State)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// PubKeys
|
||||
compareState(t, spf.StateSignatureProposalCollected, fsmResponse.State)
|
||||
|
||||
for _, participant := range participantsMap {
|
||||
participantCounter--
|
||||
testFSMInstance, err = FromDump(dump)
|
||||
testFSMInstance, err = FromDump(dump)
|
||||
|
||||
compareErrNil(t, err)
|
||||
fsmResponse, dump, err = testFSMInstance.Do(dpf.EventDKGInitProcess)
|
||||
|
||||
compareFSMInstanceNotNil(t, testFSMInstance)
|
||||
compareErrNil(t, err)
|
||||
|
||||
if _, ok := testParticipants[participant.PubKeyFingerprint]; !ok {
|
||||
t.Fatalf("not found external user data for response fingerprint")
|
||||
}
|
||||
compareDumpNotZero(t, dump)
|
||||
|
||||
pubKeyMock := make([]byte, 128)
|
||||
_, err := rand.Read(pubKeyMock)
|
||||
if err != nil {
|
||||
compareErrNil(t, err)
|
||||
}
|
||||
|
||||
fsmResponse, dump, err = testFSMInstance.Do(dpf.EventDKGPubKeyConfirmationReceived, requests.DKGProposalPubKeyConfirmationRequest{
|
||||
ParticipantId: participant.ParticipantId,
|
||||
PubKey: pubKeyMock,
|
||||
CreatedAt: tm,
|
||||
})
|
||||
|
||||
compareErrNil(t, err)
|
||||
|
||||
compareDumpNotZero(t, dump)
|
||||
|
||||
compareFSMResponseNotNil(t, fsmResponse)
|
||||
|
||||
}
|
||||
compareFSMResponseNotNil(t, fsmResponse)
|
||||
|
||||
compareState(t, dpf.StateDkgCommitsAwaitConfirmations, fsmResponse.State)
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
|
||||
// init -> awaitingConfirmations
|
||||
// args: payload, signing id, participants list
|
||||
func (m *SignatureProposalFSM) actionInitProposal(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
func (m *SignatureProposalFSM) actionInitSignatureProposal(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
m.payloadMu.Lock()
|
||||
defer m.payloadMu.Unlock()
|
||||
|
||||
|
@ -54,7 +54,8 @@ func (m *SignatureProposalFSM) actionInitProposal(inEvent fsm.Event, args ...int
|
|||
m.payload.SignatureProposalPayload.Quorum[participantId] = &internal.SignatureProposalParticipant{
|
||||
ParticipantId: index,
|
||||
Title: participant.Title,
|
||||
PublicKey: parsedPubKey,
|
||||
PubKey: parsedPubKey,
|
||||
DkgPubKey: participant.DkgPubKey,
|
||||
InvitationSecret: secret,
|
||||
Status: internal.SignatureConfirmationAwaitConfirmation,
|
||||
UpdatedAt: request.CreatedAt,
|
||||
|
@ -72,7 +73,7 @@ func (m *SignatureProposalFSM) actionInitProposal(inEvent fsm.Event, args ...int
|
|||
responseData := make(responses.SignatureProposalParticipantInvitationsResponse, 0)
|
||||
|
||||
for pubKeyFingerprint, proposal := range m.payload.SignatureProposalPayload.Quorum {
|
||||
encryptedInvitationSecret, err := encryptWithPubKey(proposal.PublicKey, proposal.InvitationSecret)
|
||||
encryptedInvitationSecret, err := encryptWithPubKey(proposal.PubKey, proposal.InvitationSecret)
|
||||
if err != nil {
|
||||
return inEvent, nil, errors.New("cannot encryptWithPubKey")
|
||||
}
|
||||
|
@ -122,7 +123,7 @@ func (m *SignatureProposalFSM) actionProposalResponseByParticipant(inEvent fsm.E
|
|||
return
|
||||
}
|
||||
|
||||
if signatureProposalParticipant.UpdatedAt.Add(config.SignatureProposalConfirmationDeadline).Before(*request.CreatedAt) {
|
||||
if signatureProposalParticipant.UpdatedAt.Add(config.SignatureProposalConfirmationDeadline).Before(request.CreatedAt) {
|
||||
outEvent = eventSetValidationCanceledByTimeout
|
||||
return
|
||||
}
|
||||
|
@ -133,7 +134,7 @@ func (m *SignatureProposalFSM) actionProposalResponseByParticipant(inEvent fsm.E
|
|||
}
|
||||
|
||||
switch inEvent {
|
||||
case EventConfirmProposal:
|
||||
case EventConfirmSignatureProposal:
|
||||
signatureProposalParticipant.Status = internal.SignatureConfirmationConfirmed
|
||||
case EventDeclineProposal:
|
||||
signatureProposalParticipant.Status = internal.SignatureConfirmationDeclined
|
||||
|
@ -189,37 +190,19 @@ func (m *SignatureProposalFSM) actionValidateSignatureProposal(inEvent fsm.Event
|
|||
return
|
||||
}
|
||||
|
||||
outEvent = eventSetProposalValidatedInternal
|
||||
|
||||
m.actionSetValidatedSignatureProposal(outEvent)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (m *SignatureProposalFSM) actionSetValidatedSignatureProposal(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
// m.payloadMu.Lock()
|
||||
// defer m.payloadMu.Unlock()
|
||||
|
||||
// TODO: Run once after validation
|
||||
if m.payload.DKGProposalPayload != nil {
|
||||
return
|
||||
}
|
||||
|
||||
m.payload.DKGProposalPayload = &internal.DKGConfirmation{
|
||||
Quorum: make(internal.DKGProposalQuorum),
|
||||
}
|
||||
responseData := make(responses.SignatureProposalParticipantStatusResponse, 0)
|
||||
|
||||
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
|
||||
m.payload.DKGProposalPayload.Quorum[participant.ParticipantId] = &internal.DKGProposalParticipant{
|
||||
Title: participant.Title,
|
||||
Status: internal.PubKeyAwaitConfirmation,
|
||||
UpdatedAt: participant.UpdatedAt,
|
||||
responseEntry := &responses.SignatureProposalParticipantStatusEntry{
|
||||
ParticipantId: participant.ParticipantId,
|
||||
Title: participant.Title,
|
||||
DkgPubKey: participant.DkgPubKey,
|
||||
Status: uint8(participant.Status),
|
||||
}
|
||||
responseData = append(responseData, responseEntry)
|
||||
}
|
||||
|
||||
// Remove m.payload.SignatureProposalPayload?
|
||||
|
||||
return
|
||||
return eventSetProposalValidatedInternal, responseData, nil
|
||||
}
|
||||
|
||||
func (m *SignatureProposalFSM) actionSignatureProposalCanceledByTimeout(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
|
@ -228,12 +211,11 @@ func (m *SignatureProposalFSM) actionSignatureProposalCanceledByTimeout(inEvent
|
|||
|
||||
responseData := make(responses.SignatureProposalParticipantStatusResponse, 0)
|
||||
|
||||
for pubKeyFingerprint, participant := range m.payload.SignatureProposalPayload.Quorum {
|
||||
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
|
||||
responseEntry := &responses.SignatureProposalParticipantStatusEntry{
|
||||
ParticipantId: participant.ParticipantId,
|
||||
Title: participant.Title,
|
||||
PubKeyFingerprint: pubKeyFingerprint,
|
||||
Status: uint8(participant.Status),
|
||||
ParticipantId: participant.ParticipantId,
|
||||
Title: participant.Title,
|
||||
Status: uint8(participant.Status),
|
||||
}
|
||||
responseData = append(responseData, responseEntry)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package signature_proposal_fsm
|
|||
|
||||
import (
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
||||
"sync"
|
||||
)
|
||||
|
@ -21,14 +20,18 @@ const (
|
|||
// Out state
|
||||
|
||||
EventInitProposal = fsm.Event("event_sig_proposal_init")
|
||||
EventConfirmProposal = fsm.Event("event_sig_proposal_confirm_by_participant")
|
||||
EventConfirmSignatureProposal = fsm.Event("event_sig_proposal_confirm_by_participant")
|
||||
EventDeclineProposal = fsm.Event("event_sig_proposal_decline_by_participant")
|
||||
eventAutoValidateProposalInternal = fsm.Event("event_sig_proposal_validate")
|
||||
eventSetProposalValidatedInternal = fsm.Event("event_sig_proposal_set_validated")
|
||||
|
||||
eventDoneInternal = fsm.Event("event_sig_proposal_done")
|
||||
|
||||
eventSetValidationCanceledByTimeout = fsm.Event("event_sig_proposal_canceled_timeout")
|
||||
eventSetValidationCanceledByParticipant = fsm.Event("event_sig_proposal_declined_timeout")
|
||||
|
||||
StateSignatureProposalCollected = fsm.State("state_sig_proposal_collected")
|
||||
|
||||
// Switch to next fsm
|
||||
|
||||
)
|
||||
|
@ -52,7 +55,7 @@ func New() internal.DumpedMachineProvider {
|
|||
{Name: EventInitProposal, SrcState: []fsm.State{StateParticipantsConfirmationsInit}, DstState: StateAwaitParticipantsConfirmations},
|
||||
|
||||
// Validate by participants
|
||||
{Name: EventConfirmProposal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateAwaitParticipantsConfirmations},
|
||||
{Name: EventConfirmSignatureProposal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateAwaitParticipantsConfirmations},
|
||||
// Is decline event should auto change state to default, or it process will initiated by client (external emit)?
|
||||
// Now set for external emitting.
|
||||
{Name: EventDeclineProposal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateAwaitParticipantsConfirmations},
|
||||
|
@ -62,17 +65,18 @@ func New() internal.DumpedMachineProvider {
|
|||
|
||||
// eventProposalValidate internal or from client?
|
||||
// yay
|
||||
|
||||
// Exit point
|
||||
{Name: eventSetProposalValidatedInternal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: dkg_proposal_fsm.StateDkgPubKeysAwaitConfirmations, IsInternal: true},
|
||||
{Name: eventSetProposalValidatedInternal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateSignatureProposalCollected, IsInternal: true},
|
||||
|
||||
// nan
|
||||
{Name: eventSetValidationCanceledByTimeout, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateValidationCanceledByTimeout, IsInternal: true},
|
||||
},
|
||||
fsm.Callbacks{
|
||||
EventInitProposal: machine.actionInitProposal,
|
||||
EventConfirmProposal: machine.actionProposalResponseByParticipant,
|
||||
EventInitProposal: machine.actionInitSignatureProposal,
|
||||
EventConfirmSignatureProposal: machine.actionProposalResponseByParticipant,
|
||||
EventDeclineProposal: machine.actionProposalResponseByParticipant,
|
||||
eventAutoValidateProposalInternal: machine.actionValidateSignatureProposal,
|
||||
eventSetProposalValidatedInternal: machine.actionSetValidatedSignatureProposal,
|
||||
},
|
||||
)
|
||||
return machine
|
||||
|
|
|
@ -2,14 +2,6 @@ package requests
|
|||
|
||||
import "time"
|
||||
|
||||
// States: "state_dkg_pub_keys_await_confirmations"
|
||||
// Events: "event_dkg_pub_key_confirm_received"
|
||||
type DKGProposalPubKeyConfirmationRequest struct {
|
||||
ParticipantId int
|
||||
PubKey []byte
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
// States: "state_dkg_commits_sending_await_confirmations"
|
||||
// Events: "event_dkg_commit_confirm_received"
|
||||
type DKGProposalCommitConfirmationRequest struct {
|
||||
|
|
|
@ -2,22 +2,6 @@ package requests
|
|||
|
||||
import "errors"
|
||||
|
||||
func (r *DKGProposalPubKeyConfirmationRequest) Validate() error {
|
||||
if r.ParticipantId < 0 {
|
||||
return errors.New("{ParticipantId} cannot be a negative number")
|
||||
}
|
||||
|
||||
if len(r.PubKey) == 0 {
|
||||
return errors.New("{PubKey} cannot zero length")
|
||||
}
|
||||
|
||||
if r.CreatedAt.IsZero() {
|
||||
return errors.New("{CreatedAt} is not set")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *DKGProposalCommitConfirmationRequest) Validate() error {
|
||||
if r.ParticipantId < 0 {
|
||||
return errors.New("{ParticipantId} cannot be a negative number")
|
||||
|
|
|
@ -8,13 +8,14 @@ import "time"
|
|||
// Events: "event_sig_proposal_init"
|
||||
type SignatureProposalParticipantsListRequest struct {
|
||||
Participants []*SignatureProposalParticipantsEntry
|
||||
CreatedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
||||
type SignatureProposalParticipantsEntry struct {
|
||||
// Public title for address, such as name, nickname, organization
|
||||
Title string
|
||||
PubKey []byte
|
||||
Title string
|
||||
PubKey []byte
|
||||
DkgPubKey []byte
|
||||
}
|
||||
|
||||
// States: "__idle"
|
||||
|
@ -24,5 +25,5 @@ type SignatureProposalParticipantRequest struct {
|
|||
// Key for link invitations to participants
|
||||
PubKeyFingerprint string
|
||||
DecryptedInvitation string
|
||||
CreatedAt *time.Time
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
|
|
@ -23,9 +23,13 @@ func (r *SignatureProposalParticipantsListRequest) Validate() error {
|
|||
if len(participant.PubKey) < 10 {
|
||||
return errors.New("{PubKey} too short")
|
||||
}
|
||||
|
||||
if len(participant.DkgPubKey) < 10 {
|
||||
return errors.New("{DkgPubKey} too short")
|
||||
}
|
||||
}
|
||||
|
||||
if r.CreatedAt == nil {
|
||||
if r.CreatedAt.IsZero() {
|
||||
return errors.New("{CreatedAt} cannot be a nil")
|
||||
}
|
||||
|
||||
|
@ -41,7 +45,7 @@ func (r *SignatureProposalParticipantRequest) Validate() error {
|
|||
return errors.New("{DecryptedInvitation} cannot zero length")
|
||||
}
|
||||
|
||||
if r.CreatedAt == nil {
|
||||
if r.CreatedAt.IsZero() {
|
||||
return errors.New("{CreatedAt} cannot be a nil")
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -1,13 +1,5 @@
|
|||
package responses
|
||||
|
||||
type DKGProposalPubKeyParticipantResponse []*DKGProposalPubKeyParticipantEntry
|
||||
|
||||
type DKGProposalPubKeyParticipantEntry struct {
|
||||
ParticipantId int
|
||||
Title string
|
||||
PubKey []byte
|
||||
}
|
||||
|
||||
type DKGProposalCommitParticipantResponse []*DKGProposalCommitParticipantEntry
|
||||
|
||||
type DKGProposalCommitParticipantEntry struct {
|
||||
|
|
|
@ -22,8 +22,8 @@ type SignatureProposalParticipantInvitationEntry struct {
|
|||
type SignatureProposalParticipantStatusResponse []*SignatureProposalParticipantStatusEntry
|
||||
|
||||
type SignatureProposalParticipantStatusEntry struct {
|
||||
ParticipantId int
|
||||
Title string
|
||||
PubKeyFingerprint string
|
||||
Status uint8
|
||||
ParticipantId int
|
||||
Title string
|
||||
DkgPubKey []byte
|
||||
Status uint8
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue