wip merged

This commit is contained in:
x88 2020-08-19 16:47:38 +03:00
parent b2cd06ea7e
commit 9fbc54cf34
11 changed files with 174 additions and 126 deletions

View File

@ -14,21 +14,38 @@ import (
// Init
func (m *DKGProposalFSM) actionInitDKGProposal(inEvent fsm.Event, args ...interface{}) (outEvent fsm.Event, response interface{}, err error) {
m.payloadMu.Lock()
defer m.payloadMu.Unlock()
if m.payload.DKGProposalPayload != nil {
return
}
m.payload.DKGProposalPayload = &internal.DKGConfirmation{
Quorum: make(internal.DKGProposalQuorum),
if len(args) != 1 {
err = errors.New("{arg0} required {DefaultRequest}")
return
}
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
m.payload.DKGProposalPayload.Quorum[participant.ParticipantId] = &internal.DKGProposalParticipant{
Title: participant.Title,
request, ok := args[0].(requests.DefaultRequest)
if !ok {
err = errors.New("cannot cast {arg0} to type {DefaultRequest}")
return
}
m.payload.DKGProposalPayload = &internal.DKGConfirmation{
Quorum: make(internal.DKGProposalQuorum),
CreatedAt: request.CreatedAt,
ExpiresAt: request.CreatedAt.Add(config.DkgConfirmationDeadline),
}
for participantId, participant := range m.payload.SignatureProposalPayload.Quorum {
m.payload.DKGProposalPayload.Quorum[participantId] = &internal.DKGProposalParticipant{
Addr: participant.Addr,
Status: internal.CommitAwaitConfirmation,
UpdatedAt: participant.UpdatedAt,
}
copy(m.payload.DKGProposalPayload.Quorum[participant.ParticipantId].PubKey, participant.DkgPubKey)
copy(m.payload.DKGProposalPayload.Quorum[participantId].DkgPubKey, participant.DkgPubKey)
}
// Remove m.payload.SignatureProposalPayload?
@ -71,9 +88,11 @@ func (m *DKGProposalFSM) actionCommitConfirmationReceived(inEvent fsm.Event, arg
}
copy(dkgProposalParticipant.Commit, request.Commit)
dkgProposalParticipant.UpdatedAt = request.CreatedAt
dkgProposalParticipant.Status = internal.CommitConfirmed
dkgProposalParticipant.UpdatedAt = request.CreatedAt
m.payload.SignatureProposalPayload.UpdatedAt = request.CreatedAt
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
return
@ -163,9 +182,11 @@ func (m *DKGProposalFSM) actionDealConfirmationReceived(inEvent fsm.Event, args
}
copy(dkgProposalParticipant.Deal, request.Deal)
dkgProposalParticipant.UpdatedAt = request.CreatedAt
dkgProposalParticipant.Status = internal.DealConfirmed
dkgProposalParticipant.UpdatedAt = request.CreatedAt
m.payload.SignatureProposalPayload.UpdatedAt = request.CreatedAt
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
return
@ -255,9 +276,11 @@ func (m *DKGProposalFSM) actionResponseConfirmationReceived(inEvent fsm.Event, a
}
copy(dkgProposalParticipant.Response, request.Response)
dkgProposalParticipant.UpdatedAt = request.CreatedAt
dkgProposalParticipant.Status = internal.ResponseConfirmed
dkgProposalParticipant.UpdatedAt = request.CreatedAt
m.payload.SignatureProposalPayload.UpdatedAt = request.CreatedAt
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
return
@ -347,9 +370,11 @@ func (m *DKGProposalFSM) actionMasterKeyConfirmationReceived(inEvent fsm.Event,
}
copy(dkgProposalParticipant.MasterKey, request.MasterKey)
dkgProposalParticipant.UpdatedAt = request.CreatedAt
dkgProposalParticipant.Status = internal.MasterKeyConfirmed
dkgProposalParticipant.UpdatedAt = request.CreatedAt
m.payload.SignatureProposalPayload.UpdatedAt = request.CreatedAt
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)
return
@ -527,7 +552,9 @@ func (m *DKGProposalFSM) actionConfirmationError(inEvent fsm.Event, args ...inte
}
dkgProposalParticipant.Error = request.Error
dkgProposalParticipant.UpdatedAt = request.CreatedAt
m.payload.SignatureProposalPayload.UpdatedAt = request.CreatedAt
m.payload.DKGQuorumUpdate(request.ParticipantId, dkgProposalParticipant)

View File

@ -1,6 +1,11 @@
package internal
import "github.com/depools/dc4bc/fsm/fsm_pool"
import (
"crypto/ed25519"
"encoding/hex"
"errors"
"github.com/depools/dc4bc/fsm/fsm_pool"
)
type DumpedMachineProvider interface {
fsm_pool.MachineProvider
@ -10,10 +15,11 @@ type DumpedMachineProvider interface {
// DKG and other stages quorums are separated,
// because unnecessary data may be unset
type DumpedMachineStatePayload struct {
TransactionId string
DkgId string
SignatureProposalPayload *SignatureConfirmation
DKGProposalPayload *DKGConfirmation
SigningProposalPayload *SigningConfirmation
pubKeys map[string]ed25519.PublicKey
}
// Signature quorum
@ -26,7 +32,7 @@ func (p *DumpedMachineStatePayload) SigQuorumCount() int {
return count
}
func (p *DumpedMachineStatePayload) SigQuorumExists(id string) bool {
func (p *DumpedMachineStatePayload) SigQuorumExists(id int) bool {
var exists bool
if p.SignatureProposalPayload.Quorum != nil {
_, exists = p.SignatureProposalPayload.Quorum[id]
@ -34,14 +40,14 @@ func (p *DumpedMachineStatePayload) SigQuorumExists(id string) bool {
return exists
}
func (p *DumpedMachineStatePayload) SigQuorumGet(id string) (participant *SignatureProposalParticipant) {
func (p *DumpedMachineStatePayload) SigQuorumGet(id int) (participant *SignatureProposalParticipant) {
if p.SignatureProposalPayload.Quorum != nil {
participant, _ = p.SignatureProposalPayload.Quorum[id]
}
return
}
func (p *DumpedMachineStatePayload) SigQuorumUpdate(id string, participant *SignatureProposalParticipant) {
func (p *DumpedMachineStatePayload) SigQuorumUpdate(id int, participant *SignatureProposalParticipant) {
if p.SignatureProposalPayload.Quorum != nil {
p.SignatureProposalPayload.Quorum[id] = participant
}
@ -111,3 +117,27 @@ func (p *DumpedMachineStatePayload) SigningQuorumUpdate(id int, participant *Sig
}
return
}
func (p *DumpedMachineStatePayload) SetAddrHexPubKey(addr string, key ed25519.PublicKey) {
if p.pubKeys == nil {
p.pubKeys = make(map[string]ed25519.PublicKey)
}
hexKey := hex.EncodeToString([]byte(addr))
p.pubKeys[hexKey] = key
return
}
func (p *DumpedMachineStatePayload) GetPubKeyByAddr(addr string) (ed25519.PublicKey, error) {
if p.pubKeys == nil {
return nil, errors.New("{pubKeys} not initialized")
}
if addr == "" {
return nil, errors.New("{addr} cannot be empty")
}
pubKey, ok := p.pubKeys[addr]
if !ok {
return nil, errors.New("cannot find public key by {addr}")
}
return pubKey, nil
}

View File

@ -1,7 +1,7 @@
package internal
import (
"crypto/rsa"
"crypto/ed25519"
"time"
)
@ -32,24 +32,23 @@ func (s ConfirmationParticipantStatus) String() string {
type SignatureConfirmation struct {
Quorum SignatureProposalQuorum
CreatedAt time.Time
UpdatedAt time.Time
ExpiresAt time.Time
}
type SignatureProposalParticipant struct {
// Public title for address, such as name, nickname, organization
ParticipantId int
Title string
PubKey []byte
DkgPubKey []byte
Addr string
PubKey ed25519.PublicKey
DkgPubKey []byte
// For validation user confirmation: sign(InvitationSecret, PubKey) => user
InvitationSecret string
Status ParticipantStatus
Status ConfirmationParticipantStatus
UpdatedAt time.Time
}
// Unique alias for map iteration - Public Key Fingerprint
// Excludes array merge and rotate operations
type SignatureProposalQuorum map[string]*SignatureProposalParticipant
type SignatureProposalQuorum map[int]*SignatureProposalParticipant
// DKG proposal
@ -71,8 +70,8 @@ const (
)
type DKGProposalParticipant struct {
Title string
PubKey []byte
Addr string
DkgPubKey []byte
Commit []byte
Deal []byte
Response []byte
@ -86,8 +85,9 @@ type DKGProposalQuorum map[int]*DKGProposalParticipant
type DKGConfirmation struct {
Quorum DKGProposalQuorum
CreatedAt *time.Time
ExpiresAt *time.Time
CreatedAt time.Time
UpdatedAt time.Time
ExpiresAt time.Time
}
type DKGProposalParticipantStatus uint8
@ -131,6 +131,7 @@ type SigningConfirmation struct {
SrcPayload []byte
EncryptedPayload []byte
CreatedAt time.Time
UpdatedAt time.Time
ExpiresAt time.Time
}
@ -171,7 +172,7 @@ func (s SigningParticipantStatus) String() string {
}
type SigningProposalParticipant struct {
Title string
Addr string
Status SigningParticipantStatus
PartialKey []byte
Error error

View File

@ -87,7 +87,11 @@ func FromDump(data []byte) (*FSMInstance, error) {
}
func (i *FSMInstance) GetPubKeyByAddr(addr string) (ed25519.PublicKey, error) {
return ed25519.PublicKey{}, nil
if i.dump == nil {
return nil, errors.New("dump not initialized")
}
return i.dump.Payload.GetPubKeyByAddr(addr)
}
func (i *FSMInstance) Do(event fsm.Event, args ...interface{}) (result *fsm.Response, dump []byte, err error) {
@ -112,22 +116,22 @@ func (i *FSMInstance) Do(event fsm.Event, args ...interface{}) (result *fsm.Resp
return result, dump, err
}
func (i *FSMInstance) InitDump(transactionId string) error {
func (i *FSMInstance) InitDump(dkgID string) error {
if i.dump != nil {
return errors.New("dump already initialized")
}
transactionId = strings.TrimSpace(transactionId)
dkgID = strings.TrimSpace(dkgID)
if transactionId == "" {
return errors.New("empty transaction id")
if dkgID == "" {
return errors.New("empty {dkgID}")
}
i.dump = &FSMDump{
TransactionId: transactionId,
TransactionId: dkgID,
State: fsm.StateGlobalIdle,
Payload: &internal.DumpedMachineStatePayload{
TransactionId: transactionId,
DkgId: dkgID,
SignatureProposalPayload: nil,
DKGProposalPayload: nil,
},

View File

@ -3,9 +3,7 @@ package state_machines
import (
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"fmt"
"log"
"testing"
@ -19,7 +17,7 @@ import (
)
type testExternalParticipants struct {
Title string
Addr string
PrivKey *rsa.PrivateKey
PubKey *rsa.PublicKey
DkgPubKey []byte
@ -28,7 +26,9 @@ type testExternalParticipants struct {
var (
tm = time.Now()
testParticipants = map[string]*testExternalParticipants{}
dkgId = "1b7a6382afe0fbe2ff127a5779f5e9b042e685cabefeadcf4ef27c6089a56bfb"
testParticipants = map[int]*testExternalParticipants{}
testParticipantsListRequest = requests.SignatureProposalParticipantsListRequest{
Participants: []*requests.SignatureProposalParticipantsEntry{},
@ -52,22 +52,17 @@ func init() {
key.Precompute()
marshaledPubKey := x509.MarshalPKCS1PublicKey(&key.PublicKey)
hash := sha1.Sum(marshaledPubKey)
fingerprint := base64.StdEncoding.EncodeToString(hash[:])
pubKeyMock := make([]byte, 128)
rand.Read(pubKeyMock)
participant := &testExternalParticipants{
Title: fmt.Sprintf("User %d", i),
Addr: fmt.Sprintf("User %d", i),
PrivKey: key,
PubKey: &key.PublicKey,
DkgPubKey: pubKeyMock,
}
testParticipants[fingerprint] = participant
testParticipants[i] = participant
}
participantsForRequest := make([]*requests.SignatureProposalParticipantsEntry, 0)
@ -75,7 +70,7 @@ func init() {
for _, participant := range testParticipants {
participantsForRequest = append(participantsForRequest, &requests.SignatureProposalParticipantsEntry{
Addr: participant.Title,
Addr: participant.Addr,
PubKey: x509.MarshalPKCS1PublicKey(participant.PubKey),
DkgPubKey: participant.DkgPubKey,
})
@ -85,7 +80,7 @@ func init() {
}
func TestCreate_Positive(t *testing.T) {
testFSMInstance, err := Create()
testFSMInstance, err := Create(dkgId)
if err != nil {
t.Fatalf("expected nil error, got {%s}", err)
}
@ -128,7 +123,7 @@ func compareState(t *testing.T, expected fsm.State, got fsm.State) {
// Test Workflow
func Test_SignatureProposal_Init(t *testing.T) {
testFSMInstance, err := Create()
testFSMInstance, err := Create(dkgId)
compareErrNil(t, err)
@ -187,18 +182,10 @@ func Test_SignatureProposal_Positive(t *testing.T) {
t.Fatalf("expected unique {ParticipantId}")
}
if participant.Title == "" {
if participant.Addr == "" {
t.Fatalf("expected not empty {Addr}")
}
if participant.EncryptedInvitation == "" {
t.Fatalf("expected not empty {DecryptedInvitation}")
}
if participant.PubKeyFingerprint == "" {
t.Fatalf("expected not empty {PubKeyFingerprint}")
}
participantsMap[participant.ParticipantId] = participant
}
@ -216,21 +203,9 @@ func Test_SignatureProposal_Positive(t *testing.T) {
compareFSMInstanceNotNil(t, testFSMInstance)
if _, ok := testParticipants[participant.PubKeyFingerprint]; !ok {
t.Fatalf("not found external user data for response fingerprint")
}
r := rand.Reader
encrypted, err := rsa.DecryptPKCS1v15(r, testParticipants[participant.PubKeyFingerprint].PrivKey, []byte(participant.EncryptedInvitation))
if err != nil {
t.Fatalf("cannot encrypt {DecryptedInvitation} with private key")
}
fsmResponse, dump, err = testFSMInstance.Do(spf.EventConfirmSignatureProposal, requests.SignatureProposalParticipantRequest{
PubKeyFingerprint: participant.PubKeyFingerprint,
DecryptedInvitation: string(encrypted),
CreatedAt: tm,
ParticipantId: participant.ParticipantId,
CreatedAt: tm,
})
compareErrNil(t, err)
@ -249,7 +224,9 @@ func Test_SignatureProposal_Positive(t *testing.T) {
testFSMInstance, err = FromDump(dump)
fsmResponse, dump, err = testFSMInstance.Do(dpf.EventDKGInitProcess)
fsmResponse, dump, err = testFSMInstance.Do(dpf.EventDKGInitProcess, requests.DefaultRequest{
CreatedAt: time.Now(),
})
compareErrNil(t, err)
@ -269,7 +246,7 @@ func Test_SignatureProposal_Positive(t *testing.T) {
compareFSMInstanceNotNil(t, testFSMInstance)
if _, ok := testParticipants[participant.PubKeyFingerprint]; !ok {
if _, ok := testParticipants[participant.ParticipantId]; !ok {
t.Fatalf("not found external user data for response fingerprint")
}
@ -305,7 +282,7 @@ func Test_SignatureProposal_Positive(t *testing.T) {
compareFSMInstanceNotNil(t, testFSMInstance)
if _, ok := testParticipants[participant.PubKeyFingerprint]; !ok {
if _, ok := testParticipants[participant.ParticipantId]; !ok {
t.Fatalf("not found external user data for response fingerprint")
}
@ -341,7 +318,7 @@ func Test_SignatureProposal_Positive(t *testing.T) {
compareFSMInstanceNotNil(t, testFSMInstance)
if _, ok := testParticipants[participant.PubKeyFingerprint]; !ok {
if _, ok := testParticipants[participant.ParticipantId]; !ok {
t.Fatalf("not found external user data for response fingerprint")
}
@ -383,7 +360,7 @@ func Test_SignatureProposal_Positive(t *testing.T) {
compareFSMInstanceNotNil(t, testFSMInstance)
if _, ok := testParticipants[participant.PubKeyFingerprint]; !ok {
if _, ok := testParticipants[participant.ParticipantId]; !ok {
t.Fatalf("not found external user data for response fingerprint")
}

View File

@ -35,19 +35,22 @@ func (m *SignatureProposalFSM) actionInitSignatureProposal(inEvent fsm.Event, ar
}
m.payload.SignatureProposalPayload = &internal.SignatureConfirmation{
Quorum: make(internal.SignatureProposalQuorum),
Quorum: make(internal.SignatureProposalQuorum),
CreatedAt: request.CreatedAt,
ExpiresAt: request.CreatedAt.Add(config.SignatureProposalConfirmationDeadline),
}
for index, participant := range request.Participants {
participantId := createFingerprint(&participant.PubKey)
m.payload.SignatureProposalPayload.Quorum[participantId] = &internal.SignatureProposalParticipant{
ParticipantId: index,
Title: participant.Addr,
PubKey: participant.PubKey,
DkgPubKey: participant.DkgPubKey,
Status: internal.SignatureConfirmationAwaitConfirmation,
UpdatedAt: request.CreatedAt,
//participantId := createFingerprint(&participant.DkgPubKey)
m.payload.SignatureProposalPayload.Quorum[index] = &internal.SignatureProposalParticipant{
Addr: participant.Addr,
PubKey: participant.PubKey,
DkgPubKey: participant.DkgPubKey,
Status: internal.SigConfirmationAwaitConfirmation,
UpdatedAt: request.CreatedAt,
}
m.payload.SetAddrHexPubKey(participant.Addr, participant.PubKey)
}
// Checking fo quorum length
@ -60,11 +63,10 @@ func (m *SignatureProposalFSM) actionInitSignatureProposal(inEvent fsm.Event, ar
responseData := make(responses.SignatureProposalParticipantInvitationsResponse, 0)
for pubKeyFingerprint, proposal := range m.payload.SignatureProposalPayload.Quorum {
for participantId, proposal := range m.payload.SignatureProposalPayload.Quorum {
responseEntry := &responses.SignatureProposalParticipantInvitationEntry{
ParticipantId: proposal.ParticipantId,
Title: proposal.Title,
PubKeyFingerprint: pubKeyFingerprint,
ParticipantId: participantId,
Addr: proposal.Addr,
}
responseData = append(responseData, responseEntry)
}
@ -94,12 +96,12 @@ func (m *SignatureProposalFSM) actionProposalResponseByParticipant(inEvent fsm.E
return
}
if !m.payload.SigQuorumExists(request.PubKeyFingerprint) {
err = errors.New("{PubKeyFingerprint} not exist in quorum")
if !m.payload.SigQuorumExists(request.ParticipantId) {
err = errors.New("{ParticipantId} not exist in quorum")
return
}
signatureProposalParticipant := m.payload.SigQuorumGet(request.PubKeyFingerprint)
signatureProposalParticipant := m.payload.SigQuorumGet(request.ParticipantId)
if signatureProposalParticipant.UpdatedAt.Add(config.SignatureProposalConfirmationDeadline).Before(request.CreatedAt) {
outEvent = eventSetValidationCanceledByTimeout
return
@ -122,7 +124,7 @@ func (m *SignatureProposalFSM) actionProposalResponseByParticipant(inEvent fsm.E
signatureProposalParticipant.UpdatedAt = request.CreatedAt
m.payload.SigQuorumUpdate(request.PubKeyFingerprint, signatureProposalParticipant)
m.payload.SigQuorumUpdate(request.ParticipantId, signatureProposalParticipant)
return
}
@ -169,11 +171,10 @@ func (m *SignatureProposalFSM) actionValidateSignatureProposal(inEvent fsm.Event
responseData := make(responses.SignatureProposalParticipantStatusResponse, 0)
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
for participantId, participant := range m.payload.SignatureProposalPayload.Quorum {
responseEntry := &responses.SignatureProposalParticipantStatusEntry{
ParticipantId: participant.ParticipantId,
Title: participant.Title,
DkgPubKey: participant.DkgPubKey,
ParticipantId: participantId,
Addr: participant.Addr,
Status: uint8(participant.Status),
}
responseData = append(responseData, responseEntry)
@ -188,10 +189,10 @@ func (m *SignatureProposalFSM) actionSignatureProposalCanceledByTimeout(inEvent
responseData := make(responses.SignatureProposalParticipantStatusResponse, 0)
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
for participantId, participant := range m.payload.SignatureProposalPayload.Quorum {
responseEntry := &responses.SignatureProposalParticipantStatusEntry{
ParticipantId: participant.ParticipantId,
Title: participant.Title,
ParticipantId: participantId,
Addr: participant.Addr,
Status: uint8(participant.Status),
}
responseData = append(responseData, responseEntry)

View File

@ -14,10 +14,9 @@ import (
func ProposalParticipantsQuorumToResponse(list *internal.SignatureProposalQuorum) responses.SignatureProposalParticipantInvitationsResponse {
var response responses.SignatureProposalParticipantInvitationsResponse
for quorumId, participant := range *list {
for _, participant := range *list {
response = append(response, &responses.SignatureProposalParticipantInvitationEntry{
Title: participant.Title,
PubKeyFingerprint: quorumId,
Addr: participant.Addr,
})
}
return response

View File

@ -14,14 +14,31 @@ func (m *SigningProposalFSM) actionInitSigningProposal(inEvent fsm.Event, args .
m.payloadMu.Lock()
defer m.payloadMu.Unlock()
m.payload.SigningProposalPayload = &internal.SigningConfirmation{
Quorum: make(internal.SigningProposalQuorum),
// CreatedAt:
if len(args) != 1 {
err = errors.New("{arg0} required {DefaultRequest}")
return
}
for _, participant := range m.payload.SignatureProposalPayload.Quorum {
m.payload.SigningProposalPayload.Quorum[participant.ParticipantId] = &internal.SigningProposalParticipant{
Title: participant.Title,
request, ok := args[0].(requests.DefaultRequest)
if !ok {
err = errors.New("cannot cast {arg0} to type {DefaultRequest}")
return
}
if err = request.Validate(); err != nil {
return
}
m.payload.SigningProposalPayload = &internal.SigningConfirmation{
Quorum: make(internal.SigningProposalQuorum),
CreatedAt: request.CreatedAt,
ExpiresAt: request.CreatedAt.Add(config.SigningConfirmationDeadline),
}
for participantId, participant := range m.payload.SignatureProposalPayload.Quorum {
m.payload.SigningProposalPayload.Quorum[participantId] = &internal.SigningProposalParticipant{
Addr: participant.Addr,
Status: internal.SigningIdle,
UpdatedAt: participant.UpdatedAt,
}
@ -50,6 +67,8 @@ func (m *SigningProposalFSM) actionStartSigningProposal(inEvent fsm.Event, args
return
}
m.payload.SigningProposalPayload.CreatedAt = request.CreatedAt
return
}

View File

@ -24,7 +24,6 @@ type SignatureProposalParticipantsEntry struct {
// "event_sig_proposal_decline_by_participant"
type SignatureProposalParticipantRequest struct {
// Key for link invitations to participants
PubKeyFingerprint string
DecryptedInvitation string
CreatedAt time.Time
ParticipantId int
CreatedAt time.Time
}

View File

@ -46,12 +46,8 @@ func (r *SignatureProposalParticipantsListRequest) Validate() error {
}
func (r *SignatureProposalParticipantRequest) Validate() error {
if len(r.PubKeyFingerprint) == 0 {
return errors.New("{PubKeyFingerprint} cannot zero length")
}
if len(r.DecryptedInvitation) == 0 {
return errors.New("{DecryptedInvitation} cannot zero length")
if r.ParticipantId < 0 {
return errors.New("{ParticipantId} cannot be a negative number")
}
if r.CreatedAt.IsZero() {

View File

@ -10,11 +10,7 @@ type SignatureProposalParticipantInvitationsResponse []*SignatureProposalPartici
type SignatureProposalParticipantInvitationEntry struct {
ParticipantId int
// Public title for address, such as name, nickname, organization
Title string
// Key for link invitations to participants
PubKeyFingerprint string
// Encrypted with public key secret
EncryptedInvitation string
Addr string
}
// Public lists for proposal confirmation process
@ -23,7 +19,6 @@ type SignatureProposalParticipantStatusResponse []*SignatureProposalParticipantS
type SignatureProposalParticipantStatusEntry struct {
ParticipantId int
Title string
DkgPubKey []byte
Addr string
Status uint8
}