From dc23e4faf29ceac2b7a874d09bc6de247580e886 Mon Sep 17 00:00:00 2001 From: x88 Date: Fri, 21 Aug 2020 16:56:03 +0300 Subject: [PATCH] fixed init FSM with custom state --- fsm/fsm/fsm.go | 12 ++++- fsm/state_machines/dkg_proposal_fsm/init.go | 4 +- fsm/state_machines/internal/provider.go | 3 +- fsm/state_machines/provider.go | 21 ++++---- fsm/state_machines/provider_test.go | 52 ++++++++++++++++++- .../signature_proposal_fsm/init.go | 4 +- .../signing_proposal_fsm/init.go | 4 +- 7 files changed, 84 insertions(+), 16 deletions(-) diff --git a/fsm/fsm/fsm.go b/fsm/fsm/fsm.go index 4f3c9c8..cdd5d8c 100644 --- a/fsm/fsm/fsm.go +++ b/fsm/fsm/fsm.go @@ -120,7 +120,6 @@ type Callback func(event Event, args ...interface{}) (Event, interface{}, error) type Callbacks map[Event]Callback -// TODO: Exports func MustNewFSM(machineName string, initialState State, events []EventDesc, callbacks Callbacks) *FSM { machineName = strings.TrimSpace(machineName) initialState = State(strings.TrimSpace(initialState.String())) @@ -276,6 +275,17 @@ func MustNewFSM(machineName string, initialState State, events []EventDesc, call return f } +// WithState returns FSM copy with custom setup state +func (f FSM) CopyWithState(state State) *FSM { + f.stateMu.RLock() + defer f.stateMu.RUnlock() + + if state != "" { + f.currentState = state + } + return &f +} + func (f *FSM) DoInternal(event Event, args ...interface{}) (resp *Response, err error) { trEvent, ok := f.transitions[trKey{f.currentState, event}] if !ok { diff --git a/fsm/state_machines/dkg_proposal_fsm/init.go b/fsm/state_machines/dkg_proposal_fsm/init.go index 04e869c..df0fe94 100644 --- a/fsm/state_machines/dkg_proposal_fsm/init.go +++ b/fsm/state_machines/dkg_proposal_fsm/init.go @@ -165,9 +165,11 @@ func New() internal.DumpedMachineProvider { return machine } -func (m *DKGProposalFSM) SetUpPayload(payload *internal.DumpedMachineStatePayload) { +func (m *DKGProposalFSM) WithSetup(state fsm.State, payload *internal.DumpedMachineStatePayload) internal.DumpedMachineProvider { m.payloadMu.Lock() defer m.payloadMu.Unlock() m.payload = payload + m.FSM = m.FSM.CopyWithState(state) + return m } diff --git a/fsm/state_machines/internal/provider.go b/fsm/state_machines/internal/provider.go index 78969e9..a2d569a 100644 --- a/fsm/state_machines/internal/provider.go +++ b/fsm/state_machines/internal/provider.go @@ -4,12 +4,13 @@ import ( "crypto/ed25519" "encoding/hex" "errors" + "github.com/depools/dc4bc/fsm/fsm" "github.com/depools/dc4bc/fsm/fsm_pool" ) type DumpedMachineProvider interface { fsm_pool.MachineProvider - SetUpPayload(payload *DumpedMachineStatePayload) + WithSetup(state fsm.State, payload *DumpedMachineStatePayload) DumpedMachineProvider } // DKG and other stages quorums are separated, diff --git a/fsm/state_machines/provider.go b/fsm/state_machines/provider.go index 2be01d9..00a7aa2 100644 --- a/fsm/state_machines/provider.go +++ b/fsm/state_machines/provider.go @@ -47,8 +47,8 @@ func Create(dkgID string) (*FSMInstance, error) { ) machine, err := fsmPoolProvider.EntryPointMachine() - i.machine = machine.(internal.DumpedMachineProvider) - i.machine.SetUpPayload(i.dump.Payload) + i.machine = machine.(internal.DumpedMachineProvider). + WithSetup(i.dump.State, i.dump.Payload) return i, err } @@ -60,6 +60,12 @@ func FromDump(data []byte) (*FSMInstance, error) { return nil, errors.New("machine dump is empty") } + fsmPoolProvider := fsm_pool.Init( + signature_proposal_fsm.New(), + dkg_proposal_fsm.New(), + signing_proposal_fsm.New(), + ) + i := &FSMInstance{ dump: &FSMDump{}, } @@ -70,18 +76,13 @@ func FromDump(data []byte) (*FSMInstance, error) { return nil, errors.New("cannot read machine dump") } - fsmPoolProvider := fsm_pool.Init( - signature_proposal_fsm.New(), - dkg_proposal_fsm.New(), - signing_proposal_fsm.New(), - ) - machine, err := fsmPoolProvider.MachineByState(i.dump.State) if err != nil { return nil, err } - i.machine = machine.(internal.DumpedMachineProvider) - i.machine.SetUpPayload(i.dump.Payload) + + i.machine = machine.(internal.DumpedMachineProvider). + WithSetup(i.dump.State, i.dump.Payload) return i, err } diff --git a/fsm/state_machines/provider_test.go b/fsm/state_machines/provider_test.go index 54d7d84..a488dd1 100644 --- a/fsm/state_machines/provider_test.go +++ b/fsm/state_machines/provider_test.go @@ -439,6 +439,56 @@ func Test_SignatureProposal_Positive(t *testing.T) { } -func Test_DKGProposal_Positive(t *testing.T) { +func Test_Parallel(t *testing.T) { + var ( + id1 = "123" + id2 = "456" + ) + testFSMInstance1, err := Create(id1) + compareErrNil(t, err) + + compareFSMInstanceNotNil(t, testFSMInstance1) + + compareState(t, spf.StateParticipantsConfirmationsInit, testFSMInstance1.machine.State()) + + testFSMDump1, err := testFSMInstance1.Dump() + + compareErrNil(t, err) + + compareDumpNotZero(t, testFSMDump1) + + /// fsm2 + testFSMInstance2, err := Create(id2) + compareErrNil(t, err) + + compareFSMInstanceNotNil(t, testFSMInstance2) + + compareState(t, spf.StateParticipantsConfirmationsInit, testFSMInstance2.machine.State()) + + testFSMDump2, err := testFSMInstance2.Dump() + + compareErrNil(t, err) + + compareDumpNotZero(t, testFSMDump2) + + testFSMInstance1, err = FromDump(testFSMDump1) + + compareErrNil(t, err) + + testFSMInstance2, err = FromDump(testFSMDump2) + + compareErrNil(t, err) + + _, _, err = testFSMInstance1.Do(spf.EventInitProposal, testParticipantsListRequest) + + s1, err := testFSMInstance1.State() + + compareErrNil(t, err) + + s2, err := testFSMInstance2.State() + + if s1 == s2 { + t.Fatalf("MATCH STATES {%s}", s1) + } } diff --git a/fsm/state_machines/signature_proposal_fsm/init.go b/fsm/state_machines/signature_proposal_fsm/init.go index ed8b7d5..11a2509 100644 --- a/fsm/state_machines/signature_proposal_fsm/init.go +++ b/fsm/state_machines/signature_proposal_fsm/init.go @@ -82,9 +82,11 @@ func New() internal.DumpedMachineProvider { return machine } -func (m *SignatureProposalFSM) SetUpPayload(payload *internal.DumpedMachineStatePayload) { +func (m *SignatureProposalFSM) WithSetup(state fsm.State, payload *internal.DumpedMachineStatePayload) internal.DumpedMachineProvider { m.payloadMu.Lock() defer m.payloadMu.Unlock() m.payload = payload + m.FSM = m.FSM.CopyWithState(state) + return m } diff --git a/fsm/state_machines/signing_proposal_fsm/init.go b/fsm/state_machines/signing_proposal_fsm/init.go index f9dde50..9f1b8d7 100644 --- a/fsm/state_machines/signing_proposal_fsm/init.go +++ b/fsm/state_machines/signing_proposal_fsm/init.go @@ -105,9 +105,11 @@ func New() internal.DumpedMachineProvider { return machine } -func (m *SigningProposalFSM) SetUpPayload(payload *internal.DumpedMachineStatePayload) { +func (m *SigningProposalFSM) WithSetup(state fsm.State, payload *internal.DumpedMachineStatePayload) internal.DumpedMachineProvider { m.payloadMu.Lock() defer m.payloadMu.Unlock() m.payload = payload + m.FSM = m.FSM.CopyWithState(state) + return m }