mirror of https://github.com/certusone/dc4bc.git
1200 lines
33 KiB
Go
1200 lines
33 KiB
Go
package state_machines
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"errors"
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
sif "github.com/lidofinance/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
|
|
|
"github.com/lidofinance/dc4bc/fsm/fsm"
|
|
dpf "github.com/lidofinance/dc4bc/fsm/state_machines/dkg_proposal_fsm"
|
|
spf "github.com/lidofinance/dc4bc/fsm/state_machines/signature_proposal_fsm"
|
|
"github.com/lidofinance/dc4bc/fsm/types/requests"
|
|
"github.com/lidofinance/dc4bc/fsm/types/responses"
|
|
)
|
|
|
|
const (
|
|
usernameMockLen = 32
|
|
keysMockLen = 128
|
|
)
|
|
|
|
type testParticipantsPayload struct {
|
|
Username string
|
|
HotPrivKey ed25519.PrivateKey
|
|
HotPubKey ed25519.PublicKey
|
|
DkgPubKey []byte
|
|
DkgCommit []byte
|
|
DkgDeal []byte
|
|
DkgResponse []byte
|
|
DkgPartialKey []byte
|
|
}
|
|
|
|
var (
|
|
tm = time.Now()
|
|
|
|
dkgId = "1b7a6382afe0fbe2ff127a5779f5e9b042e685cabefeadcf4ef27c6089a56bfb"
|
|
|
|
// map {username} -> {participant}
|
|
testUsernameMapParticipants = map[string]*testParticipantsPayload{}
|
|
// map {dkg_queue_id} -> {participant}
|
|
testIdMapParticipants = map[int]*testParticipantsPayload{}
|
|
|
|
testParticipantsListRequest = requests.SignatureProposalParticipantsListRequest{
|
|
Participants: []*requests.SignatureProposalParticipantsEntry{},
|
|
CreatedAt: tm,
|
|
}
|
|
|
|
testSigningId string
|
|
testSigningInitiator int
|
|
testSigningPayload = []byte("message to sign")
|
|
|
|
testFSMDump = map[fsm.State][]byte{}
|
|
)
|
|
|
|
func init() {
|
|
for i := 0; i < 3; i++ {
|
|
|
|
participant := &testParticipantsPayload{
|
|
Username: base64.StdEncoding.EncodeToString(genDataMock(usernameMockLen)),
|
|
HotPrivKey: genDataMock(keysMockLen),
|
|
HotPubKey: genDataMock(keysMockLen),
|
|
DkgPubKey: genDataMock(keysMockLen),
|
|
DkgCommit: genDataMock(keysMockLen),
|
|
DkgDeal: genDataMock(keysMockLen),
|
|
DkgResponse: genDataMock(keysMockLen),
|
|
DkgPartialKey: genDataMock(keysMockLen),
|
|
}
|
|
testUsernameMapParticipants[participant.Username] = participant
|
|
}
|
|
}
|
|
|
|
func TestCreate_Positive(t *testing.T) {
|
|
testFSMInstance, err := Create(dkgId)
|
|
if err != nil {
|
|
t.Fatalf("expected nil error, got {%s}", err)
|
|
}
|
|
|
|
if testFSMInstance == nil {
|
|
t.Fatalf("expected {*FSMInstance}")
|
|
}
|
|
}
|
|
|
|
func genDataMock(len int) []byte {
|
|
data := make([]byte, len)
|
|
rand.Read(data)
|
|
return data
|
|
}
|
|
|
|
func compareErrNil(t *testing.T, got error) {
|
|
if got != nil {
|
|
t.Fatalf("expected nil error, got {%s}", got)
|
|
}
|
|
}
|
|
|
|
func compareFSMInstanceNotNil(t *testing.T, got *FSMInstance) {
|
|
if got == nil {
|
|
t.Fatalf("expected {*FSMInstance}")
|
|
}
|
|
}
|
|
|
|
func compareDumpNotZero(t *testing.T, got []byte) {
|
|
if len(got) == 0 {
|
|
t.Fatalf("expected non zero dump, when executed without error")
|
|
}
|
|
}
|
|
|
|
func compareFSMResponseNotNil(t *testing.T, got *fsm.Response) {
|
|
if got == nil {
|
|
t.Fatalf("expected {*fsm.FSMResponse} got nil")
|
|
}
|
|
}
|
|
|
|
func compareState(t *testing.T, expected fsm.State, got fsm.State) {
|
|
if got != expected {
|
|
t.Fatalf("expected state {%s} got {%s}", expected, got)
|
|
}
|
|
}
|
|
|
|
// Test Workflow
|
|
func Test_SignatureProposal_Init(t *testing.T) {
|
|
testFSMInstance, err := Create(dkgId)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
transactionId := testFSMInstance.Id()
|
|
|
|
if transactionId == "" {
|
|
t.Fatalf("expected {transactionId for dump}")
|
|
}
|
|
|
|
if testFSMInstance.machine.Name() != spf.FsmName {
|
|
t.Fatalf("expected machine name {%s}", spf.FsmName)
|
|
}
|
|
compareState(t, spf.StateParticipantsConfirmationsInit, testFSMInstance.machine.State())
|
|
|
|
testFSMDump[spf.StateParticipantsConfirmationsInit], err = testFSMInstance.Dump()
|
|
require.NoError(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDump[spf.StateParticipantsConfirmationsInit])
|
|
}
|
|
|
|
// EventInitProposal
|
|
func Test_SignatureProposal_EventInitProposal_Positive(t *testing.T) {
|
|
var fsmResponse *fsm.Response
|
|
|
|
testFSMInstance, err := FromDump(testFSMDump[spf.StateParticipantsConfirmationsInit])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
compareState(t, spf.StateParticipantsConfirmationsInit, testFSMInstance.machine.State())
|
|
|
|
// Make request
|
|
request := make([]*requests.SignatureProposalParticipantsEntry, 0)
|
|
|
|
for _, participant := range testUsernameMapParticipants {
|
|
|
|
request = append(request, &requests.SignatureProposalParticipantsEntry{
|
|
Username: participant.Username,
|
|
PubKey: participant.HotPubKey,
|
|
DkgPubKey: participant.DkgPubKey,
|
|
})
|
|
}
|
|
testParticipantsListRequest.Participants = request
|
|
testParticipantsListRequest.SigningThreshold = len(request)
|
|
|
|
fsmResponse, testFSMDump[spf.StateAwaitParticipantsConfirmations], err = testFSMInstance.Do(spf.EventInitProposal, testParticipantsListRequest)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, spf.StateAwaitParticipantsConfirmations, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.SignatureProposalParticipantInvitationsResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {SignatureProposalParticipantInvitationsResponse}")
|
|
}
|
|
|
|
if len(response) != len(testParticipantsListRequest.Participants) {
|
|
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response))
|
|
}
|
|
|
|
for _, participant := range response {
|
|
if _, ok := testIdMapParticipants[participant.ParticipantId]; ok {
|
|
t.Fatalf("expected unique {ParticipantId}")
|
|
}
|
|
|
|
if participant.Username == "" {
|
|
t.Fatalf("expected not empty {Username}")
|
|
}
|
|
|
|
participantEntry, ok := testUsernameMapParticipants[participant.Username]
|
|
|
|
if !ok {
|
|
t.Fatalf("expected exist {Username}")
|
|
}
|
|
|
|
testIdMapParticipants[participant.ParticipantId] = participantEntry
|
|
}
|
|
|
|
compareDumpNotZero(t, testFSMDump[spf.StateAwaitParticipantsConfirmations])
|
|
}
|
|
|
|
// EventConfirmSignatureProposal
|
|
func Test_SignatureProposal_EventConfirmSignatureProposal_Positive(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
participantsCount := len(testIdMapParticipants)
|
|
|
|
participantCounter := participantsCount
|
|
|
|
// testFSMDumpLocal = make([]b)
|
|
testFSMDumpLocal = testFSMDump[spf.StateAwaitParticipantsConfirmations]
|
|
|
|
for participantId := range testIdMapParticipants {
|
|
participantCounter--
|
|
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, spf.StateAwaitParticipantsConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(spf.EventConfirmSignatureProposal, requests.SignatureProposalParticipantRequest{
|
|
ParticipantId: participantId,
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
if participantCounter > 0 {
|
|
compareState(t, spf.StateAwaitParticipantsConfirmations, fsmResponse.State)
|
|
}
|
|
|
|
}
|
|
|
|
compareState(t, spf.StateSignatureProposalCollected, fsmResponse.State)
|
|
|
|
testFSMDump[spf.StateSignatureProposalCollected] = testFSMDumpLocal
|
|
|
|
compareDumpNotZero(t, testFSMDump[spf.StateSignatureProposalCollected])
|
|
}
|
|
|
|
func Test_SignatureProposal_EventConfirmSignatureProposal_Canceled_Participant(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[spf.StateAwaitParticipantsConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, spf.StateAwaitParticipantsConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(spf.EventDeclineProposal, requests.SignatureProposalParticipantRequest{
|
|
ParticipantId: 0,
|
|
CreatedAt: time.Now(),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, spf.StateValidationCanceledByParticipant, fsmResponse.State)
|
|
}
|
|
|
|
func Test_SignatureProposal_EventConfirmSignatureProposal_Canceled_Timeout(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[spf.StateAwaitParticipantsConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, spf.StateAwaitParticipantsConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(spf.EventConfirmSignatureProposal, requests.SignatureProposalParticipantRequest{
|
|
ParticipantId: 0,
|
|
CreatedAt: time.Now().Add(36 * time.Hour),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, spf.StateValidationCanceledByTimeout, fsmResponse.State)
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGInitProcess_Positive(t *testing.T) {
|
|
var fsmResponse *fsm.Response
|
|
|
|
testFSMInstance, err := FromDump(testFSMDump[spf.StateSignatureProposalCollected])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, spf.StateSignatureProposalCollected, inState)
|
|
|
|
fsmResponse, testFSMDump[dpf.StateDkgCommitsAwaitConfirmations], err = testFSMInstance.Do(dpf.EventDKGInitProcess, requests.DefaultRequest{
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, dpf.StateDkgCommitsAwaitConfirmations, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.DKGProposalPubKeysParticipantResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {DKGProposalPubKeysParticipantResponse}")
|
|
}
|
|
|
|
if len(response) != len(testParticipantsListRequest.Participants) {
|
|
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response))
|
|
}
|
|
|
|
for _, responseEntry := range response {
|
|
if _, ok := testIdMapParticipants[responseEntry.ParticipantId]; !ok {
|
|
t.Fatalf("expected exist {ParticipantId}")
|
|
}
|
|
|
|
if len(responseEntry.DkgPubKey) == 0 {
|
|
t.Fatalf("expected {DkgPubKey} non zero length")
|
|
}
|
|
|
|
if !reflect.DeepEqual(testIdMapParticipants[responseEntry.ParticipantId].DkgPubKey, responseEntry.DkgPubKey) {
|
|
t.Fatalf("expected valid {DkgPubKey}")
|
|
}
|
|
}
|
|
|
|
compareDumpNotZero(t, testFSMDump[dpf.StateDkgCommitsAwaitConfirmations])
|
|
}
|
|
|
|
// Commits
|
|
func Test_DkgProposal_EventDKGCommitConfirmationReceived(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
testFSMDumpLocal = testFSMDump[dpf.StateDkgCommitsAwaitConfirmations]
|
|
|
|
for participantId, participant := range testIdMapParticipants {
|
|
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgCommitsAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(dpf.EventDKGCommitConfirmationReceived, requests.DKGProposalCommitConfirmationRequest{
|
|
ParticipantId: participantId,
|
|
Commit: participant.DkgCommit,
|
|
CreatedAt: tm,
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
}
|
|
|
|
compareState(t, dpf.StateDkgDealsAwaitConfirmations, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.DKGProposalCommitParticipantResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {DKGProposalCommitParticipantResponse}")
|
|
}
|
|
|
|
if len(response) != len(testParticipantsListRequest.Participants) {
|
|
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response))
|
|
}
|
|
|
|
for _, responseEntry := range response {
|
|
if _, ok := testIdMapParticipants[responseEntry.ParticipantId]; !ok {
|
|
t.Fatalf("expected exist {ParticipantId}")
|
|
}
|
|
|
|
if responseEntry.Username == "" {
|
|
t.Fatalf("expected {Username} non zero length")
|
|
}
|
|
|
|
if len(responseEntry.DkgCommit) == 0 {
|
|
t.Fatalf("expected {DkgCommit} non zero length")
|
|
}
|
|
|
|
if !reflect.DeepEqual(testIdMapParticipants[responseEntry.ParticipantId].DkgCommit, responseEntry.DkgCommit) {
|
|
t.Fatalf("expected valid {DkgCommit}")
|
|
}
|
|
}
|
|
|
|
testFSMDump[dpf.StateDkgDealsAwaitConfirmations] = testFSMDumpLocal
|
|
|
|
compareDumpNotZero(t, testFSMDump[dpf.StateDkgDealsAwaitConfirmations])
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGCommitConfirmationReceived_Canceled_Error(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgCommitsAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgCommitsAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGCommitConfirmationError, requests.DKGProposalConfirmationErrorRequest{
|
|
ParticipantId: 0,
|
|
Error: errors.New("test error"),
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgCommitsAwaitCanceledByError, fsmResponse.State)
|
|
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGCommitConfirmationReceived_Canceled_Timeout(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgCommitsAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgCommitsAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGCommitConfirmationReceived, requests.DKGProposalCommitConfirmationRequest{
|
|
ParticipantId: 0,
|
|
Commit: testIdMapParticipants[0].DkgCommit,
|
|
CreatedAt: time.Now().Add(36 * time.Hour),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgCommitsAwaitCanceledByTimeout, fsmResponse.State)
|
|
|
|
}
|
|
|
|
// Deals
|
|
func Test_DkgProposal_EventDKGDealConfirmationReceived(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
testFSMDumpLocal = testFSMDump[dpf.StateDkgDealsAwaitConfirmations]
|
|
|
|
for participantId, participant := range testIdMapParticipants {
|
|
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgDealsAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(dpf.EventDKGDealConfirmationReceived, requests.DKGProposalDealConfirmationRequest{
|
|
ParticipantId: participantId,
|
|
Deal: participant.DkgDeal,
|
|
CreatedAt: tm,
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
// Deals reached, next stage
|
|
if fsmResponse.State == dpf.StateDkgResponsesAwaitConfirmations {
|
|
break
|
|
}
|
|
}
|
|
|
|
compareState(t, dpf.StateDkgResponsesAwaitConfirmations, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.DKGProposalDealParticipantResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {DKGProposalDealParticipantResponse}")
|
|
}
|
|
|
|
// Deals count less than total users count by 1 unit
|
|
if len(response) != len(testParticipantsListRequest.Participants)-1 {
|
|
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response)-1)
|
|
}
|
|
|
|
for _, responseEntry := range response {
|
|
if _, ok := testIdMapParticipants[responseEntry.ParticipantId]; !ok {
|
|
t.Fatalf("expected exist {ParticipantId}")
|
|
}
|
|
|
|
if responseEntry.Username == "" {
|
|
t.Fatalf("expected {Username} non zero length")
|
|
}
|
|
|
|
if len(responseEntry.DkgDeal) == 0 {
|
|
t.Fatalf("expected {DkgDeal} non zero length")
|
|
}
|
|
|
|
if !reflect.DeepEqual(testIdMapParticipants[responseEntry.ParticipantId].DkgDeal, responseEntry.DkgDeal) {
|
|
t.Fatalf("expected valid {DkgDeal}")
|
|
}
|
|
}
|
|
|
|
testFSMDump[dpf.StateDkgResponsesAwaitConfirmations] = testFSMDumpLocal
|
|
|
|
compareDumpNotZero(t, testFSMDump[dpf.StateDkgResponsesAwaitConfirmations])
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGDealConfirmationReceived_Canceled_Error(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgDealsAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgDealsAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGDealConfirmationError, requests.DKGProposalConfirmationErrorRequest{
|
|
ParticipantId: 0,
|
|
Error: errors.New("test error"),
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgDealsAwaitCanceledByError, fsmResponse.State)
|
|
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGDealConfirmationReceived_Canceled_Timeout(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgDealsAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgDealsAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGDealConfirmationReceived, requests.DKGProposalDealConfirmationRequest{
|
|
ParticipantId: 0,
|
|
Deal: testIdMapParticipants[0].DkgDeal,
|
|
CreatedAt: time.Now().Add(36 * time.Hour),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgDealsAwaitCanceledByTimeout, fsmResponse.State)
|
|
|
|
}
|
|
|
|
// Responses
|
|
func Test_DkgProposal_EventDKGResponseConfirmationReceived_Positive(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
testFSMDumpLocal = testFSMDump[dpf.StateDkgResponsesAwaitConfirmations]
|
|
|
|
for participantId, participant := range testIdMapParticipants {
|
|
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgResponsesAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(dpf.EventDKGResponseConfirmationReceived, requests.DKGProposalResponseConfirmationRequest{
|
|
ParticipantId: participantId,
|
|
Response: participant.DkgResponse,
|
|
CreatedAt: tm,
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
}
|
|
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitConfirmations, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.DKGProposalResponseParticipantResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {DKGProposalResponseParticipantResponse}")
|
|
}
|
|
|
|
if len(response) != len(testParticipantsListRequest.Participants) {
|
|
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response))
|
|
}
|
|
|
|
for _, responseEntry := range response {
|
|
if _, ok := testIdMapParticipants[responseEntry.ParticipantId]; !ok {
|
|
t.Fatalf("expected exist {ParticipantId}")
|
|
}
|
|
|
|
if responseEntry.Username == "" {
|
|
t.Fatalf("expected {Username} non zero length")
|
|
}
|
|
|
|
if len(responseEntry.DkgResponse) == 0 {
|
|
t.Fatalf("expected {DkgResponse} non zero length")
|
|
}
|
|
|
|
if !reflect.DeepEqual(testIdMapParticipants[responseEntry.ParticipantId].DkgResponse, responseEntry.DkgResponse) {
|
|
t.Fatalf("expected valid {DkgResponse}")
|
|
}
|
|
}
|
|
|
|
testFSMDump[dpf.StateDkgMasterKeyAwaitConfirmations] = testFSMDumpLocal
|
|
|
|
compareDumpNotZero(t, testFSMDump[dpf.StateDkgMasterKeyAwaitConfirmations])
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGResponseConfirmationError_Canceled_Error(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgResponsesAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgResponsesAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGResponseConfirmationError, requests.DKGProposalConfirmationErrorRequest{
|
|
ParticipantId: 0,
|
|
Error: errors.New("test error"),
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgResponsesAwaitCanceledByError, fsmResponse.State)
|
|
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGResponseConfirmationReceived_Canceled_Timeout(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgResponsesAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgResponsesAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGResponseConfirmationReceived, requests.DKGProposalResponseConfirmationRequest{
|
|
ParticipantId: 0,
|
|
Response: testIdMapParticipants[0].DkgResponse,
|
|
CreatedAt: time.Now().Add(36 * time.Hour),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgResponsesAwaitCanceledByTimeout, fsmResponse.State)
|
|
|
|
}
|
|
|
|
// Master keys
|
|
func Test_DkgProposal_EventDKGMasterKeyConfirmationReceived_Positive(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
testFSMDumpLocal = testFSMDump[dpf.StateDkgMasterKeyAwaitConfirmations]
|
|
|
|
masterKeyMockup := genDataMock(keysMockLen)
|
|
|
|
for participantId := range testIdMapParticipants {
|
|
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(dpf.EventDKGMasterKeyConfirmationReceived, requests.DKGProposalMasterKeyConfirmationRequest{
|
|
ParticipantId: participantId,
|
|
MasterKey: masterKeyMockup,
|
|
CreatedAt: tm,
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
}
|
|
|
|
compareState(t, dpf.StateDkgMasterKeyCollected, fsmResponse.State)
|
|
|
|
testFSMDump[dpf.StateDkgMasterKeyCollected] = testFSMDumpLocal
|
|
|
|
compareDumpNotZero(t, testFSMDump[dpf.StateDkgMasterKeyCollected])
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGMasterKeyConfirmationError_Canceled_Error(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgMasterKeyAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGMasterKeyConfirmationError, requests.DKGProposalConfirmationErrorRequest{
|
|
ParticipantId: 0,
|
|
Error: errors.New("test error"),
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitCanceledByError, fsmResponse.State)
|
|
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGMasterKeyConfirmationReceived_Canceled_Timeout(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgMasterKeyAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGMasterKeyConfirmationReceived, requests.DKGProposalMasterKeyConfirmationRequest{
|
|
ParticipantId: 0,
|
|
MasterKey: genDataMock(keysMockLen),
|
|
CreatedAt: time.Now().Add(36 * time.Hour),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitCanceledByTimeout, fsmResponse.State)
|
|
|
|
}
|
|
|
|
func Test_DkgProposal_EventDKGMasterKeyConfirmationReceived_Canceled_Mismatched(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgMasterKeyAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(dpf.EventDKGMasterKeyConfirmationReceived, requests.DKGProposalMasterKeyConfirmationRequest{
|
|
ParticipantId: 0,
|
|
MasterKey: genDataMock(keysMockLen),
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(dpf.EventDKGMasterKeyConfirmationReceived, requests.DKGProposalMasterKeyConfirmationRequest{
|
|
ParticipantId: 1,
|
|
MasterKey: genDataMock(keysMockLen),
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareState(t, dpf.StateDkgMasterKeyAwaitCanceledByError, fsmResponse.State)
|
|
|
|
}
|
|
|
|
// Signing
|
|
func Test_SigningProposal_EventSigningInit(t *testing.T) {
|
|
var fsmResponse *fsm.Response
|
|
|
|
testFSMInstance, err := FromDump(testFSMDump[dpf.StateDkgMasterKeyCollected])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, dpf.StateDkgMasterKeyCollected, inState)
|
|
|
|
fsmResponse, testFSMDump[sif.StateSigningIdle], err = testFSMInstance.Do(sif.EventSigningInit, requests.DefaultRequest{
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, sif.StateSigningIdle, fsmResponse.State)
|
|
|
|
compareDumpNotZero(t, testFSMDump[sif.StateSigningIdle])
|
|
|
|
}
|
|
|
|
// Start
|
|
func Test_SigningProposal_EventSigningStart(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
)
|
|
|
|
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningIdle])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, sif.StateSigningIdle, inState)
|
|
|
|
fsmResponse, testFSMDump[sif.StateSigningAwaitConfirmations], err = testFSMInstance.Do(sif.EventSigningStart, requests.SigningProposalStartRequest{
|
|
SigningID: "test-signing-id",
|
|
ParticipantId: 1,
|
|
SrcPayload: []byte("message to sign"),
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, sif.StateSigningAwaitConfirmations, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.SigningProposalParticipantInvitationsResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {SigningProposalParticipantInvitationsResponse}")
|
|
}
|
|
|
|
if len(response.Participants) != len(testParticipantsListRequest.Participants) {
|
|
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response.Participants))
|
|
}
|
|
|
|
if response.SigningId == "" {
|
|
t.Fatalf("expected field {SigningId}")
|
|
}
|
|
|
|
if !reflect.DeepEqual(response.SrcPayload, testSigningPayload) {
|
|
t.Fatalf("expected matched {SrcPayload}")
|
|
}
|
|
|
|
testSigningId = response.SigningId
|
|
testSigningInitiator = response.InitiatorId
|
|
|
|
compareDumpNotZero(t, testFSMDump[sif.StateSigningAwaitConfirmations])
|
|
}
|
|
|
|
func Test_SigningProposal_EventConfirmSigningConfirmation_Positive(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
participantsCount := len(testIdMapParticipants)
|
|
|
|
participantCounter := participantsCount
|
|
|
|
testFSMDumpLocal = testFSMDump[sif.StateSigningAwaitConfirmations]
|
|
|
|
for participantId := range testIdMapParticipants {
|
|
participantCounter--
|
|
|
|
if testSigningInitiator == participantId {
|
|
continue
|
|
}
|
|
|
|
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, sif.StateSigningAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventConfirmSigningConfirmation, requests.SigningProposalParticipantRequest{
|
|
SigningId: testSigningId,
|
|
ParticipantId: participantId,
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
if participantCounter-1 > 0 {
|
|
compareState(t, sif.StateSigningAwaitConfirmations, fsmResponse.State)
|
|
}
|
|
|
|
}
|
|
|
|
compareState(t, sif.StateSigningAwaitPartialSigns, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.SigningPartialSignsParticipantInvitationsResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {SigningProposalParticipantInvitationsResponse}")
|
|
}
|
|
|
|
if response.SigningId == "" {
|
|
t.Fatalf("expected field {SigningId}")
|
|
}
|
|
|
|
if !reflect.DeepEqual(response.SrcPayload, testSigningPayload) {
|
|
t.Fatalf("expected matched {SrcPayload}")
|
|
}
|
|
|
|
testFSMDump[sif.StateSigningAwaitPartialSigns] = testFSMDumpLocal
|
|
|
|
compareDumpNotZero(t, testFSMDump[sif.StateSigningAwaitPartialSigns])
|
|
}
|
|
|
|
func Test_SigningProposal_EventDeclineProposal_Canceled_Participant(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, sif.StateSigningAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(sif.EventDeclineSigningConfirmation, requests.SigningProposalParticipantRequest{
|
|
SigningId: testSigningId,
|
|
ParticipantId: 0,
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, sif.StateSigningConfirmationsAwaitCancelledByParticipant, fsmResponse.State)
|
|
}
|
|
|
|
func Test_SigningProposal_EventConfirmSignatureProposal_Canceled_Timeout(t *testing.T) {
|
|
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningAwaitConfirmations])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, sif.StateSigningAwaitConfirmations, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err := testFSMInstance.Do(sif.EventConfirmSigningConfirmation, requests.SigningProposalParticipantRequest{
|
|
SigningId: testSigningId,
|
|
ParticipantId: 0,
|
|
CreatedAt: time.Now().Add(36 * time.Hour),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, sif.StateSigningConfirmationsAwaitCancelledByTimeout, fsmResponse.State)
|
|
}
|
|
|
|
func Test_SigningProposal_EventSigningPartialKeyReceived_Positive(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
participantsCount := len(testIdMapParticipants)
|
|
|
|
participantCounter := participantsCount
|
|
|
|
testFSMDumpLocal = testFSMDump[sif.StateSigningAwaitPartialSigns]
|
|
|
|
for participantId, participant := range testIdMapParticipants {
|
|
participantCounter--
|
|
|
|
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, sif.StateSigningAwaitPartialSigns, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventSigningPartialSignReceived, requests.SigningProposalPartialSignRequest{
|
|
SigningId: testSigningId,
|
|
ParticipantId: participantId,
|
|
PartialSign: participant.DkgPartialKey,
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
if participantCounter > 0 {
|
|
compareState(t, sif.StateSigningAwaitPartialSigns, fsmResponse.State)
|
|
}
|
|
|
|
}
|
|
|
|
compareState(t, sif.StateSigningPartialSignsCollected, fsmResponse.State)
|
|
|
|
response, ok := fsmResponse.Data.(responses.SigningProcessParticipantResponse)
|
|
|
|
if !ok {
|
|
t.Fatalf("expected response {SigningProcessParticipantResponse}")
|
|
}
|
|
|
|
if response.SigningId == "" {
|
|
t.Fatalf("expected field {SigningId}")
|
|
}
|
|
|
|
if !reflect.DeepEqual(response.SrcPayload, testSigningPayload) {
|
|
t.Fatalf("expected matched {SrcPayload}")
|
|
}
|
|
|
|
testFSMDump[sif.StateSigningPartialSignsCollected] = testFSMDumpLocal
|
|
|
|
compareDumpNotZero(t, testFSMDump[sif.StateSigningPartialSignsCollected])
|
|
}
|
|
|
|
func Test_DkgProposal_EventSigningRestart_Positive(t *testing.T) {
|
|
var (
|
|
fsmResponse *fsm.Response
|
|
testFSMDumpLocal []byte
|
|
)
|
|
|
|
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningPartialSignsCollected])
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
|
|
|
inState, _ := testFSMInstance.State()
|
|
compareState(t, sif.StateSigningPartialSignsCollected, inState)
|
|
|
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventSigningRestart, requests.DefaultRequest{
|
|
CreatedAt: time.Now(),
|
|
})
|
|
|
|
compareErrNil(t, err)
|
|
|
|
compareFSMResponseNotNil(t, fsmResponse)
|
|
|
|
compareState(t, sif.StateSigningIdle, fsmResponse.State)
|
|
|
|
compareDumpNotZero(t, testFSMDumpLocal)
|
|
}
|
|
|
|
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)
|
|
require.NoError(t, err)
|
|
|
|
s1, err := testFSMInstance1.State()
|
|
|
|
compareErrNil(t, err)
|
|
|
|
s2, err := testFSMInstance2.State()
|
|
require.NoError(t, err)
|
|
|
|
if s1 == s2 {
|
|
t.Fatalf("MATCH STATES {%s}", s1)
|
|
}
|
|
|
|
}
|