mirror of https://github.com/certusone/dc4bc.git
Merge pull request #26 from depools/feat/airgapped-bls-signing
Feat/airgapped bls signing
This commit is contained in:
commit
233ee27745
|
@ -3,6 +3,7 @@ package airgapped
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
|
@ -190,6 +191,12 @@ func (am *AirgappedMachine) HandleOperation(operation client.Operation) (client.
|
|||
err = am.handleStateDkgResponsesAwaitConfirmations(&operation)
|
||||
case dkg_proposal_fsm.StateDkgMasterKeyAwaitConfirmations:
|
||||
err = am.handleStateDkgMasterKeyAwaitConfirmations(&operation)
|
||||
case signing_proposal_fsm.StateSigningAwaitConfirmations:
|
||||
err = am.handleStateSigningAwaitConfirmations(&operation)
|
||||
case signing_proposal_fsm.StateSigningAwaitPartialKeys:
|
||||
err = am.handleStateSigningAwaitPartialSigns(&operation)
|
||||
case signing_proposal_fsm.StateSigningPartialKeysCollected:
|
||||
err = am.reconstructThresholdSignature(&operation)
|
||||
default:
|
||||
err = fmt.Errorf("invalid operation type: %s", operation.Type)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
client "github.com/depools/dc4bc/client/types"
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/dkg_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/responses"
|
||||
"github.com/depools/dc4bc/storage"
|
||||
|
@ -29,6 +30,7 @@ type Node struct {
|
|||
deals []requests.DKGProposalDealConfirmationRequest
|
||||
responses []requests.DKGProposalResponseConfirmationRequest
|
||||
masterKeys []requests.DKGProposalMasterKeyConfirmationRequest
|
||||
partialSigns []requests.SigningProposalPartialKeyRequest
|
||||
}
|
||||
|
||||
func (n *Node) storeOperation(t *testing.T, msg storage.Message) {
|
||||
|
@ -57,6 +59,12 @@ func (n *Node) storeOperation(t *testing.T, msg storage.Message) {
|
|||
t.Fatalf("failed to unmarshal fsm req: %v", err)
|
||||
}
|
||||
n.masterKeys = append(n.masterKeys, req)
|
||||
case signing_proposal_fsm.EventSigningPartialKeyReceived:
|
||||
var req requests.SigningProposalPartialKeyRequest
|
||||
if err := json.Unmarshal(msg.Data, &req); err != nil {
|
||||
t.Fatalf("failed to unmarshal fsm req: %v", err)
|
||||
}
|
||||
n.partialSigns = append(n.partialSigns, req)
|
||||
default:
|
||||
t.Fatalf("invalid event: %s", msg.Event)
|
||||
}
|
||||
|
@ -91,7 +99,7 @@ func createOperation(t *testing.T, opType string, to string, req interface{}) cl
|
|||
}
|
||||
|
||||
func TestAirgappedAllSteps(t *testing.T) {
|
||||
nodesCount := 25
|
||||
nodesCount := 10
|
||||
participants := make([]string, nodesCount)
|
||||
for i := 0; i < nodesCount; i++ {
|
||||
participants[i] = fmt.Sprintf("Participant#%d", i)
|
||||
|
@ -220,27 +228,52 @@ func TestAirgappedAllSteps(t *testing.T) {
|
|||
}
|
||||
|
||||
msgToSign := []byte("i am a message")
|
||||
sigShares := make([][]byte, 0)
|
||||
for _, n := range tr.nodes {
|
||||
sigShare, err := n.Machine.createPartialSign(msgToSign, DKGIdentifier)
|
||||
|
||||
//partialSigns
|
||||
runStep(tr, func(n *Node, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
payload := responses.SigningPartialSignsParticipantInvitationsResponse{
|
||||
SrcPayload: msgToSign,
|
||||
}
|
||||
|
||||
op := createOperation(t, string(signing_proposal_fsm.StateSigningAwaitPartialKeys), "", payload)
|
||||
|
||||
operation, err := n.Machine.HandleOperation(op)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create sig share: %v", err.Error())
|
||||
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
|
||||
}
|
||||
sigShares = append(sigShares, sigShare)
|
||||
}
|
||||
|
||||
fullSign, err := tr.nodes[0].Machine.recoverFullSign(msgToSign, sigShares, DKGIdentifier)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to recover full sign: %v", err.Error())
|
||||
}
|
||||
|
||||
for _, n := range tr.nodes {
|
||||
if err = n.Machine.verifySign(msgToSign, fullSign, DKGIdentifier); err != nil {
|
||||
t.Fatalf("failed to verify signature: %v", err)
|
||||
for _, msg := range operation.ResultMsgs {
|
||||
tr.BroadcastMessage(t, msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
fmt.Println("DKG succeeded, signature recovered and verified")
|
||||
//recover full signature
|
||||
runStep(tr, func(n *Node, wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
|
||||
var payload responses.SigningProcessParticipantResponse
|
||||
for _, req := range n.partialSigns {
|
||||
p := responses.SigningProcessParticipantEntry{
|
||||
ParticipantId: req.ParticipantId,
|
||||
Addr: fmt.Sprintf("Participant#%d", req.ParticipantId),
|
||||
PartialSign: req.PartialSign,
|
||||
}
|
||||
payload.Participants = append(payload.Participants, &p)
|
||||
}
|
||||
payload.SrcPayload = msgToSign
|
||||
op := createOperation(t, string(signing_proposal_fsm.StateSigningPartialKeysCollected), "", payload)
|
||||
|
||||
operation, err := n.Machine.HandleOperation(op)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
|
||||
}
|
||||
for _, msg := range operation.ResultMsgs {
|
||||
tr.BroadcastMessage(t, msg)
|
||||
}
|
||||
})
|
||||
|
||||
fmt.Println("DKG succeeded, signature recovered")
|
||||
}
|
||||
|
||||
func runStep(transport *Transport, cb func(n *Node, wg *sync.WaitGroup)) {
|
||||
|
|
121
airgapped/bls.go
121
airgapped/bls.go
|
@ -1,41 +1,102 @@
|
|||
package airgapped
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
client "github.com/depools/dc4bc/client/types"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
||||
"github.com/depools/dc4bc/fsm/types/requests"
|
||||
"github.com/depools/dc4bc/fsm/types/responses"
|
||||
"go.dedis.ch/kyber/v3/sign/bls"
|
||||
"go.dedis.ch/kyber/v3/sign/tbls"
|
||||
)
|
||||
|
||||
// commented because fsm is not ready
|
||||
//func (am *AirgappedMachine) handleStateSigningAwaitPartialKeys(o *client.Operation) error {
|
||||
// var (
|
||||
// payload responses.DKGProposalResponsesParticipantResponse
|
||||
// err error
|
||||
// )
|
||||
//
|
||||
// if err = json.Unmarshal(o.Payload, &payload); err != nil {
|
||||
// return fmt.Errorf("failed to unmarshal payload: %w", err)
|
||||
// }
|
||||
//
|
||||
// partialSign, err := am.createPartialSign(nil, o.DKGIdentifier)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to create partialSign for msg: %w", err)
|
||||
// }
|
||||
//
|
||||
// req := requests.SigningProposalPartialKeyRequest{
|
||||
// ParticipantId: 0, // TODO: from where?
|
||||
// PartialKey: partialSign,
|
||||
// CreatedAt: o.CreatedAt,
|
||||
// }
|
||||
// reqBz, err := json.Marshal(req)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to generate fsm request: %w", err)
|
||||
// }
|
||||
//
|
||||
// o.Result = reqBz
|
||||
// o.Event = signing_proposal_fsm.EventSigningPartialKeyReceived
|
||||
// return nil
|
||||
//}
|
||||
func (am *AirgappedMachine) handleStateSigningAwaitConfirmations(o *client.Operation) error {
|
||||
var (
|
||||
payload responses.SigningProposalParticipantInvitationsResponse
|
||||
err error
|
||||
)
|
||||
|
||||
if err = json.Unmarshal(o.Payload, &payload); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal payload: %w", err)
|
||||
}
|
||||
|
||||
participantID, err := am.getParticipantID(o.DKGIdentifier)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get paricipant id: %w", err)
|
||||
}
|
||||
req := requests.SigningProposalParticipantRequest{
|
||||
SigningId: payload.SigningId,
|
||||
ParticipantId: participantID,
|
||||
CreatedAt: o.CreatedAt,
|
||||
}
|
||||
reqBz, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate fsm request: %w", err)
|
||||
}
|
||||
|
||||
o.Event = signing_proposal_fsm.EventConfirmSigningConfirmation
|
||||
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am *AirgappedMachine) handleStateSigningAwaitPartialSigns(o *client.Operation) error {
|
||||
var (
|
||||
payload responses.SigningPartialSignsParticipantInvitationsResponse
|
||||
err error
|
||||
)
|
||||
|
||||
if err = json.Unmarshal(o.Payload, &payload); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal payload: %w", err)
|
||||
}
|
||||
|
||||
partialSign, err := am.createPartialSign(payload.SrcPayload, o.DKGIdentifier)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create partialSign for msg: %w", err)
|
||||
}
|
||||
|
||||
participantID, err := am.getParticipantID(o.DKGIdentifier)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get paricipant id: %w", err)
|
||||
}
|
||||
req := requests.SigningProposalPartialKeyRequest{
|
||||
SigningId: payload.SigningId,
|
||||
ParticipantId: participantID,
|
||||
PartialSign: partialSign,
|
||||
CreatedAt: o.CreatedAt,
|
||||
}
|
||||
reqBz, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate fsm request: %w", err)
|
||||
}
|
||||
|
||||
o.Event = signing_proposal_fsm.EventSigningPartialKeyReceived
|
||||
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am *AirgappedMachine) reconstructThresholdSignature(o *client.Operation) error {
|
||||
var (
|
||||
payload responses.SigningProcessParticipantResponse
|
||||
err error
|
||||
)
|
||||
|
||||
if err = json.Unmarshal(o.Payload, &payload); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal payload: %w", err)
|
||||
}
|
||||
|
||||
partialSignatures := make([][]byte, 0, len(payload.Participants))
|
||||
for _, participant := range payload.Participants {
|
||||
partialSignatures = append(partialSignatures, participant.PartialSign)
|
||||
}
|
||||
|
||||
reconstructedSignature, err := am.recoverFullSign(payload.SrcPayload, partialSignatures, o.DKGIdentifier)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to reconsruct full signature for msg: %w", err)
|
||||
}
|
||||
fmt.Println(reconstructedSignature)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am *AirgappedMachine) createPartialSign(msg []byte, dkgIdentifier string) ([]byte, error) {
|
||||
blsKeyring, err := am.loadBLSKeyring(dkgIdentifier)
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
sipf "github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
@ -182,6 +183,18 @@ func (c *Client) ProcessMessage(message storage.Message) error {
|
|||
return fmt.Errorf("failed to Do operation in FSM: %w", err)
|
||||
}
|
||||
}
|
||||
if resp.State == dpf.StateDkgMasterKeyCollected {
|
||||
fsmInstance, err = state_machines.FromDump(fsmDump)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed get state_machines from dump: %w", err)
|
||||
}
|
||||
resp, fsmDump, err = fsmInstance.Do(sipf.EventSigningInit, requests.DefaultRequest{
|
||||
CreatedAt: time.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to Do operation in FSM: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var operation *types.Operation
|
||||
switch resp.State {
|
||||
|
@ -191,7 +204,10 @@ func (c *Client) ProcessMessage(message storage.Message) error {
|
|||
dpf.StateDkgCommitsAwaitConfirmations,
|
||||
dpf.StateDkgDealsAwaitConfirmations,
|
||||
dpf.StateDkgResponsesAwaitConfirmations,
|
||||
dpf.StateDkgMasterKeyAwaitConfirmations:
|
||||
dpf.StateDkgMasterKeyAwaitConfirmations,
|
||||
sipf.StateSigningAwaitPartialKeys,
|
||||
sipf.StateSigningPartialKeysCollected,
|
||||
sipf.StateSigningAwaitConfirmations:
|
||||
if resp.Data != nil {
|
||||
bz, err := json.Marshal(resp.Data)
|
||||
if err != nil {
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
||||
"time"
|
||||
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
|
@ -85,6 +86,24 @@ func FSMRequestFromMessage(message storage.Message) (interface{}, error) {
|
|||
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
||||
}
|
||||
resolvedValue = req
|
||||
case signing_proposal_fsm.EventSigningPartialKeyReceived:
|
||||
var req requests.SigningProposalPartialKeyRequest
|
||||
if err := json.Unmarshal(message.Data, &req); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
||||
}
|
||||
resolvedValue = req
|
||||
case signing_proposal_fsm.EventConfirmSigningConfirmation:
|
||||
var req requests.SigningProposalParticipantRequest
|
||||
if err := json.Unmarshal(message.Data, &req); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
||||
}
|
||||
resolvedValue = req
|
||||
case signing_proposal_fsm.EventSigningStart:
|
||||
var req requests.SigningProposalStartRequest
|
||||
if err := json.Unmarshal(message.Data, &req); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal fsm req: %v", err), nil
|
||||
}
|
||||
resolvedValue = req
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid event: %s", message.Event)
|
||||
}
|
||||
|
|
|
@ -183,9 +183,9 @@ func (s SigningParticipantStatus) String() string {
|
|||
}
|
||||
|
||||
type SigningProposalParticipant struct {
|
||||
Addr string
|
||||
Status SigningParticipantStatus
|
||||
PartialKey []byte
|
||||
Error error
|
||||
UpdatedAt time.Time
|
||||
Addr string
|
||||
Status SigningParticipantStatus
|
||||
PartialSign []byte
|
||||
Error error
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
|
|
@ -48,6 +48,10 @@ var (
|
|||
CreatedAt: tm,
|
||||
}
|
||||
|
||||
testSigningId string
|
||||
testSigningInitiator int
|
||||
testSigningPayload = []byte("message to sign")
|
||||
|
||||
testFSMDump = map[fsm.State][]byte{}
|
||||
)
|
||||
|
||||
|
@ -173,17 +177,17 @@ func Test_SignatureProposal_EventInitProposal_Positive(t *testing.T) {
|
|||
|
||||
compareState(t, spf.StateAwaitParticipantsConfirmations, fsmResponse.State)
|
||||
|
||||
testParticipantsListResponse, ok := fsmResponse.Data.(responses.SignatureProposalParticipantInvitationsResponse)
|
||||
response, 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))
|
||||
if len(response) != len(testParticipantsListRequest.Participants) {
|
||||
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response))
|
||||
}
|
||||
|
||||
for _, participant := range testParticipantsListResponse {
|
||||
for _, participant := range response {
|
||||
if _, ok := testIdMapParticipants[participant.ParticipantId]; ok {
|
||||
t.Fatalf("expected unique {ParticipantId}")
|
||||
}
|
||||
|
@ -400,6 +404,10 @@ func Test_DkgProposal_EventDKGCommitConfirmationReceived(t *testing.T) {
|
|||
t.Fatalf("expected exist {ParticipantId}")
|
||||
}
|
||||
|
||||
if responseEntry.Addr == "" {
|
||||
t.Fatalf("expected {Addr} non zero length")
|
||||
}
|
||||
|
||||
if len(responseEntry.DkgCommit) == 0 {
|
||||
t.Fatalf("expected {DkgCommit} non zero length")
|
||||
}
|
||||
|
@ -521,6 +529,10 @@ func Test_DkgProposal_EventDKGDealConfirmationReceived(t *testing.T) {
|
|||
t.Fatalf("expected exist {ParticipantId}")
|
||||
}
|
||||
|
||||
if responseEntry.Addr == "" {
|
||||
t.Fatalf("expected {Addr} non zero length")
|
||||
}
|
||||
|
||||
if len(responseEntry.DkgDeal) == 0 {
|
||||
t.Fatalf("expected {DkgDeal} non zero length")
|
||||
}
|
||||
|
@ -636,6 +648,10 @@ func Test_DkgProposal_EventDKGResponseConfirmationReceived_Positive(t *testing.T
|
|||
t.Fatalf("expected exist {ParticipantId}")
|
||||
}
|
||||
|
||||
if responseEntry.Addr == "" {
|
||||
t.Fatalf("expected {Addr} non zero length")
|
||||
}
|
||||
|
||||
if len(responseEntry.DkgResponse) == 0 {
|
||||
t.Fatalf("expected {DkgResponse} non zero length")
|
||||
}
|
||||
|
@ -864,7 +880,9 @@ func Test_SigningProposal_EventSigningInit(t *testing.T) {
|
|||
|
||||
// Start
|
||||
func Test_SigningProposal_EventSigningStart(t *testing.T) {
|
||||
var fsmResponse *fsm.Response
|
||||
var (
|
||||
fsmResponse *fsm.Response
|
||||
)
|
||||
|
||||
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningIdle])
|
||||
|
||||
|
@ -887,22 +905,237 @@ func Test_SigningProposal_EventSigningStart(t *testing.T) {
|
|||
|
||||
compareState(t, sif.StateSigningAwaitConfirmations, fsmResponse.State)
|
||||
|
||||
compareDumpNotZero(t, testFSMDump[sif.StateSigningAwaitConfirmations])
|
||||
|
||||
testSigningParticipantsListResponse, ok := fsmResponse.Data.(responses.SigningProposalParticipantInvitationsResponse)
|
||||
response, ok := fsmResponse.Data.(responses.SigningProposalParticipantInvitationsResponse)
|
||||
|
||||
if !ok {
|
||||
t.Fatalf("expected response {SigningProposalParticipantInvitationsResponse}")
|
||||
}
|
||||
|
||||
if len(testSigningParticipantsListResponse.Participants) != len(testParticipantsListRequest.Participants) {
|
||||
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(testSigningParticipantsListResponse.Participants))
|
||||
if len(response.Participants) != len(testParticipantsListRequest.Participants) {
|
||||
t.Fatalf("expected response len {%d}, got {%d}", len(testParticipantsListRequest.Participants), len(response.Participants))
|
||||
}
|
||||
|
||||
if testSigningParticipantsListResponse.SigningId == "" {
|
||||
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.StateSigningAwaitPartialKeys, 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.StateSigningAwaitPartialKeys] = testFSMDumpLocal
|
||||
|
||||
compareDumpNotZero(t, testFSMDump[sif.StateSigningAwaitPartialKeys])
|
||||
}
|
||||
|
||||
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.StateSigningAwaitPartialKeys]
|
||||
|
||||
for participantId, participant := range testIdMapParticipants {
|
||||
participantCounter--
|
||||
|
||||
testFSMInstance, err := FromDump(testFSMDumpLocal)
|
||||
|
||||
compareErrNil(t, err)
|
||||
|
||||
compareFSMInstanceNotNil(t, testFSMInstance)
|
||||
|
||||
inState, _ := testFSMInstance.State()
|
||||
compareState(t, sif.StateSigningAwaitPartialKeys, inState)
|
||||
|
||||
fsmResponse, testFSMDumpLocal, err = testFSMInstance.Do(sif.EventSigningPartialKeyReceived, requests.SigningProposalPartialKeyRequest{
|
||||
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.StateSigningAwaitPartialKeys, fsmResponse.State)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
compareState(t, sif.StateSigningPartialKeysCollected, 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.StateSigningPartialKeysCollected] = testFSMDumpLocal
|
||||
|
||||
compareDumpNotZero(t, testFSMDump[sif.StateSigningPartialKeysCollected])
|
||||
}
|
||||
|
||||
func Test_DkgProposal_EventSigningRestart_Positive(t *testing.T) {
|
||||
var (
|
||||
fsmResponse *fsm.Response
|
||||
testFSMDumpLocal []byte
|
||||
)
|
||||
|
||||
testFSMInstance, err := FromDump(testFSMDump[sif.StateSigningPartialKeysCollected])
|
||||
|
||||
compareErrNil(t, err)
|
||||
|
||||
compareFSMInstanceNotNil(t, testFSMInstance)
|
||||
|
||||
inState, _ := testFSMInstance.State()
|
||||
compareState(t, sif.StateSigningPartialKeysCollected, 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) {
|
||||
|
|
|
@ -84,17 +84,18 @@ func (m *SigningProposalFSM) actionStartSigningProposal(inEvent fsm.Event, args
|
|||
m.payload.SigningProposalPayload.CreatedAt = request.CreatedAt
|
||||
|
||||
// Make response
|
||||
|
||||
responseData := responses.SigningProposalParticipantInvitationsResponse{
|
||||
SigningId: m.payload.SigningProposalPayload.SigningId,
|
||||
InitiatorId: m.payload.SigningProposalPayload.InitiatorId,
|
||||
SrcPayload: m.payload.SigningProposalPayload.SrcPayload,
|
||||
Participants: make([]*responses.SigningProposalParticipantInvitationEntry, 0),
|
||||
}
|
||||
|
||||
for participantId, proposal := range m.payload.SigningProposalPayload.Quorum {
|
||||
for participantId, participant := range m.payload.SigningProposalPayload.Quorum {
|
||||
responseEntry := &responses.SigningProposalParticipantInvitationEntry{
|
||||
ParticipantId: participantId,
|
||||
Addr: proposal.Addr,
|
||||
Addr: participant.Addr,
|
||||
Status: uint8(participant.Status),
|
||||
}
|
||||
responseData.Participants = append(responseData.Participants, responseEntry)
|
||||
}
|
||||
|
@ -130,7 +131,7 @@ func (m *SigningProposalFSM) actionProposalResponseByParticipant(inEvent fsm.Eve
|
|||
signingProposalParticipant := m.payload.SigningQuorumGet(request.ParticipantId)
|
||||
|
||||
if signingProposalParticipant.Status != internal.SigningAwaitConfirmation {
|
||||
err = errors.New(fmt.Sprintf("cannot confirm commit with {Status} = {\"%s\"}", signingProposalParticipant.Status))
|
||||
err = errors.New(fmt.Sprintf("cannot confirm participant with {Status} = {\"%s\"}", signingProposalParticipant.Status))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -143,7 +144,6 @@ func (m *SigningProposalFSM) actionProposalResponseByParticipant(inEvent fsm.Eve
|
|||
err = errors.New(fmt.Sprintf("unsupported event for action {inEvent} = {\"%s\"}", inEvent))
|
||||
return
|
||||
}
|
||||
signingProposalParticipant.Status = internal.SigningConfirmed
|
||||
|
||||
signingProposalParticipant.UpdatedAt = request.CreatedAt
|
||||
m.payload.SigningProposalPayload.UpdatedAt = request.CreatedAt
|
||||
|
@ -162,7 +162,7 @@ func (m *SigningProposalFSM) actionValidateSigningProposalConfirmations(inEvent
|
|||
defer m.payloadMu.Unlock()
|
||||
|
||||
if m.payload.SigningProposalPayload.IsExpired() {
|
||||
outEvent = eventSetSigningConfirmCanceledByParticipantInternal
|
||||
outEvent = eventSetSigningConfirmCanceledByTimeoutInternal
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -191,6 +191,15 @@ func (m *SigningProposalFSM) actionValidateSigningProposalConfirmations(inEvent
|
|||
participant.Status = internal.SigningAwaitPartialKeys
|
||||
}
|
||||
|
||||
// Make response
|
||||
responseData := responses.SigningPartialSignsParticipantInvitationsResponse{
|
||||
SigningId: m.payload.SigningProposalPayload.SigningId,
|
||||
InitiatorId: m.payload.SigningProposalPayload.InitiatorId,
|
||||
SrcPayload: m.payload.SigningProposalPayload.SrcPayload,
|
||||
}
|
||||
|
||||
response = responseData
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -226,8 +235,8 @@ func (m *SigningProposalFSM) actionPartialKeyConfirmationReceived(inEvent fsm.Ev
|
|||
return
|
||||
}
|
||||
|
||||
signingProposalParticipant.PartialKey = make([]byte, len(request.PartialKey))
|
||||
copy(signingProposalParticipant.PartialKey, request.PartialKey)
|
||||
signingProposalParticipant.PartialSign = make([]byte, len(request.PartialSign))
|
||||
copy(signingProposalParticipant.PartialSign, request.PartialSign)
|
||||
signingProposalParticipant.Status = internal.SigningPartialKeysConfirmed
|
||||
|
||||
signingProposalParticipant.UpdatedAt = request.CreatedAt
|
||||
|
@ -276,6 +285,29 @@ func (m *SigningProposalFSM) actionValidateSigningPartialKeyAwaitConfirmations(i
|
|||
participant.Status = internal.SigningProcess
|
||||
}
|
||||
|
||||
// Response
|
||||
responseData := responses.SigningProcessParticipantResponse{
|
||||
SigningId: m.payload.SigningProposalPayload.SigningId,
|
||||
SrcPayload: m.payload.SigningProposalPayload.SrcPayload,
|
||||
Participants: make([]*responses.SigningProcessParticipantEntry, 0),
|
||||
}
|
||||
|
||||
for participantId, participant := range m.payload.SigningProposalPayload.Quorum {
|
||||
responseEntry := &responses.SigningProcessParticipantEntry{
|
||||
ParticipantId: participantId,
|
||||
Addr: participant.Addr,
|
||||
PartialSign: participant.PartialSign,
|
||||
}
|
||||
responseData.Participants = append(responseData.Participants, responseEntry)
|
||||
}
|
||||
|
||||
response = responseData
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (m *SigningProposalFSM) actionSigningRestart(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
dkgTransactionIdLength = 128
|
||||
dkgTransactionIdLength = 512
|
||||
)
|
||||
|
||||
func generateSigningId() (string, error) {
|
||||
|
|
|
@ -23,8 +23,8 @@ const (
|
|||
|
||||
StateSigningAwaitPartialKeys = fsm.State("state_signing_await_partial_keys")
|
||||
// Cancelled
|
||||
StateSigningPartialKeysAwaitCancelledByTimeout = fsm.State("state_signing_partial_signatures_await_cancelled_by_timeout")
|
||||
StateSigningPartialKeysAwaitCancelledByParticipant = fsm.State("state_signing_partial_signatures_await_cancelled_by_participant")
|
||||
StateSigningPartialKeysAwaitCancelledByTimeout = fsm.State("state_signing_partial_signatures_await_cancelled_by_timeout")
|
||||
StateSigningPartialKeysAwaitCancelledByError = fsm.State("state_signing_partial_signatures_await_cancelled_by_error")
|
||||
|
||||
StateSigningPartialKeysCollected = fsm.State("state_signing_partial_signatures_collected")
|
||||
|
||||
|
@ -37,15 +37,18 @@ const (
|
|||
eventSetSigningConfirmCanceledByParticipantInternal = fsm.Event("event_signing_proposal_canceled_by_participant")
|
||||
eventSetSigningConfirmCanceledByTimeoutInternal = fsm.Event("event_signing_proposal_canceled_by_timeout")
|
||||
|
||||
eventAutoValidateProposalInternal = fsm.Event("event_signing_proposal_validate")
|
||||
eventSetProposalValidatedInternal = fsm.Event("event_signing_proposal_set_validated")
|
||||
eventAutoSigningValidateProposalInternal = fsm.Event("event_signing_proposal_await_validate")
|
||||
eventSetProposalValidatedInternal = fsm.Event("event_signing_proposal_set_validated")
|
||||
|
||||
EventSigningPartialKeyReceived = fsm.Event("event_signing_partial_key_received")
|
||||
EventSigningPartialKeyError = fsm.Event("event_signing_partial_key_error_received")
|
||||
eventSigningPartialKeyCancelByTimeoutInternal = fsm.Event("event_signing_partial_key_canceled_by_timeout_internal")
|
||||
eventSigningPartialKeyCancelByErrorInternal = fsm.Event("event_signing_partial_key_canceled_by_error_internal")
|
||||
eventSigningPartialKeysConfirmedInternal = fsm.Event("event_signing_partial_keys_confirmed_internal")
|
||||
EventSigningRestart = fsm.Event("event_signing_restart")
|
||||
|
||||
eventAutoSigningValidatePartialKeyInternal = fsm.Event("event_signing_partial_keys_await_validate")
|
||||
|
||||
eventSigningPartialKeysConfirmedInternal = fsm.Event("event_signing_partial_keys_confirmed_internal")
|
||||
EventSigningRestart = fsm.Event("event_signing_restart")
|
||||
)
|
||||
|
||||
type SigningProposalFSM struct {
|
||||
|
@ -76,29 +79,33 @@ func New() internal.DumpedMachineProvider {
|
|||
{Name: eventSetSigningConfirmCanceledByTimeoutInternal, SrcState: []fsm.State{StateSigningAwaitConfirmations}, DstState: StateSigningConfirmationsAwaitCancelledByTimeout, IsInternal: true},
|
||||
|
||||
// Validate
|
||||
{Name: eventAutoValidateProposalInternal, 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},
|
||||
|
||||
// Canceled
|
||||
{Name: EventSigningPartialKeyReceived, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningAwaitPartialKeys},
|
||||
{Name: EventSigningPartialKeyError, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByParticipant},
|
||||
{Name: EventSigningPartialKeyError, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByError},
|
||||
{Name: eventSigningPartialKeyCancelByTimeoutInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByTimeout, IsInternal: true},
|
||||
{Name: eventSigningPartialKeyCancelByErrorInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByParticipant, IsInternal: true, IsAuto: true},
|
||||
{Name: eventSigningPartialKeyCancelByErrorInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysAwaitCancelledByError, IsInternal: true},
|
||||
|
||||
// Validate
|
||||
{Name: eventAutoSigningValidatePartialKeyInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningAwaitPartialKeys, IsInternal: true, IsAuto: true},
|
||||
|
||||
{Name: eventSigningPartialKeysConfirmedInternal, SrcState: []fsm.State{StateSigningAwaitPartialKeys}, DstState: StateSigningPartialKeysCollected, IsInternal: true},
|
||||
|
||||
{Name: EventSigningRestart, SrcState: []fsm.State{StateSigningPartialKeysCollected}, DstState: StateSigningIdle, IsInternal: true},
|
||||
{Name: EventSigningRestart, SrcState: []fsm.State{StateSigningPartialKeysCollected}, DstState: StateSigningIdle},
|
||||
},
|
||||
fsm.Callbacks{
|
||||
EventSigningInit: machine.actionInitSigningProposal,
|
||||
EventSigningStart: machine.actionStartSigningProposal,
|
||||
EventConfirmSigningConfirmation: machine.actionProposalResponseByParticipant,
|
||||
EventDeclineSigningConfirmation: machine.actionProposalResponseByParticipant,
|
||||
eventAutoValidateProposalInternal: machine.actionValidateSigningProposalConfirmations,
|
||||
EventSigningPartialKeyReceived: machine.actionPartialKeyConfirmationReceived,
|
||||
EventSigningPartialKeyError: machine.actionValidateSigningPartialKeyAwaitConfirmations,
|
||||
// actionConfirmationError
|
||||
EventSigningInit: machine.actionInitSigningProposal,
|
||||
EventSigningStart: machine.actionStartSigningProposal,
|
||||
EventConfirmSigningConfirmation: machine.actionProposalResponseByParticipant,
|
||||
EventDeclineSigningConfirmation: machine.actionProposalResponseByParticipant,
|
||||
eventAutoSigningValidateProposalInternal: machine.actionValidateSigningProposalConfirmations,
|
||||
EventSigningPartialKeyReceived: machine.actionPartialKeyConfirmationReceived,
|
||||
eventAutoSigningValidatePartialKeyInternal: machine.actionValidateSigningPartialKeyAwaitConfirmations,
|
||||
EventSigningPartialKeyError: machine.actionConfirmationError,
|
||||
EventSigningRestart: machine.actionSigningRestart,
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
@ -24,6 +24,6 @@ type SigningProposalParticipantRequest struct {
|
|||
type SigningProposalPartialKeyRequest struct {
|
||||
SigningId string
|
||||
ParticipantId int
|
||||
PartialKey []byte
|
||||
PartialSign []byte
|
||||
CreatedAt time.Time
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ func (r *SigningProposalPartialKeyRequest) Validate() error {
|
|||
return errors.New("{ParticipantId} cannot be a negative number")
|
||||
}
|
||||
|
||||
if len(r.PartialKey) == 0 {
|
||||
return errors.New("{PartialKey} cannot zero length")
|
||||
if len(r.PartialSign) == 0 {
|
||||
return errors.New("{PartialSign} cannot zero length")
|
||||
}
|
||||
|
||||
if r.CreatedAt.IsZero() {
|
||||
|
|
|
@ -4,7 +4,6 @@ package responses
|
|||
|
||||
// Event: "event_sig_proposal_init"
|
||||
// States: "__idle"
|
||||
|
||||
type SignatureProposalParticipantInvitationsResponse []*SignatureProposalParticipantInvitationEntry
|
||||
|
||||
type SignatureProposalParticipantInvitationEntry struct {
|
||||
|
|
|
@ -1,20 +1,52 @@
|
|||
package responses
|
||||
|
||||
// Event: "event_signing_start"
|
||||
// States: "state_signing_await_confirmations"
|
||||
type SigningProposalParticipantInvitationsResponse struct {
|
||||
SigningId string
|
||||
InitiatorId int
|
||||
Participants []*SigningProposalParticipantInvitationEntry
|
||||
SigningId string
|
||||
// Source message for signing
|
||||
SrcPayload []byte
|
||||
}
|
||||
|
||||
type SigningProposalParticipantInvitationEntry struct {
|
||||
ParticipantId int
|
||||
Addr string
|
||||
Status uint8
|
||||
}
|
||||
|
||||
type SigningProposalParticipantStatusResponse []*SignatureProposalParticipantStatusEntry
|
||||
// Event: "event_signing_proposal_confirm_by_participant"
|
||||
// States: "state_signing_await_partial_keys"
|
||||
type SigningPartialSignsParticipantInvitationsResponse struct {
|
||||
SigningId string
|
||||
InitiatorId int
|
||||
SrcPayload []byte
|
||||
}
|
||||
|
||||
// Event: ""
|
||||
// States: ""
|
||||
type SigningProposalParticipantStatusResponse struct {
|
||||
SigningId string
|
||||
Participants []*SignatureProposalParticipantStatusEntry
|
||||
}
|
||||
|
||||
type SigningProposalParticipantStatusEntry struct {
|
||||
ParticipantId int
|
||||
Addr string
|
||||
Status uint8
|
||||
}
|
||||
|
||||
// Event: ""
|
||||
// States: ""
|
||||
type SigningProcessParticipantResponse struct {
|
||||
SigningId string
|
||||
SrcPayload []byte
|
||||
Participants []*SigningProcessParticipantEntry
|
||||
}
|
||||
|
||||
type SigningProcessParticipantEntry struct {
|
||||
ParticipantId int
|
||||
Addr string
|
||||
PartialSign []byte
|
||||
}
|
||||
|
|
30
main.go
30
main.go
|
@ -7,6 +7,7 @@ import (
|
|||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
sif "github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
|
||||
_ "image/jpeg"
|
||||
"log"
|
||||
"sync"
|
||||
|
@ -119,7 +120,7 @@ func main() {
|
|||
participants = append(participants, &requests.SignatureProposalParticipantsEntry{
|
||||
Addr: node.client.GetAddr(),
|
||||
PubKey: node.client.GetPubKey(),
|
||||
DkgPubKey: dkgPubKey, // TODO: Use a real one.
|
||||
DkgPubKey: dkgPubKey,
|
||||
})
|
||||
}
|
||||
messageData := requests.SignatureProposalParticipantsListRequest{
|
||||
|
@ -146,6 +147,33 @@ func main() {
|
|||
log.Fatalf("Failed to send %+v to storage: %v\n", message, err)
|
||||
}
|
||||
|
||||
// i haven't a better idea to test signing without big changes in the client code
|
||||
time.Sleep(10 * time.Second)
|
||||
log.Println("Propose message to sign")
|
||||
|
||||
messageDataSign := requests.SigningProposalStartRequest{
|
||||
ParticipantId: 0,
|
||||
SrcPayload: []byte("message to sign"),
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
messageDataBz, err = json.Marshal(messageDataSign)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to marshal SignatureProposalParticipantsListRequest: %v\n", err)
|
||||
}
|
||||
|
||||
message = storage.Message{
|
||||
ID: uuid.New().String(),
|
||||
DkgRoundID: hex.EncodeToString(dkgRoundID[:]),
|
||||
Event: string(sif.EventSigningStart),
|
||||
Data: messageDataBz,
|
||||
SenderAddr: nodes[0].client.GetAddr(),
|
||||
}
|
||||
|
||||
message.Signature = ed25519.Sign(nodes[0].keyPair.Priv, message.Bytes())
|
||||
if _, err := stg.Send(message); err != nil {
|
||||
log.Fatalf("Failed to send %+v to storage: %v\n", message, err)
|
||||
}
|
||||
|
||||
var wg = sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
wg.Wait()
|
||||
|
|
Loading…
Reference in New Issue