From 023a9f8d5c9de050c78f628e4298c1228030fc81 Mon Sep 17 00:00:00 2001 From: x88 Date: Wed, 12 Aug 2020 09:38:58 +0300 Subject: [PATCH] feat: fixed flow, added tests --- fsm/fsm/fsm.go | 2 +- fsm/state_machines/dkg_proposal_fsm/init.go | 54 +++++++----- fsm/state_machines/provider_test.go | 98 +-------------------- 3 files changed, 33 insertions(+), 121 deletions(-) diff --git a/fsm/fsm/fsm.go b/fsm/fsm/fsm.go index 0a947a4..2af2abd 100644 --- a/fsm/fsm/fsm.go +++ b/fsm/fsm/fsm.go @@ -382,7 +382,7 @@ func (f *FSM) SetState(event Event) error { trEvent, ok := f.transitions[trKey{f.currentState, event}] if !ok { - return errors.New("cannot change state") + return errors.New(fmt.Sprintf("cannot execute event \"%s\" for state \"%s\"", event, f.currentState)) } f.currentState = trEvent.dstState diff --git a/fsm/state_machines/dkg_proposal_fsm/init.go b/fsm/state_machines/dkg_proposal_fsm/init.go index 040e759..e7df621 100644 --- a/fsm/state_machines/dkg_proposal_fsm/init.go +++ b/fsm/state_machines/dkg_proposal_fsm/init.go @@ -48,7 +48,7 @@ const ( EventDKGPubKeyConfirmationReceived = fsm.Event("event_dkg_pub_key_confirm_received") EventDKGPubKeyConfirmationError = fsm.Event("event_dkg_pub_key_confirm_canceled_by_error") - eventAutoValidatePubKeysInternal = fsm.Event("event_dkg_pub_keys_validate_internal") + 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") @@ -59,20 +59,21 @@ const ( eventDKGCommitsConfirmationCancelByTimeoutInternal = fsm.Event("event_dkg_commits_confirm_canceled_by_timeout_internal") eventDKGCommitsConfirmationCancelByErrorInternal = fsm.Event("event_dkg_commits_confirm_canceled_by_error_internal") eventDKGCommitsConfirmedInternal = fsm.Event("event_dkg_commits_confirmed_internal") - - // EventDKGDealsSendingRequiredInternal = fsm.Event("event_dkg_deals_sending_required_internal") + eventAutoDKGValidateConfirmationCommitsInternal = fsm.Event("event_dkg_commits_validate_internal") EventDKGDealConfirmationReceived = fsm.Event("event_dkg_deal_confirm_received") EventDKGDealConfirmationError = fsm.Event("event_dkg_deal_confirm_canceled_by_error") eventDKGDealsConfirmationCancelByTimeoutInternal = fsm.Event("event_dkg_deals_confirm_canceled_by_timeout_internal") eventDKGDealsConfirmationCancelByErrorInternal = fsm.Event("event_dkg_deals_confirm_canceled_by_error_internal") eventDKGDealsConfirmedInternal = fsm.Event("event_dkg_deals_confirmed_internal") + eventAutoDKGValidateConfirmationDealsInternal = fsm.Event("event_dkg_deals_validate_internal") EventDKGResponseConfirmationReceived = fsm.Event("event_dkg_response_confirm_received") EventDKGResponseConfirmationError = fsm.Event("event_dkg_response_confirm_canceled_by_error") eventDKGResponseConfirmationCancelByTimeoutInternal = fsm.Event("event_dkg_response_confirm_canceled_by_timeout_internal") eventDKGResponseConfirmationCancelByErrorInternal = fsm.Event("event_dkg_response_confirm_canceled_by_error_internal") eventDKGResponsesConfirmedInternal = fsm.Event("event_dkg_responses_confirmed_internal") + eventAutoDKGValidateResponsesConfirmationInternal = fsm.Event("event_dkg_responses_validate_internal") EventDKGMasterKeyRequiredInternal = fsm.Event("event_dkg_master_key_required_internal") ) @@ -102,59 +103,64 @@ func New() internal.DumpedMachineProvider { // Canceled {Name: EventDKGPubKeyConfirmationError, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitCanceled}, - {Name: eventAutoValidatePubKeysInternal, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitConfirmations, IsInternal: true, IsAuto: true}, + {Name: eventAutoDKGValidatePubKeysConfirmationInternal, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmations}, DstState: StateDkgPubKeysAwaitConfirmations, IsInternal: true, IsAuto: true}, {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: EventDKGCommitsSendingRequiredInternal, SrcState: []fsm.State{StateDkgPubKeysAwaitConfirmed}, DstState: StateDkgCommitsAwaitConfirmations, IsInternal: true}, // Commits {Name: EventDKGCommitConfirmationReceived, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgCommitsAwaitConfirmations}, // Canceled {Name: EventDKGCommitConfirmationError, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgCommitsAwaitCanceled}, {Name: eventDKGCommitsConfirmationCancelByTimeoutInternal, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgCommitsAwaitCanceledByTimeout, IsInternal: true}, + + {Name: eventAutoDKGValidateConfirmationCommitsInternal, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgCommitsAwaitConfirmations, IsInternal: true, IsAuto: true}, + // Confirmed {Name: eventDKGCommitsConfirmedInternal, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgDealsAwaitConfirmations, IsInternal: true}, - // Switch to deals required - // {Name: EventDKGDealsSendingRequiredInternal, SrcState: []fsm.State{StateDkgDealsAwaitConfirmed}, DstState: StateDkgDealsAwaitConfirmations, IsInternal: true}, - // Deals {Name: EventDKGDealConfirmationReceived, SrcState: []fsm.State{StateDkgDealsAwaitConfirmations}, DstState: StateDkgDealsAwaitConfirmations}, // Canceled - {Name: EventDKGDealConfirmationError, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgDealsAwaitCanceled}, - {Name: eventDKGDealsConfirmationCancelByTimeoutInternal, SrcState: []fsm.State{StateDkgCommitsAwaitConfirmations}, DstState: StateDkgDealsAwaitCanceledByTimeout, IsInternal: true}, + {Name: EventDKGDealConfirmationError, SrcState: []fsm.State{StateDkgDealsAwaitConfirmations}, DstState: StateDkgDealsAwaitCanceled}, + {Name: eventDKGDealsConfirmationCancelByTimeoutInternal, SrcState: []fsm.State{StateDkgDealsAwaitConfirmations}, DstState: StateDkgDealsAwaitConfirmations, IsInternal: true}, + {Name: eventAutoDKGValidateConfirmationDealsInternal, SrcState: []fsm.State{StateDkgDealsAwaitConfirmations}, DstState: StateDkgDealsAwaitConfirmations, IsInternal: true, IsAuto: true}, - // Switch to responses required - // {Name: eventDKGResponsesSendingRequiredInternal, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmed}, DstState: StateDkgResponsesAwaitConfirmations, IsInternal: true}, + {Name: eventDKGDealsConfirmedInternal, SrcState: []fsm.State{StateDkgDealsAwaitConfirmations}, DstState: StateDkgResponsesAwaitConfirmations, IsInternal: true}, - // Deals + // Responses {Name: EventDKGResponseConfirmationReceived, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: StateDkgResponsesAwaitConfirmations}, // Canceled {Name: EventDKGResponseConfirmationError, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: StateDkgResponsesAwaitCanceled}, {Name: eventDKGResponseConfirmationCancelByTimeoutInternal, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: StateDkgResponsesAwaitCanceledByTimeout, IsInternal: true}, + {Name: eventAutoDKGValidateResponsesConfirmationInternal, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: StateDkgResponsesAwaitConfirmations, IsInternal: true, IsAuto: true}, + + {Name: eventDKGResponsesConfirmedInternal, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: fsm.StateGlobalDone, IsInternal: true}, + // Done - {Name: EventDKGMasterKeyRequiredInternal, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: fsm.StateGlobalDone, IsInternal: true}, + // {Name: EventDKGMasterKeyRequiredInternal, SrcState: []fsm.State{StateDkgResponsesAwaitConfirmations}, DstState: fsm.StateGlobalDone, IsInternal: true}, }, fsm.Callbacks{ - EventDKGPubKeyConfirmationReceived: machine.actionPubKeyConfirmationReceived, - EventDKGPubKeyConfirmationError: machine.actionConfirmationError, - // actionValidateDkgProposalPubKeys - eventAutoValidatePubKeysInternal: machine.actionValidateDkgProposalPubKeys, + EventDKGPubKeyConfirmationReceived: machine.actionPubKeyConfirmationReceived, + EventDKGPubKeyConfirmationError: machine.actionConfirmationError, + eventAutoDKGValidatePubKeysConfirmationInternal: machine.actionValidateDkgProposalPubKeys, - EventDKGCommitConfirmationReceived: machine.actionCommitConfirmationReceived, - EventDKGCommitConfirmationError: machine.actionConfirmationError, + EventDKGCommitConfirmationReceived: machine.actionCommitConfirmationReceived, + EventDKGCommitConfirmationError: machine.actionConfirmationError, + eventAutoDKGValidateConfirmationCommitsInternal: machine.actionValidateDkgProposalAwaitCommits, - EventDKGDealConfirmationReceived: machine.actionDealConfirmationReceived, - EventDKGDealConfirmationError: machine.actionConfirmationError, + EventDKGDealConfirmationReceived: machine.actionDealConfirmationReceived, + EventDKGDealConfirmationError: machine.actionConfirmationError, + eventAutoDKGValidateConfirmationDealsInternal: machine.actionValidateDkgProposalAwaitDeals, - EventDKGResponseConfirmationReceived: machine.actionResponseConfirmationReceived, - EventDKGResponseConfirmationError: machine.actionConfirmationError, + EventDKGResponseConfirmationReceived: machine.actionResponseConfirmationReceived, + EventDKGResponseConfirmationError: machine.actionConfirmationError, + eventAutoDKGValidateResponsesConfirmationInternal: machine.actionValidateDkgProposalAwaitResponses, }, ) return machine diff --git a/fsm/state_machines/provider_test.go b/fsm/state_machines/provider_test.go index 71a6b55..1d5f60b 100644 --- a/fsm/state_machines/provider_test.go +++ b/fsm/state_machines/provider_test.go @@ -375,9 +375,9 @@ func Test_SignatureProposal_Positive(t *testing.T) { compareErrNil(t, err) } - fsmResponse, dump, err = testFSMInstance.Do(dpf.EventDKGDealConfirmationReceived, requests.DKGProposalDealConfirmationRequest{ + fsmResponse, dump, err = testFSMInstance.Do(dpf.EventDKGResponseConfirmationReceived, requests.DKGProposalResponseConfirmationRequest{ ParticipantId: participant.ParticipantId, - Deal: responseMock, + Response: responseMock, CreatedAt: &tm, }) @@ -391,97 +391,3 @@ func Test_SignatureProposal_Positive(t *testing.T) { compareState(t, fsm.StateGlobalDone, fsmResponse.State) } - -/* -func Test_SignatureProposal_Negative_By_Decline(t *testing.T) { - testFSMInstance, err := FromDump(testFSMDump) - - compareErrNil(t, err) - - compareFSMInstanceNotNil(t, testFSMInstance) - - fsmResponse, dump, err := testFSMInstance.Do(spf.EventInitProposal, testParticipantsListRequest) - - compareErrNil(t, err) - - compareDumpNotZero(t, dump) - - compareFSMResponseNotNil(t, fsmResponse) - - compareState(t, spf.StateAwaitParticipantsConfirmations, fsmResponse.State) - - testParticipantsListResponse, ok := fsmResponse.Data.(responses.SignatureProposalParticipantInvitationsResponse) - - if !ok { - t.Fatalf("expected response {SignatureProposalParticipantInvitationsResponse}") - } - - if len(testParticipantsListResponse) != len(testParticipantsListRequest.Participants) { - t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(testParticipantsListResponse)) - } - - participantsMap := map[int]*responses.SignatureProposalParticipantInvitationEntry{} - - for _, participant := range testParticipantsListResponse { - if _, ok := participantsMap[participant.ParticipantId]; ok { - t.Fatalf("expected unique {ParticipantId}") - } - - if participant.Title == "" { - t.Fatalf("expected not empty {Title}") - } - - if participant.EncryptedInvitation == "" { - t.Fatalf("expected not empty {DecryptedInvitation}") - } - - if participant.PubKeyFingerprint == "" { - t.Fatalf("expected not empty {PubKeyFingerprint}") - } - - participantsMap[participant.ParticipantId] = participant - } - - tm = tm.Add(10 * time.Second) - - participantsCount := len(participantsMap) - - participantCounter := participantsCount - - for _, participant := range participantsMap { - participantCounter-- - testFSMInstance, err = FromDump(dump) - - compareErrNil(t, err) - - compareFSMInstanceNotNil(t, testFSMInstance) - - if _, ok := testParticipants[participant.PubKeyFingerprint]; !ok { - t.Fatalf("not found external user data for response fingerprint") - } - - r := rand.Reader - encrypted, err := rsa.DecryptPKCS1v15(r, testParticipants[participant.PubKeyFingerprint].PrivKey, []byte(participant.EncryptedInvitation)) - - if err != nil { - t.Fatalf("cannot encrypt {DecryptedInvitation} with private key") - } - - fsmResponse, dump, err = testFSMInstance.Do(spf.EventDeclineProposal, requests.SignatureProposalParticipantRequest{ - PubKeyFingerprint: participant.PubKeyFingerprint, - DecryptedInvitation: string(encrypted), - CreatedAt: &tm, - }) - - compareErrNil(t, err) - - compareDumpNotZero(t, dump) - - compareFSMResponseNotNil(t, fsmResponse) - - compareState(t, spf.StateValidationCanceledByParticipant, fsmResponse.State) - - - } -} -*/