mirror of https://github.com/certusone/dc4bc.git
Merge branch 'master' into feat/bls12-381
# Conflicts: # airgapped/bls.go
This commit is contained in:
commit
82faa71d5e
|
@ -195,9 +195,9 @@ func (am *AirgappedMachine) HandleOperation(operation client.Operation) (client.
|
||||||
err = am.handleStateDkgMasterKeyAwaitConfirmations(&operation)
|
err = am.handleStateDkgMasterKeyAwaitConfirmations(&operation)
|
||||||
case signing_proposal_fsm.StateSigningAwaitConfirmations:
|
case signing_proposal_fsm.StateSigningAwaitConfirmations:
|
||||||
err = am.handleStateSigningAwaitConfirmations(&operation)
|
err = am.handleStateSigningAwaitConfirmations(&operation)
|
||||||
case signing_proposal_fsm.StateSigningAwaitPartialKeys:
|
case signing_proposal_fsm.StateSigningAwaitPartialSigns:
|
||||||
err = am.handleStateSigningAwaitPartialSigns(&operation)
|
err = am.handleStateSigningAwaitPartialSigns(&operation)
|
||||||
case signing_proposal_fsm.StateSigningPartialKeysCollected:
|
case signing_proposal_fsm.StateSigningPartialSignsCollected:
|
||||||
err = am.reconstructThresholdSignature(&operation)
|
err = am.reconstructThresholdSignature(&operation)
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("invalid operation type: %s", operation.Type)
|
err = fmt.Errorf("invalid operation type: %s", operation.Type)
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
client "github.com/depools/dc4bc/client/types"
|
client "github.com/depools/dc4bc/client/types"
|
||||||
"github.com/depools/dc4bc/fsm/fsm"
|
"github.com/depools/dc4bc/fsm/fsm"
|
||||||
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
|
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
|
||||||
|
"github.com/depools/dc4bc/fsm/state_machines/signature_proposal_fsm"
|
||||||
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
||||||
"github.com/depools/dc4bc/fsm/types/requests"
|
"github.com/depools/dc4bc/fsm/types/requests"
|
||||||
"github.com/depools/dc4bc/fsm/types/responses"
|
"github.com/depools/dc4bc/fsm/types/responses"
|
||||||
|
@ -100,6 +101,7 @@ func createOperation(t *testing.T, opType string, to string, req interface{}) cl
|
||||||
|
|
||||||
func TestAirgappedAllSteps(t *testing.T) {
|
func TestAirgappedAllSteps(t *testing.T) {
|
||||||
nodesCount := 10
|
nodesCount := 10
|
||||||
|
threshold := 3
|
||||||
participants := make([]string, nodesCount)
|
participants := make([]string, nodesCount)
|
||||||
for i := 0; i < nodesCount; i++ {
|
for i := 0; i < nodesCount; i++ {
|
||||||
participants[i] = fmt.Sprintf("Participant#%d", i)
|
participants[i] = fmt.Sprintf("Participant#%d", i)
|
||||||
|
@ -111,6 +113,7 @@ func TestAirgappedAllSteps(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create airgapped machine: %v", err)
|
t.Fatalf("failed to create airgapped machine: %v", err)
|
||||||
}
|
}
|
||||||
|
am.SetAddress(participants[i])
|
||||||
node := Node{
|
node := Node{
|
||||||
ParticipantID: i,
|
ParticipantID: i,
|
||||||
Participant: participants[i],
|
Participant: participants[i],
|
||||||
|
@ -119,6 +122,25 @@ func TestAirgappedAllSteps(t *testing.T) {
|
||||||
tr.nodes = append(tr.nodes, &node)
|
tr.nodes = append(tr.nodes, &node)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var initReq responses.SignatureProposalParticipantInvitationsResponse
|
||||||
|
for _, n := range tr.nodes {
|
||||||
|
entry := &responses.SignatureProposalParticipantInvitationEntry{
|
||||||
|
ParticipantId: n.ParticipantID,
|
||||||
|
Addr: n.Participant,
|
||||||
|
Threshold: threshold,
|
||||||
|
}
|
||||||
|
initReq = append(initReq, entry)
|
||||||
|
}
|
||||||
|
op := createOperation(t, string(signature_proposal_fsm.StateAwaitParticipantsConfirmations), "", initReq)
|
||||||
|
runStep(tr, func(n *Node, wg *sync.WaitGroup) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
_, err := n.Machine.HandleOperation(op)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// get commits
|
// get commits
|
||||||
var getCommitsRequest responses.DKGProposalPubKeysParticipantResponse
|
var getCommitsRequest responses.DKGProposalPubKeysParticipantResponse
|
||||||
for _, n := range tr.nodes {
|
for _, n := range tr.nodes {
|
||||||
|
@ -133,7 +155,7 @@ func TestAirgappedAllSteps(t *testing.T) {
|
||||||
}
|
}
|
||||||
getCommitsRequest = append(getCommitsRequest, entry)
|
getCommitsRequest = append(getCommitsRequest, entry)
|
||||||
}
|
}
|
||||||
op := createOperation(t, string(dkg_proposal_fsm.StateDkgCommitsAwaitConfirmations), "", getCommitsRequest)
|
op = createOperation(t, string(dkg_proposal_fsm.StateDkgCommitsAwaitConfirmations), "", getCommitsRequest)
|
||||||
runStep(tr, func(n *Node, wg *sync.WaitGroup) {
|
runStep(tr, func(n *Node, wg *sync.WaitGroup) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (am *AirgappedMachine) handleStateSigningAwaitPartialSigns(o *client.Operat
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get paricipant id: %w", err)
|
return fmt.Errorf("failed to get paricipant id: %w", err)
|
||||||
}
|
}
|
||||||
req := requests.SigningProposalPartialKeyRequest{
|
req := requests.SigningProposalPartialSignRequest{
|
||||||
SigningId: payload.SigningId,
|
SigningId: payload.SigningId,
|
||||||
ParticipantId: participantID,
|
ParticipantId: participantID,
|
||||||
PartialSign: partialSign,
|
PartialSign: partialSign,
|
||||||
|
@ -73,7 +73,7 @@ func (am *AirgappedMachine) handleStateSigningAwaitPartialSigns(o *client.Operat
|
||||||
return fmt.Errorf("failed to generate fsm request: %w", err)
|
return fmt.Errorf("failed to generate fsm request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
o.Event = signing_proposal_fsm.EventSigningPartialKeyReceived
|
o.Event = signing_proposal_fsm.EventSigningPartialSignReceived
|
||||||
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
|
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,13 @@ func (am *AirgappedMachine) reconstructThresholdSignature(o *client.Operation) e
|
||||||
partialSignatures = append(partialSignatures, participant.PartialSign)
|
partialSignatures = append(partialSignatures, participant.PartialSign)
|
||||||
}
|
}
|
||||||
|
|
||||||
reconstructedSignature, err := am.recoverFullSign(payload.SrcPayload, partialSignatures, o.DKGIdentifier)
|
dkgInstance, ok := am.dkgInstances[o.DKGIdentifier]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("dkg instance with identifier %s does not exist", o.DKGIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
reconstructedSignature, err := am.recoverFullSign(payload.SrcPayload, partialSignatures, dkgInstance.Threshold,
|
||||||
|
dkgInstance.N, o.DKGIdentifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to reconsruct full signature for msg: %w", err)
|
return fmt.Errorf("failed to reconsruct full signature for msg: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -110,13 +116,13 @@ func (am *AirgappedMachine) createPartialSign(msg []byte, dkgIdentifier string)
|
||||||
return tbls.Sign(am.suite.(pairing.Suite), blsKeyring.Share, msg)
|
return tbls.Sign(am.suite.(pairing.Suite), blsKeyring.Share, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AirgappedMachine) recoverFullSign(msg []byte, sigShares [][]byte, dkgIdentifier string) ([]byte, error) {
|
func (am *AirgappedMachine) recoverFullSign(msg []byte, sigShares [][]byte, t, n int, dkgIdentifier string) ([]byte, error) {
|
||||||
blsKeyring, err := am.loadBLSKeyring(dkgIdentifier)
|
blsKeyring, err := am.loadBLSKeyring(dkgIdentifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to load blsKeyring: %w", err)
|
return nil, fmt.Errorf("failed to load blsKeyring: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return tbls.Recover(am.suite.(pairing.Suite), blsKeyring.PubPoly, msg, sigShares, len(sigShares), len(sigShares))
|
return tbls.Recover(am.suite.(pairing.Suite), blsKeyring.PubPoly, msg, sigShares, t, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (am *AirgappedMachine) verifySign(msg []byte, fullSignature []byte, dkgIdentifier string) error {
|
func (am *AirgappedMachine) verifySign(msg []byte, fullSignature []byte, dkgIdentifier string) error {
|
||||||
|
|
|
@ -39,25 +39,26 @@ func (am *AirgappedMachine) handleStateAwaitParticipantsConfirmations(o *client.
|
||||||
return fmt.Errorf("failed to unmarshal payload: %w", err)
|
return fmt.Errorf("failed to unmarshal payload: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := am.dkgInstances[o.DKGIdentifier]; ok {
|
|
||||||
return fmt.Errorf("dkg instance %s already exists", o.DKGIdentifier)
|
|
||||||
}
|
|
||||||
|
|
||||||
dkgInstance := dkg.Init(am.suite, am.pubKey, am.secKey)
|
|
||||||
dkgInstance.Threshold = len(payload)
|
|
||||||
|
|
||||||
am.dkgInstances[o.DKGIdentifier] = dkgInstance
|
|
||||||
|
|
||||||
pid := -1
|
pid := -1
|
||||||
for _, r := range payload {
|
for _, r := range payload {
|
||||||
if r.Addr == am.ParticipantAddress {
|
if r.Addr == am.ParticipantAddress {
|
||||||
pid = r.ParticipantId
|
pid = r.ParticipantId
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if pid < 0 {
|
if pid < 0 {
|
||||||
return fmt.Errorf("failed to determine participant id for DKG with participant address %s", am.ParticipantAddress)
|
return fmt.Errorf("failed to determine participant id for DKG with participant address %s", am.ParticipantAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if _, ok := am.dkgInstances[o.DKGIdentifier]; ok {
|
||||||
|
return fmt.Errorf("dkg instance %s already exists", o.DKGIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
dkgInstance := dkg.Init(am.suite, am.pubKey, am.secKey)
|
||||||
|
dkgInstance.Threshold = payload[0].Threshold //same for everyone
|
||||||
|
dkgInstance.N = len(payload)
|
||||||
|
am.dkgInstances[o.DKGIdentifier] = dkgInstance
|
||||||
|
|
||||||
req := requests.SignatureProposalParticipantRequest{
|
req := requests.SignatureProposalParticipantRequest{
|
||||||
ParticipantId: pid,
|
ParticipantId: pid,
|
||||||
CreatedAt: o.CreatedAt,
|
CreatedAt: o.CreatedAt,
|
||||||
|
@ -84,11 +85,9 @@ func (am *AirgappedMachine) handleStateDkgCommitsAwaitConfirmations(o *client.Op
|
||||||
|
|
||||||
dkgInstance, ok := am.dkgInstances[o.DKGIdentifier]
|
dkgInstance, ok := am.dkgInstances[o.DKGIdentifier]
|
||||||
if !ok {
|
if !ok {
|
||||||
dkgInstance = dkg.Init(am.suite, am.pubKey, am.secKey)
|
return fmt.Errorf("dkg instance with identifier %s does not exist", o.DKGIdentifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
dkgInstance.Threshold = len(payload)
|
|
||||||
|
|
||||||
if err = json.Unmarshal(o.Payload, &payload); err != nil {
|
if err = json.Unmarshal(o.Payload, &payload); err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal payload: %w", err)
|
return fmt.Errorf("failed to unmarshal payload: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,8 +205,8 @@ func (c *Client) ProcessMessage(message storage.Message) error {
|
||||||
dpf.StateDkgDealsAwaitConfirmations,
|
dpf.StateDkgDealsAwaitConfirmations,
|
||||||
dpf.StateDkgResponsesAwaitConfirmations,
|
dpf.StateDkgResponsesAwaitConfirmations,
|
||||||
dpf.StateDkgMasterKeyAwaitConfirmations,
|
dpf.StateDkgMasterKeyAwaitConfirmations,
|
||||||
sipf.StateSigningAwaitPartialKeys,
|
sipf.StateSigningAwaitPartialSigns,
|
||||||
sipf.StateSigningPartialKeysCollected,
|
sipf.StateSigningPartialSignsCollected,
|
||||||
sipf.StateSigningAwaitConfirmations:
|
sipf.StateSigningAwaitConfirmations:
|
||||||
if resp.Data != nil {
|
if resp.Data != nil {
|
||||||
bz, err := json.Marshal(resp.Data)
|
bz, err := json.Marshal(resp.Data)
|
||||||
|
|
|
@ -86,8 +86,8 @@ func FSMRequestFromMessage(message storage.Message) (interface{}, error) {
|
||||||
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
||||||
}
|
}
|
||||||
resolvedValue = req
|
resolvedValue = req
|
||||||
case signing_proposal_fsm.EventSigningPartialKeyReceived:
|
case signing_proposal_fsm.EventSigningPartialSignReceived:
|
||||||
var req requests.SigningProposalPartialKeyRequest
|
var req requests.SigningProposalPartialSignRequest
|
||||||
if err := json.Unmarshal(message.Data, &req); err != nil {
|
if err := json.Unmarshal(message.Data, &req); err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ type DKG struct {
|
||||||
secKey kyber.Scalar
|
secKey kyber.Scalar
|
||||||
suite vss.Suite
|
suite vss.Suite
|
||||||
ParticipantID int
|
ParticipantID int
|
||||||
|
|
||||||
|
N int
|
||||||
Threshold int
|
Threshold int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ type SignatureProposalParticipant struct {
|
||||||
// For validation user confirmation: sign(InvitationSecret, PubKey) => user
|
// For validation user confirmation: sign(InvitationSecret, PubKey) => user
|
||||||
InvitationSecret string
|
InvitationSecret string
|
||||||
Status ConfirmationParticipantStatus
|
Status ConfirmationParticipantStatus
|
||||||
|
Threshold int
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,8 +158,8 @@ const (
|
||||||
SigningAwaitConfirmation SigningParticipantStatus = iota
|
SigningAwaitConfirmation SigningParticipantStatus = iota
|
||||||
SigningConfirmed
|
SigningConfirmed
|
||||||
SigningDeclined
|
SigningDeclined
|
||||||
SigningAwaitPartialKeys
|
SigningAwaitPartialSigns
|
||||||
SigningPartialKeysConfirmed
|
SigningPartialSignsConfirmed
|
||||||
SigningError
|
SigningError
|
||||||
SigningProcess
|
SigningProcess
|
||||||
)
|
)
|
||||||
|
@ -170,10 +171,10 @@ func (s SigningParticipantStatus) String() string {
|
||||||
str = "SigningAwaitConfirmation"
|
str = "SigningAwaitConfirmation"
|
||||||
case SigningConfirmed:
|
case SigningConfirmed:
|
||||||
str = "SigningConfirmed"
|
str = "SigningConfirmed"
|
||||||
case SigningAwaitPartialKeys:
|
case SigningAwaitPartialSigns:
|
||||||
str = "SigningAwaitPartialKeys"
|
str = "SigningAwaitPartialSigns"
|
||||||
case SigningPartialKeysConfirmed:
|
case SigningPartialSignsConfirmed:
|
||||||
str = "SigningPartialKeysConfirmed"
|
str = "SigningPartialSignsConfirmed"
|
||||||
case SigningError:
|
case SigningError:
|
||||||
str = "SigningError"
|
str = "SigningError"
|
||||||
case SigningProcess:
|
case SigningProcess:
|
||||||
|
|
|
@ -975,7 +975,7 @@ func Test_SigningProposal_EventConfirmSigningConfirmation_Positive(t *testing.T)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compareState(t, sif.StateSigningAwaitPartialKeys, fsmResponse.State)
|
compareState(t, sif.StateSigningAwaitPartialSigns, fsmResponse.State)
|
||||||
|
|
||||||
response, ok := fsmResponse.Data.(responses.SigningPartialSignsParticipantInvitationsResponse)
|
response, ok := fsmResponse.Data.(responses.SigningPartialSignsParticipantInvitationsResponse)
|
||||||
|
|
||||||
|
@ -991,9 +991,9 @@ func Test_SigningProposal_EventConfirmSigningConfirmation_Positive(t *testing.T)
|
||||||
t.Fatalf("expected matched {SrcPayload}")
|
t.Fatalf("expected matched {SrcPayload}")
|
||||||
}
|
}
|
||||||
|
|
||||||
testFSMDump[sif.StateSigningAwaitPartialKeys] = testFSMDumpLocal
|
testFSMDump[sif.StateSigningAwaitPartialSigns] = testFSMDumpLocal
|
||||||
|
|
||||||
compareDumpNotZero(t, testFSMDump[sif.StateSigningAwaitPartialKeys])
|
compareDumpNotZero(t, testFSMDump[sif.StateSigningAwaitPartialSigns])
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_SigningProposal_EventDeclineProposal_Canceled_Participant(t *testing.T) {
|
func Test_SigningProposal_EventDeclineProposal_Canceled_Participant(t *testing.T) {
|
||||||
|
@ -1056,7 +1056,7 @@ func Test_SigningProposal_EventSigningPartialKeyReceived_Positive(t *testing.T)
|
||||||
|
|
||||||
participantCounter := participantsCount
|
participantCounter := participantsCount
|
||||||
|
|
||||||
testFSMDumpLocal = testFSMDump[sif.StateSigningAwaitPartialKeys]
|
testFSMDumpLocal = testFSMDump[sif.StateSigningAwaitPartialSigns]
|
||||||
|
|
||||||
for participantId, participant := range testIdMapParticipants {
|
for participantId, participant := range testIdMapParticipants {
|
||||||
participantCounter--
|
participantCounter--
|
||||||
|
@ -1068,9 +1068,9 @@ func Test_SigningProposal_EventSigningPartialKeyReceived_Positive(t *testing.T)
|
||||||
compareFSMInstanceNotNil(t, testFSMInstance)
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
||||||
|
|
||||||
inState, _ := testFSMInstance.State()
|
inState, _ := testFSMInstance.State()
|
||||||
compareState(t, sif.StateSigningAwaitPartialKeys, inState)
|
compareState(t, sif.StateSigningAwaitPartialSigns, inState)
|
||||||
|
|
||||||
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventSigningPartialKeyReceived, requests.SigningProposalPartialKeyRequest{
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventSigningPartialSignReceived, requests.SigningProposalPartialSignRequest{
|
||||||
SigningId: testSigningId,
|
SigningId: testSigningId,
|
||||||
ParticipantId: participantId,
|
ParticipantId: participantId,
|
||||||
PartialSign: participant.DkgPartialKey,
|
PartialSign: participant.DkgPartialKey,
|
||||||
|
@ -1084,12 +1084,12 @@ func Test_SigningProposal_EventSigningPartialKeyReceived_Positive(t *testing.T)
|
||||||
compareFSMResponseNotNil(t, fsmResponse)
|
compareFSMResponseNotNil(t, fsmResponse)
|
||||||
|
|
||||||
if participantCounter > 0 {
|
if participantCounter > 0 {
|
||||||
compareState(t, sif.StateSigningAwaitPartialKeys, fsmResponse.State)
|
compareState(t, sif.StateSigningAwaitPartialSigns, fsmResponse.State)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compareState(t, sif.StateSigningPartialKeysCollected, fsmResponse.State)
|
compareState(t, sif.StateSigningPartialSignsCollected, fsmResponse.State)
|
||||||
|
|
||||||
response, ok := fsmResponse.Data.(responses.SigningProcessParticipantResponse)
|
response, ok := fsmResponse.Data.(responses.SigningProcessParticipantResponse)
|
||||||
|
|
||||||
|
@ -1105,9 +1105,9 @@ func Test_SigningProposal_EventSigningPartialKeyReceived_Positive(t *testing.T)
|
||||||
t.Fatalf("expected matched {SrcPayload}")
|
t.Fatalf("expected matched {SrcPayload}")
|
||||||
}
|
}
|
||||||
|
|
||||||
testFSMDump[sif.StateSigningPartialKeysCollected] = testFSMDumpLocal
|
testFSMDump[sif.StateSigningPartialSignsCollected] = testFSMDumpLocal
|
||||||
|
|
||||||
compareDumpNotZero(t, testFSMDump[sif.StateSigningPartialKeysCollected])
|
compareDumpNotZero(t, testFSMDump[sif.StateSigningPartialSignsCollected])
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test_DkgProposal_EventSigningRestart_Positive(t *testing.T) {
|
func Test_DkgProposal_EventSigningRestart_Positive(t *testing.T) {
|
||||||
|
@ -1116,14 +1116,14 @@ func Test_DkgProposal_EventSigningRestart_Positive(t *testing.T) {
|
||||||
testFSMDumpLocal []byte
|
testFSMDumpLocal []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningPartialKeysCollected])
|
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningPartialSignsCollected])
|
||||||
|
|
||||||
compareErrNil(t, err)
|
compareErrNil(t, err)
|
||||||
|
|
||||||
compareFSMInstanceNotNil(t, testFSMInstance)
|
compareFSMInstanceNotNil(t, testFSMInstance)
|
||||||
|
|
||||||
inState, _ := testFSMInstance.State()
|
inState, _ := testFSMInstance.State()
|
||||||
compareState(t, sif.StateSigningPartialKeysCollected, inState)
|
compareState(t, sif.StateSigningPartialSignsCollected, inState)
|
||||||
|
|
||||||
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventSigningRestart, requests.DefaultRequest{
|
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventSigningRestart, requests.DefaultRequest{
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
|
|
|
@ -46,6 +46,7 @@ func (m *SignatureProposalFSM) actionInitSignatureProposal(inEvent fsm.Event, ar
|
||||||
PubKey: participant.PubKey,
|
PubKey: participant.PubKey,
|
||||||
DkgPubKey: participant.DkgPubKey,
|
DkgPubKey: participant.DkgPubKey,
|
||||||
Status: internal.SigConfirmationAwaitConfirmation,
|
Status: internal.SigConfirmationAwaitConfirmation,
|
||||||
|
Threshold: request.SigningThreshold,
|
||||||
UpdatedAt: request.CreatedAt,
|
UpdatedAt: request.CreatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +67,7 @@ func (m *SignatureProposalFSM) actionInitSignatureProposal(inEvent fsm.Event, ar
|
||||||
responseEntry := &responses.SignatureProposalParticipantInvitationEntry{
|
responseEntry := &responses.SignatureProposalParticipantInvitationEntry{
|
||||||
ParticipantId: participantId,
|
ParticipantId: participantId,
|
||||||
Addr: participant.Addr,
|
Addr: participant.Addr,
|
||||||
|
Threshold: participant.Threshold,
|
||||||
}
|
}
|
||||||
responseData = append(responseData, responseEntry)
|
responseData = append(responseData, responseEntry)
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ func (m *SigningProposalFSM) actionValidateSigningProposalConfirmations(inEvent
|
||||||
outEvent = eventSetProposalValidatedInternal
|
outEvent = eventSetProposalValidatedInternal
|
||||||
|
|
||||||
for _, participant := range m.payload.SigningProposalPayload.Quorum {
|
for _, participant := range m.payload.SigningProposalPayload.Quorum {
|
||||||
participant.Status = internal.SigningAwaitPartialKeys
|
participant.Status = internal.SigningAwaitPartialSigns
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make response
|
// Make response
|
||||||
|
@ -203,19 +203,19 @@ func (m *SigningProposalFSM) actionValidateSigningProposalConfirmations(inEvent
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SigningProposalFSM) actionPartialKeyConfirmationReceived(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
func (m *SigningProposalFSM) actionPartialSignConfirmationReceived(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||||
m.payloadMu.Lock()
|
m.payloadMu.Lock()
|
||||||
defer m.payloadMu.Unlock()
|
defer m.payloadMu.Unlock()
|
||||||
|
|
||||||
if len(args) != 1 {
|
if len(args) != 1 {
|
||||||
err = errors.New("{arg0} required {SigningProposalPartialKeyRequest}")
|
err = errors.New("{arg0} required {SigningProposalPartialSignRequest}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
request, ok := args[0].(requests.SigningProposalPartialKeyRequest)
|
request, ok := args[0].(requests.SigningProposalPartialSignRequest)
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
err = errors.New("cannot cast {arg0} to type {SigningProposalPartialKeyRequest}")
|
err = errors.New("cannot cast {arg0} to type {SigningProposalPartialSignRequest}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,14 +230,14 @@ func (m *SigningProposalFSM) actionPartialKeyConfirmationReceived(inEvent fsm.Ev
|
||||||
|
|
||||||
signingProposalParticipant := m.payload.SigningQuorumGet(request.ParticipantId)
|
signingProposalParticipant := m.payload.SigningQuorumGet(request.ParticipantId)
|
||||||
|
|
||||||
if signingProposalParticipant.Status != internal.SigningAwaitPartialKeys {
|
if signingProposalParticipant.Status != internal.SigningAwaitPartialSigns {
|
||||||
err = errors.New(fmt.Sprintf("cannot confirm response with {Status} = {\"%s\"}", signingProposalParticipant.Status))
|
err = errors.New(fmt.Sprintf("cannot confirm response with {Status} = {\"%s\"}", signingProposalParticipant.Status))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
signingProposalParticipant.PartialSign = make([]byte, len(request.PartialSign))
|
signingProposalParticipant.PartialSign = make([]byte, len(request.PartialSign))
|
||||||
copy(signingProposalParticipant.PartialSign, request.PartialSign)
|
copy(signingProposalParticipant.PartialSign, request.PartialSign)
|
||||||
signingProposalParticipant.Status = internal.SigningPartialKeysConfirmed
|
signingProposalParticipant.Status = internal.SigningPartialSignsConfirmed
|
||||||
|
|
||||||
signingProposalParticipant.UpdatedAt = request.CreatedAt
|
signingProposalParticipant.UpdatedAt = request.CreatedAt
|
||||||
m.payload.SignatureProposalPayload.UpdatedAt = request.CreatedAt
|
m.payload.SignatureProposalPayload.UpdatedAt = request.CreatedAt
|
||||||
|
@ -247,7 +247,7 @@ func (m *SigningProposalFSM) actionPartialKeyConfirmationReceived(inEvent fsm.Ev
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *SigningProposalFSM) actionValidateSigningPartialKeyAwaitConfirmations(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
func (m *SigningProposalFSM) actionValidateSigningPartialSignsAwaitConfirmations(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||||
var (
|
var (
|
||||||
isContainsError bool
|
isContainsError bool
|
||||||
)
|
)
|
||||||
|
@ -256,7 +256,7 @@ func (m *SigningProposalFSM) actionValidateSigningPartialKeyAwaitConfirmations(i
|
||||||
defer m.payloadMu.Unlock()
|
defer m.payloadMu.Unlock()
|
||||||
|
|
||||||
if m.payload.SigningProposalPayload.IsExpired() {
|
if m.payload.SigningProposalPayload.IsExpired() {
|
||||||
outEvent = eventSigningPartialKeyCancelByTimeoutInternal
|
outEvent = eventSigningPartialSignsAwaitCancelByTimeoutInternal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,13 +264,13 @@ func (m *SigningProposalFSM) actionValidateSigningPartialKeyAwaitConfirmations(i
|
||||||
for _, participant := range m.payload.SigningProposalPayload.Quorum {
|
for _, participant := range m.payload.SigningProposalPayload.Quorum {
|
||||||
if participant.Status == internal.SigningError {
|
if participant.Status == internal.SigningError {
|
||||||
isContainsError = true
|
isContainsError = true
|
||||||
} else if participant.Status == internal.SigningPartialKeysConfirmed {
|
} else if participant.Status == internal.SigningPartialSignsConfirmed {
|
||||||
unconfirmedParticipants--
|
unconfirmedParticipants--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isContainsError {
|
if isContainsError {
|
||||||
outEvent = eventSigningPartialKeyCancelByErrorInternal
|
outEvent = eventSigningPartialSignsAwaitCancelByErrorInternal
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ func (m *SigningProposalFSM) actionValidateSigningPartialKeyAwaitConfirmations(i
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
outEvent = eventSigningPartialKeysConfirmedInternal
|
outEvent = eventSigningPartialSignsConfirmedInternal
|
||||||
|
|
||||||
for _, participant := range m.payload.SigningProposalPayload.Quorum {
|
for _, participant := range m.payload.SigningProposalPayload.Quorum {
|
||||||
participant.Status = internal.SigningProcess
|
participant.Status = internal.SigningProcess
|
||||||
|
@ -341,11 +341,11 @@ func (m *SigningProposalFSM) actionConfirmationError(inEvent fsm.Event, args ...
|
||||||
|
|
||||||
// TODO: Move to methods
|
// TODO: Move to methods
|
||||||
switch inEvent {
|
switch inEvent {
|
||||||
case EventSigningPartialKeyError:
|
case EventSigningPartialSignError:
|
||||||
switch signingProposalParticipant.Status {
|
switch signingProposalParticipant.Status {
|
||||||
case internal.SigningAwaitPartialKeys:
|
case internal.SigningAwaitPartialSigns:
|
||||||
signingProposalParticipant.Status = internal.SigningError
|
signingProposalParticipant.Status = internal.SigningError
|
||||||
case internal.SigningPartialKeysConfirmed:
|
case internal.SigningPartialSignsConfirmed:
|
||||||
err = errors.New("{Status} already confirmed")
|
err = errors.New("{Status} already confirmed")
|
||||||
case internal.SigningError:
|
case internal.SigningError:
|
||||||
err = errors.New(fmt.Sprintf("{Status} already has {\"%s\"}", internal.SigningError))
|
err = errors.New(fmt.Sprintf("{Status} already has {\"%s\"}", internal.SigningError))
|
||||||
|
|
|
@ -21,12 +21,12 @@ const (
|
||||||
StateSigningConfirmationsAwaitCancelledByTimeout = fsm.State("state_signing_confirmations_await_cancelled_by_timeout")
|
StateSigningConfirmationsAwaitCancelledByTimeout = fsm.State("state_signing_confirmations_await_cancelled_by_timeout")
|
||||||
StateSigningConfirmationsAwaitCancelledByParticipant = fsm.State("state_signing_confirmations_await_cancelled_by_participant")
|
StateSigningConfirmationsAwaitCancelledByParticipant = fsm.State("state_signing_confirmations_await_cancelled_by_participant")
|
||||||
|
|
||||||
StateSigningAwaitPartialKeys = fsm.State("state_signing_await_partial_keys")
|
StateSigningAwaitPartialSigns = fsm.State("state_signing_await_partial_signs")
|
||||||
// Cancelled
|
// Cancelled
|
||||||
StateSigningPartialKeysAwaitCancelledByTimeout = fsm.State("state_signing_partial_signatures_await_cancelled_by_timeout")
|
StateSigningPartialSignsAwaitCancelledByTimeout = fsm.State("state_signing_partial_signs_await_cancelled_by_timeout")
|
||||||
StateSigningPartialKeysAwaitCancelledByError = fsm.State("state_signing_partial_signatures_await_cancelled_by_error")
|
StateSigningPartialSignsAwaitCancelledByError = fsm.State("state_signing_partial_signs_await_cancelled_by_error")
|
||||||
|
|
||||||
StateSigningPartialKeysCollected = fsm.State("state_signing_partial_signatures_collected")
|
StateSigningPartialSignsCollected = fsm.State("state_signing_partial_signs_collected")
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
|
|
||||||
|
@ -40,14 +40,14 @@ const (
|
||||||
eventAutoSigningValidateProposalInternal = fsm.Event("event_signing_proposal_await_validate")
|
eventAutoSigningValidateProposalInternal = fsm.Event("event_signing_proposal_await_validate")
|
||||||
eventSetProposalValidatedInternal = fsm.Event("event_signing_proposal_set_validated")
|
eventSetProposalValidatedInternal = fsm.Event("event_signing_proposal_set_validated")
|
||||||
|
|
||||||
EventSigningPartialKeyReceived = fsm.Event("event_signing_partial_key_received")
|
EventSigningPartialSignReceived = fsm.Event("event_signing_partial_sign_received")
|
||||||
EventSigningPartialKeyError = fsm.Event("event_signing_partial_key_error_received")
|
EventSigningPartialSignError = fsm.Event("event_signing_partial_sign_error_received")
|
||||||
eventSigningPartialKeyCancelByTimeoutInternal = fsm.Event("event_signing_partial_key_canceled_by_timeout_internal")
|
eventSigningPartialSignsAwaitCancelByTimeoutInternal = fsm.Event("event_signing_partial_signs_await_cancel_by_timeout_internal")
|
||||||
eventSigningPartialKeyCancelByErrorInternal = fsm.Event("event_signing_partial_key_canceled_by_error_internal")
|
eventSigningPartialSignsAwaitCancelByErrorInternal = fsm.Event("event_signing_partial_signs_await_sign_cancel_by_error_internal")
|
||||||
|
|
||||||
eventAutoSigningValidatePartialKeyInternal = fsm.Event("event_signing_partial_keys_await_validate")
|
eventAutoSigningValidatePartialSignInternal = fsm.Event("event_signing_partial_signs_await_validate")
|
||||||
|
|
||||||
eventSigningPartialKeysConfirmedInternal = fsm.Event("event_signing_partial_keys_confirmed_internal")
|
eventSigningPartialSignsConfirmedInternal = fsm.Event("event_signing_partial_signs_confirmed_internal")
|
||||||
EventSigningRestart = fsm.Event("event_signing_restart")
|
EventSigningRestart = fsm.Event("event_signing_restart")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -81,20 +81,20 @@ func New() internal.DumpedMachineProvider {
|
||||||
// Validate
|
// Validate
|
||||||
{Name: eventAutoSigningValidateProposalInternal, SrcState: []fsm.State{StateSigningAwaitConfirmations}, DstState: StateSigningAwaitConfirmations, IsInternal: true, IsAuto: true},
|
{Name: eventAutoSigningValidateProposalInternal, SrcState: []fsm.State{StateSigningAwaitConfirmations}, DstState: StateSigningAwaitConfirmations, IsInternal: true, IsAuto: true},
|
||||||
|
|
||||||
{Name: eventSetProposalValidatedInternal, SrcState: []fsm.State{StateSigningAwaitConfirmations}, DstState: StateSigningAwaitPartialKeys, IsInternal: true},
|
{Name: eventSetProposalValidatedInternal, SrcState: []fsm.State{StateSigningAwaitConfirmations}, DstState: StateSigningAwaitPartialSigns, IsInternal: true},
|
||||||
|
|
||||||
// Canceled
|
// Canceled
|
||||||
{Name: EventSigningPartialKeyReceived, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningAwaitPartialKeys},
|
{Name: EventSigningPartialSignReceived, SrcState: []fsm.State{StateSigningAwaitPartialSigns}, DstState: StateSigningAwaitPartialSigns},
|
||||||
{Name: EventSigningPartialKeyError, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByError},
|
{Name: EventSigningPartialSignError, SrcState: []fsm.State{StateSigningAwaitPartialSigns}, DstState: StateSigningPartialSignsAwaitCancelledByError},
|
||||||
{Name: eventSigningPartialKeyCancelByTimeoutInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByTimeout, IsInternal: true},
|
{Name: eventSigningPartialSignsAwaitCancelByTimeoutInternal, SrcState: []fsm.State{StateSigningAwaitPartialSigns}, DstState: StateSigningPartialSignsAwaitCancelledByTimeout, IsInternal: true},
|
||||||
{Name: eventSigningPartialKeyCancelByErrorInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByError, IsInternal: true},
|
{Name: eventSigningPartialSignsAwaitCancelByErrorInternal, SrcState: []fsm.State{StateSigningAwaitPartialSigns}, DstState: StateSigningPartialSignsAwaitCancelledByError, IsInternal: true},
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
{Name: eventAutoSigningValidatePartialKeyInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningAwaitPartialKeys, IsInternal: true, IsAuto: true},
|
{Name: eventAutoSigningValidatePartialSignInternal, SrcState: []fsm.State{StateSigningAwaitPartialSigns}, DstState: StateSigningAwaitPartialSigns, IsInternal: true, IsAuto: true},
|
||||||
|
|
||||||
{Name: eventSigningPartialKeysConfirmedInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysCollected, IsInternal: true},
|
{Name: eventSigningPartialSignsConfirmedInternal, SrcState: []fsm.State{StateSigningAwaitPartialSigns}, DstState: StateSigningPartialSignsCollected, IsInternal: true},
|
||||||
|
|
||||||
{Name: EventSigningRestart, SrcState: []fsm.State{StateSigningPartialKeysCollected}, DstState: StateSigningIdle},
|
{Name: EventSigningRestart, SrcState: []fsm.State{StateSigningPartialSignsCollected}, DstState: StateSigningIdle},
|
||||||
},
|
},
|
||||||
fsm.Callbacks{
|
fsm.Callbacks{
|
||||||
EventSigningInit: machine.actionInitSigningProposal,
|
EventSigningInit: machine.actionInitSigningProposal,
|
||||||
|
@ -102,9 +102,9 @@ func New() internal.DumpedMachineProvider {
|
||||||
EventConfirmSigningConfirmation: machine.actionProposalResponseByParticipant,
|
EventConfirmSigningConfirmation: machine.actionProposalResponseByParticipant,
|
||||||
EventDeclineSigningConfirmation: machine.actionProposalResponseByParticipant,
|
EventDeclineSigningConfirmation: machine.actionProposalResponseByParticipant,
|
||||||
eventAutoSigningValidateProposalInternal: machine.actionValidateSigningProposalConfirmations,
|
eventAutoSigningValidateProposalInternal: machine.actionValidateSigningProposalConfirmations,
|
||||||
EventSigningPartialKeyReceived: machine.actionPartialKeyConfirmationReceived,
|
EventSigningPartialSignReceived: machine.actionPartialSignConfirmationReceived,
|
||||||
eventAutoSigningValidatePartialKeyInternal: machine.actionValidateSigningPartialKeyAwaitConfirmations,
|
eventAutoSigningValidatePartialSignInternal: machine.actionValidateSigningPartialSignsAwaitConfirmations,
|
||||||
EventSigningPartialKeyError: machine.actionConfirmationError,
|
EventSigningPartialSignError: machine.actionConfirmationError,
|
||||||
EventSigningRestart: machine.actionSigningRestart,
|
EventSigningRestart: machine.actionSigningRestart,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
@ -21,7 +21,7 @@ type SigningProposalParticipantRequest struct {
|
||||||
|
|
||||||
// States: "state_signing_await_partial_keys"
|
// States: "state_signing_await_partial_keys"
|
||||||
// Events: "event_signing_partial_key_received"
|
// Events: "event_signing_partial_key_received"
|
||||||
type SigningProposalPartialKeyRequest struct {
|
type SigningProposalPartialSignRequest struct {
|
||||||
SigningId string
|
SigningId string
|
||||||
ParticipantId int
|
ParticipantId int
|
||||||
PartialSign []byte
|
PartialSign []byte
|
||||||
|
|
|
@ -34,7 +34,7 @@ func (r *SigningProposalParticipantRequest) Validate() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *SigningProposalPartialKeyRequest) Validate() error {
|
func (r *SigningProposalPartialSignRequest) Validate() error {
|
||||||
if r.SigningId == "" {
|
if r.SigningId == "" {
|
||||||
return errors.New("{SigningId} cannot be empty")
|
return errors.New("{SigningId} cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ type SignatureProposalParticipantInvitationEntry struct {
|
||||||
ParticipantId int
|
ParticipantId int
|
||||||
// Public title for address, such as name, nickname, organization
|
// Public title for address, such as name, nickname, organization
|
||||||
Addr string
|
Addr string
|
||||||
|
Threshold int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public lists for proposal confirmation process
|
// Public lists for proposal confirmation process
|
||||||
|
|
Loading…
Reference in New Issue