mirror of https://github.com/certusone/dc4bc.git
Merge branch 'master' into feat/client-fsm
This commit is contained in:
commit
cbd8257489
|
@ -13,9 +13,9 @@ func main() {
|
|||
fsmMachine, err := state_machines.New([]byte{})
|
||||
log.Println(fsmMachine, err)
|
||||
resp, dump, err := fsmMachine.Do(
|
||||
"proposal_init",
|
||||
"event_proposal_init",
|
||||
"d8a928b2043db77e340b523547bf16cb4aa483f0645fe0a290ed1f20aab76257",
|
||||
requests.ProposalParticipantsListRequest{
|
||||
requests.SignatureProposalParticipantsListRequest{
|
||||
{
|
||||
"John Doe",
|
||||
[]byte("pubkey123123"),
|
||||
|
@ -41,7 +41,7 @@ func processResponse(resp *fsm.Response) {
|
|||
switch resp.State {
|
||||
// Await proposals
|
||||
case fsm.State("validate_proposal"):
|
||||
data, ok := resp.Data.(responses.ProposalParticipantInvitationsResponse)
|
||||
data, ok := resp.Data.(responses.SignatureProposalParticipantInvitationsResponse)
|
||||
if !ok {
|
||||
log.Printf("undefined response type for state \"%s\"\n", resp.State)
|
||||
return
|
||||
|
@ -57,7 +57,7 @@ func processResponse(resp *fsm.Response) {
|
|||
}
|
||||
}
|
||||
|
||||
func sendInvitations(invitations responses.ProposalParticipantInvitationsResponse) {
|
||||
func sendInvitations(invitations responses.SignatureProposalParticipantInvitationsResponse) {
|
||||
for _, invitation := range invitations {
|
||||
log.Printf(
|
||||
"Dear %s, please encrypt value \"%s\" with your key, fingerprint: %s\n",
|
||||
|
|
|
@ -73,8 +73,10 @@ type trKey struct {
|
|||
|
||||
// Transition lightweight event description
|
||||
type trEvent struct {
|
||||
event Event
|
||||
dstState State
|
||||
isInternal bool
|
||||
isDstInit bool
|
||||
}
|
||||
|
||||
type EventDesc struct {
|
||||
|
@ -87,6 +89,9 @@ type EventDesc struct {
|
|||
|
||||
// Internal events, cannot be emitted from external call
|
||||
IsInternal bool
|
||||
|
||||
// Set dst state before execute action
|
||||
IsDstInit bool
|
||||
}
|
||||
|
||||
type Callback func(event Event, args ...interface{}) (interface{}, error)
|
||||
|
@ -168,7 +173,12 @@ func MustNewFSM(machineName string, initialState State, events []EventDesc, call
|
|||
panic("duplicate dst for pair `source + event`")
|
||||
}
|
||||
|
||||
f.transitions[tKey] = &trEvent{event.DstState, event.IsInternal}
|
||||
f.transitions[tKey] = &trEvent{
|
||||
tKey.event,
|
||||
event.DstState,
|
||||
event.IsInternal,
|
||||
event.IsDstInit,
|
||||
}
|
||||
|
||||
// For using provider, event must use with IsGlobal = true
|
||||
if sourceState == initialState {
|
||||
|
@ -221,34 +231,58 @@ func MustNewFSM(machineName string, initialState State, events []EventDesc, call
|
|||
return f
|
||||
}
|
||||
|
||||
func (f *FSM) Do(event Event, args ...interface{}) (resp *Response, err error) {
|
||||
f.eventMu.Lock()
|
||||
defer f.eventMu.Unlock()
|
||||
|
||||
func (f *FSM) DoInternal(event Event, args ...interface{}) (resp *Response, err error) {
|
||||
trEvent, ok := f.transitions[trKey{f.currentState, event}]
|
||||
if !ok {
|
||||
return nil, errors.New("cannot execute event for this state")
|
||||
return nil, errors.New(fmt.Sprintf("cannot execute event \"%s\" for state \"%s\"", event, f.currentState))
|
||||
}
|
||||
|
||||
return f.do(trEvent, args...)
|
||||
}
|
||||
|
||||
func (f *FSM) Do(event Event, args ...interface{}) (resp *Response, err error) {
|
||||
trEvent, ok := f.transitions[trKey{f.currentState, event}]
|
||||
if !ok {
|
||||
return nil, errors.New(fmt.Sprintf("cannot execute event \"%s\" for state \"%s\"", event, f.currentState))
|
||||
}
|
||||
if trEvent.isInternal {
|
||||
return nil, errors.New("event is internal")
|
||||
}
|
||||
|
||||
return f.do(trEvent, args...)
|
||||
}
|
||||
func (f *FSM) do(trEvent *trEvent, args ...interface{}) (resp *Response, err error) {
|
||||
// f.eventMu.Lock()
|
||||
// defer f.eventMu.Unlock()
|
||||
|
||||
if trEvent.isDstInit {
|
||||
err = f.SetState(trEvent.event)
|
||||
if err != nil {
|
||||
resp = &Response{
|
||||
State: f.State(),
|
||||
}
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
||||
resp = &Response{
|
||||
State: f.State(),
|
||||
}
|
||||
|
||||
if callback, ok := f.callbacks[event]; ok {
|
||||
resp.Data, err = callback(event, args...)
|
||||
if callback, ok := f.callbacks[trEvent.event]; ok {
|
||||
resp.Data, err = callback(trEvent.event, args...)
|
||||
// Do not try change state on error
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
}
|
||||
|
||||
err = f.setState(event)
|
||||
if err == nil {
|
||||
resp.State = f.currentState
|
||||
if !trEvent.isDstInit {
|
||||
err = f.SetState(trEvent.event)
|
||||
}
|
||||
|
||||
resp.State = f.State()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -259,9 +293,9 @@ func (f *FSM) State() State {
|
|||
return f.currentState
|
||||
}
|
||||
|
||||
// setState allows the user to move to the given state from currentState state.
|
||||
// SetState allows the user to move to the given state from currentState state.
|
||||
// The call does not trigger any callbacks, if defined.
|
||||
func (f *FSM) setState(event Event) error {
|
||||
func (f *FSM) SetState(event Event) error {
|
||||
f.stateMu.Lock()
|
||||
defer f.stateMu.Unlock()
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package fsm_pool
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
)
|
||||
|
@ -15,6 +16,8 @@ type MachineProvider interface {
|
|||
|
||||
InitialState() fsm.State
|
||||
|
||||
State() fsm.State
|
||||
|
||||
// Process event
|
||||
Do(event fsm.Event, args ...interface{}) (*fsm.Response, error)
|
||||
|
||||
|
@ -75,7 +78,7 @@ func Init(machines ...MachineProvider) *FSMPool {
|
|||
machineEvents := machine.EventsList()
|
||||
for _, event := range machineEvents {
|
||||
if _, exists := p.events[event]; exists {
|
||||
panic("duplicate public event")
|
||||
panic(fmt.Sprintf("duplicate public event \"%s\"", event))
|
||||
}
|
||||
p.events[event] = machineName
|
||||
}
|
||||
|
@ -106,7 +109,7 @@ func Init(machines ...MachineProvider) *FSMPool {
|
|||
}
|
||||
}
|
||||
if name, exists := p.states[state]; exists && name != machineName {
|
||||
panic("duplicate state for machines")
|
||||
panic(fmt.Sprintf("duplicate state for machines \"%s\"", state))
|
||||
}
|
||||
|
||||
p.states[state] = machineName
|
||||
|
@ -120,8 +123,6 @@ func Init(machines ...MachineProvider) *FSMPool {
|
|||
}
|
||||
|
||||
func (p *FSMPool) EntryPointMachine() (MachineProvider, error) {
|
||||
// StateGlobalIdle
|
||||
// TODO: Short code
|
||||
entryStateMachineName := p.events[p.fsmInitialEvent]
|
||||
|
||||
machine, exists := p.mapper[entryStateMachineName]
|
||||
|
@ -142,6 +143,7 @@ func (p *FSMPool) MachineByEvent(event fsm.Event) (MachineProvider, error) {
|
|||
return machine, nil
|
||||
}
|
||||
|
||||
// Out states now is not returns machine
|
||||
func (p *FSMPool) MachineByState(state fsm.State) (MachineProvider, error) {
|
||||
eventMachineName := p.states[state]
|
||||
machine, exists := p.mapper[eventMachineName]
|
||||
|
|
|
@ -1,18 +1,284 @@
|
|||
package fsm_pool
|
||||
|
||||
/*
|
||||
import (
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
type testMachineFSM1 struct {
|
||||
*fsm.FSM
|
||||
data int
|
||||
}
|
||||
|
||||
func Test_InitPool(t *testing.T) {
|
||||
const (
|
||||
testVal1 = 100
|
||||
testVal2 = 17
|
||||
)
|
||||
|
||||
} */
|
||||
const (
|
||||
fsm1Name = "fsm1"
|
||||
// Init process from global idle state
|
||||
fsm1StateInit = fsm.StateGlobalIdle
|
||||
// Set up data
|
||||
fsm1StateStage1 = fsm.State("state_fsm1_stage1")
|
||||
// Process data
|
||||
fsm1StateStage2 = fsm.State("state_fsm1_stage2")
|
||||
// Cancelled with internal event
|
||||
fsm1StateCanceledByInternal = fsm.State("state_fsm1_canceled")
|
||||
// Cancelled with external event
|
||||
fsm1StateCanceled2 = fsm.State("state_fsm1_canceled2")
|
||||
// Out endpoint to switch
|
||||
fsm1StateOutToFSM2 = fsm.State("state_fsm1_out_to_fsm2")
|
||||
|
||||
// Events
|
||||
eventFSM1Init = fsm.Event("event_fsm1_init")
|
||||
eventFSM1Cancel = fsm.Event("event_fsm1_cancel")
|
||||
eventFSM1Process = fsm.Event("event_fsm1_process")
|
||||
|
||||
// Internal events
|
||||
eventFSM1Internal = fsm.Event("event_internal_fsm1")
|
||||
eventFSM1CancelByInternal = fsm.Event("event_internal_fsm1_cancel")
|
||||
eventFSM1InternalOut2 = fsm.Event("event_internal_fsm1_out")
|
||||
)
|
||||
|
||||
var (
|
||||
testing1Events = []fsm.EventDesc{
|
||||
// Init
|
||||
{Name: eventFSM1Init, SrcState: []fsm.State{fsm1StateInit}, DstState: fsm1StateStage1, IsDstInit: true},
|
||||
{Name: eventFSM1Internal, SrcState: []fsm.State{fsm1StateStage1}, DstState: fsm1StateStage2, IsInternal: true},
|
||||
|
||||
// Cancellation events
|
||||
{Name: eventFSM1CancelByInternal, SrcState: []fsm.State{fsm1StateStage2}, DstState: fsm1StateCanceledByInternal, IsInternal: true},
|
||||
{Name: eventFSM1Cancel, SrcState: []fsm.State{fsm1StateStage2}, DstState: fsm1StateCanceled2},
|
||||
|
||||
// Out
|
||||
{Name: eventFSM1Process, SrcState: []fsm.State{fsm1StateStage2}, DstState: fsm1StateOutToFSM2},
|
||||
{Name: eventFSM1InternalOut2, SrcState: []fsm.State{fsm1StateStage2}, DstState: fsm1StateOutToFSM2, IsInternal: true},
|
||||
}
|
||||
)
|
||||
|
||||
func NewFSM1() MachineProvider {
|
||||
machine := &testMachineFSM1{}
|
||||
|
||||
machine.FSM = fsm.MustNewFSM(
|
||||
fsm1Name,
|
||||
fsm1StateInit,
|
||||
testing1Events,
|
||||
fsm.Callbacks{
|
||||
eventFSM1Init: machine.actionFSM1SetUpData,
|
||||
eventFSM1InternalOut2: machine.actionFSM1EmitOut2,
|
||||
eventFSM1Process: machine.actionFSM1ProcessData,
|
||||
},
|
||||
)
|
||||
return machine
|
||||
}
|
||||
|
||||
func (m *testMachineFSM1) actionFSM1SetUpData(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
m.data = testVal1
|
||||
return m.DoInternal(eventFSM1Internal)
|
||||
}
|
||||
|
||||
func (m *testMachineFSM1) actionFSM1ProcessData(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
if len(args) == 1 {
|
||||
if val, ok := args[0].(int); ok {
|
||||
m.data -= val
|
||||
}
|
||||
}
|
||||
return m.data, nil
|
||||
}
|
||||
|
||||
func (m *testMachineFSM1) actionFSM1EmitOut2(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// Second test machine
|
||||
|
||||
type testMachineFSM2 struct {
|
||||
*fsm.FSM
|
||||
data int
|
||||
}
|
||||
|
||||
const (
|
||||
fsm2Name = "fsm2"
|
||||
// Init process from global idle state
|
||||
fsm2StateInit = fsm1StateOutToFSM2
|
||||
// Process data
|
||||
fsm2StateStage1 = fsm.State("state_fsm2_stage1")
|
||||
fsm2StateStage2 = fsm.State("state_fsm2_stage2")
|
||||
// Cancelled with internal event
|
||||
fsm2StateCanceledByInternal = fsm.State("state_fsm2_canceled")
|
||||
// Out endpoint to switch
|
||||
fsm2StateOutToFSM3 = fsm.State("state_fsm2_out_to_fsm3")
|
||||
|
||||
// Events
|
||||
eventFSM2Init = fsm.Event("event_fsm2_init")
|
||||
eventFSM2Process = fsm.Event("event_fsm2_process")
|
||||
|
||||
// Internal events
|
||||
eventFSM2Internal = fsm.Event("event_internal_fsm2")
|
||||
eventFSM2CancelByInternal = fsm.Event("event_internal_fsm2_cancel")
|
||||
eventFSM2InternalOut = fsm.Event("event_internal_fsm2_out")
|
||||
)
|
||||
|
||||
var (
|
||||
testing2Events = []fsm.EventDesc{
|
||||
// Init
|
||||
{Name: eventFSM2Init, SrcState: []fsm.State{fsm2StateInit}, DstState: fsm2StateStage1},
|
||||
{Name: eventFSM2Internal, SrcState: []fsm.State{fsm2StateStage1}, DstState: fsm2StateStage2, IsInternal: true},
|
||||
|
||||
// Cancellation events
|
||||
{Name: eventFSM2CancelByInternal, SrcState: []fsm.State{fsm2StateStage2}, DstState: fsm2StateCanceledByInternal, IsInternal: true},
|
||||
|
||||
// Out
|
||||
{Name: eventFSM2Process, SrcState: []fsm.State{fsm2StateStage2}, DstState: fsm.StateGlobalDone},
|
||||
{Name: eventFSM2InternalOut, SrcState: []fsm.State{fsm2StateStage2}, DstState: fsm.StateGlobalDone, IsInternal: true},
|
||||
}
|
||||
|
||||
testing2Callbacks = fsm.Callbacks{}
|
||||
)
|
||||
|
||||
func NewFSM2() MachineProvider {
|
||||
machine := &testMachineFSM1{}
|
||||
|
||||
machine.FSM = fsm.MustNewFSM(
|
||||
fsm2Name,
|
||||
fsm2StateInit,
|
||||
testing2Events,
|
||||
testing2Callbacks,
|
||||
)
|
||||
return machine
|
||||
}
|
||||
|
||||
func (m *testMachineFSM2) actionFSM2SetUpData(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (m *testMachineFSM2) actionFSM2ProcessData(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func (m *testMachineFSM2) actionFSM2EmitOut2(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
var testPoolProvider *FSMPool
|
||||
|
||||
func init() {
|
||||
testPoolProvider = Init(
|
||||
NewFSM1(),
|
||||
NewFSM2(),
|
||||
)
|
||||
}
|
||||
|
||||
func TestFSMPool_Init_EventsMap(t *testing.T) {
|
||||
if len(testPoolProvider.events) == 0 {
|
||||
t.Errorf("expected initialized events map")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSMPool_Init_StatesMap(t *testing.T) {
|
||||
if len(testPoolProvider.states) == 0 {
|
||||
t.Errorf("expected initialized states map")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSMPool_EntryPointMachine(t *testing.T) {
|
||||
m, err := testPoolProvider.EntryPointMachine()
|
||||
|
||||
if err != nil || m.Name() != fsm1Name {
|
||||
t.Errorf("expected entry point machine")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSMPool_MachineByState(t *testing.T) {
|
||||
fsm1States := []fsm.State{
|
||||
fsm1StateInit,
|
||||
fsm1StateStage1,
|
||||
fsm1StateStage2,
|
||||
}
|
||||
|
||||
for _, state := range fsm1States {
|
||||
machine, err := testPoolProvider.MachineByState(state)
|
||||
if err != nil || machine.Name() != fsm1Name {
|
||||
t.Errorf("expected machine fsm1 for state \"%s\"", state)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
fsm2States := []fsm.State{
|
||||
fsm2StateInit,
|
||||
fsm2StateStage1,
|
||||
fsm2StateStage2,
|
||||
}
|
||||
|
||||
for _, state := range fsm2States {
|
||||
machine, err := testPoolProvider.MachineByState(state)
|
||||
if err != nil || machine.Name() != fsm2Name {
|
||||
t.Errorf("expected machine fsm2 for state \"%s\"", state)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSMPool_MachineByEvent(t *testing.T) {
|
||||
fsm1Events := []fsm.Event{
|
||||
eventFSM1Init,
|
||||
eventFSM1Cancel,
|
||||
eventFSM1Process,
|
||||
}
|
||||
|
||||
for _, event := range fsm1Events {
|
||||
machine, err := testPoolProvider.MachineByEvent(event)
|
||||
if err != nil || machine.Name() != fsm1Name {
|
||||
t.Errorf("expected machine fsm1 for event \"%s\"", event)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
fsm2Events := []fsm.Event{
|
||||
eventFSM2Init,
|
||||
eventFSM2Process,
|
||||
}
|
||||
|
||||
for _, event := range fsm2Events {
|
||||
machine, err := testPoolProvider.MachineByEvent(event)
|
||||
if err != nil || machine.Name() != fsm2Name {
|
||||
t.Errorf("expected machine fsm2 for event \"%s\"", event)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSMPool_WorkFlow(t *testing.T) {
|
||||
machine, err := testPoolProvider.MachineByState(fsm1StateInit)
|
||||
|
||||
if err != nil || machine.Name() != fsm1Name {
|
||||
t.Fatalf("expected machine fsm1 for state \"%s\"", fsm1StateInit)
|
||||
}
|
||||
|
||||
if machine.State() != fsm1StateInit {
|
||||
t.Fatalf("expected machine state \"%s\", got \"%s\"", fsm1StateInit, machine.State())
|
||||
}
|
||||
|
||||
resp, err := machine.Do(eventFSM1Init)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("expected response without error, got \"%s\"", err)
|
||||
}
|
||||
|
||||
if resp.State != fsm1StateStage2 {
|
||||
t.Fatalf("expected machine state \"%s\", got \"%s\"", fsm1StateStage2, resp.State)
|
||||
}
|
||||
|
||||
resp, err = machine.Do(eventFSM1Process, testVal2)
|
||||
|
||||
data, ok := resp.Data.(int)
|
||||
|
||||
if !ok {
|
||||
t.Fatalf("expected response data int, got \"%s\"", resp.Data)
|
||||
}
|
||||
|
||||
if data != (testVal1 - testVal2) {
|
||||
t.Fatalf("expected response data value, got \"%d\"", data)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
package dkg_commit_fsm
|
|
@ -1 +0,0 @@
|
|||
package dkg_deals_fsm
|
|
@ -0,0 +1,54 @@
|
|||
package dkg_proposal_fsm
|
||||
|
||||
import (
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Pub keys
|
||||
func (s *DKGProposalFSM) actionDKGPubKeysSent(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGPubKeysSent")
|
||||
return
|
||||
}
|
||||
|
||||
func (s *DKGProposalFSM) actionDKGPubKeyConfirmationReceived(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGPubKeyConfirmationReceived")
|
||||
return
|
||||
}
|
||||
|
||||
func (s *DKGProposalFSM) actionDKGPubKeyConfirmationError(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGPubKeyConfirmationError")
|
||||
return
|
||||
}
|
||||
|
||||
// Commits
|
||||
func (s *DKGProposalFSM) actionDKGCommitsSent(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGCommitsSent")
|
||||
return
|
||||
}
|
||||
|
||||
func (s *DKGProposalFSM) actionDKGCommitConfirmationReceived(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGCommitConfirmationReceived")
|
||||
return
|
||||
}
|
||||
|
||||
func (s *DKGProposalFSM) actionDKGCommitConfirmationError(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGCommitConfirmationError")
|
||||
return
|
||||
}
|
||||
|
||||
// Deals
|
||||
func (s *DKGProposalFSM) actionDKGDealsSent(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGDealsSent")
|
||||
return
|
||||
}
|
||||
|
||||
func (s *DKGProposalFSM) actionDKGDealConfirmationReceived(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGDealConfirmationReceived")
|
||||
return
|
||||
}
|
||||
|
||||
func (s *DKGProposalFSM) actionDKGDealConfirmationError(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||
log.Println("I'm actionDKGDealConfirmationError")
|
||||
return
|
||||
}
|
|
@ -1 +1,133 @@
|
|||
package dkg_proposal_fsm
|
||||
|
||||
import (
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"github.com/depools/dc4bc/fsm/fsm_pool"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/signature_proposal_fsm"
|
||||
)
|
||||
|
||||
const (
|
||||
fsmName = "dkg_proposal_fsm"
|
||||
|
||||
StateDkgInitial = signature_proposal_fsm.StateValidationCompleted
|
||||
// Sending dkg pub keys
|
||||
StateDkgPubKeysSendingRequired = fsm.State("state_dkg_pub_keys_sending_required")
|
||||
|
||||
StateDkgPubKeysSendingAwaitConfirmations = fsm.State("state_dkg_pub_keys_sending_await_confirmations")
|
||||
// Cancelled
|
||||
StateDkgPubKeysSendingCancelled = fsm.State("state_dkg_pub_keys_sending_cancelled")
|
||||
StateDkgPubKeysSendingCancelledByTimeout = fsm.State("state_dkg_pub_keys_sending_cancelled_by_timeout")
|
||||
// Confirmed
|
||||
StateDkgPubKeysSendingConfirmed = fsm.State("state_dkg_pub_keys_sending_confirmed")
|
||||
|
||||
// Sending dkg commits
|
||||
StateDkgCommitsSendingRequired = fsm.State("state_dkg_commits_sending_required")
|
||||
StateDkgCommitsSendingAwaitConfirmations = fsm.State("state_dkg_commits_sending_await_confirmations")
|
||||
// Cancelled
|
||||
StateDkgCommitsSendingCancelled = fsm.State("state_dkg_commits_sending_cancelled")
|
||||
StateDkgCommitsSendingCancelledByTimeout = fsm.State("state_dkg_commits_sending_cancelled_by_timeout")
|
||||
// Confirmed
|
||||
StateDkgCommitsSendingConfirmed = fsm.State("state_dkg_commits_sending_confirmed")
|
||||
|
||||
// Sending dkg deals
|
||||
StateDkgDealsSendingRequired = fsm.State("state_dkg_deals_sending_required")
|
||||
StateDkgDealsSendingAwaitConfirmations = fsm.State("state_dkg_deals_sending_await_confirmations")
|
||||
// Cancelled
|
||||
StateDkgDealsSendingCancelled = fsm.State("state_dkg_deals_sending_cancelled")
|
||||
StateDkgDealsSendingCancelledByTimeout = fsm.State("state_dkg_deals_sending_cancelled_by_timeout")
|
||||
// Confirmed
|
||||
StateDkgDealsSendingConfirmed = fsm.State("state_dkg_deals_sending_confirmed")
|
||||
|
||||
// Events
|
||||
EventDKGPubKeysSendingRequiredInternal = fsm.Event("event_dkg_pub_key_sending_required_internal")
|
||||
|
||||
EventDKGPubKeysSent = fsm.Event("event_dkg_pub_keys_sent")
|
||||
EventDKGPubKeyConfirmationReceived = fsm.Event("event_dkg_pub_key_confirm_received")
|
||||
EventDKGPubKeyConfirmationError = fsm.Event("event_dkg_pub_key_confirm_canceled_by_error")
|
||||
EventDKGPubKeysConfirmationCancelByTimeoutInternal = fsm.Event("event_dkg_pub_keys_confirm_canceled_by_timeout_internal")
|
||||
EventDKGPubKeysConfirmedInternal = fsm.Event("event_dkg_pub_keys_confirmed_internal")
|
||||
|
||||
EventDKGCommitsSendingRequiredInternal = fsm.Event("event_dkg_commits_sending_required_internal")
|
||||
|
||||
EventDKGCommitsSent = fsm.Event("event_dkg_commits_sent")
|
||||
EventDKGCommitConfirmationReceived = fsm.Event("event_dkg_commit_confirm_received")
|
||||
EventDKGCommitConfirmationError = fsm.Event("event_dkg_commit_confirm_canceled_by_error")
|
||||
EventDKGCommitsConfirmationCancelByTimeoutInternal = fsm.Event("event_dkg_commits_confirm_canceled_by_timeout_internal")
|
||||
EventDKGCommitsConfirmedInternal = fsm.Event("event_dkg_commits_confirmed_internal")
|
||||
|
||||
EventDKGDealsSendingRequiredInternal = fsm.Event("event_dkg_deals_sending_required_internal")
|
||||
|
||||
EventDKGDealsSent = fsm.Event("event_dkg_deals_sent")
|
||||
EventDKGDealConfirmationReceived = fsm.Event("event_dkg_deal_confirm_received")
|
||||
EventDKGDealConfirmationError = fsm.Event("event_dkg_deal_confirm_canceled_by_error")
|
||||
EventDKGDealsConfirmationCancelByTimeoutInternal = fsm.Event("event_dkg_deals_confirm_canceled_by_timeout_internal")
|
||||
|
||||
EventDKGMasterKeyRequiredInternal = fsm.Event("event_dkg_master_key_required_internal")
|
||||
)
|
||||
|
||||
type DKGProposalFSM struct {
|
||||
*fsm.FSM
|
||||
}
|
||||
|
||||
func New() fsm_pool.MachineProvider {
|
||||
machine := &DKGProposalFSM{}
|
||||
|
||||
machine.FSM = fsm.MustNewFSM(
|
||||
fsmName,
|
||||
StateDkgInitial,
|
||||
[]fsm.EventDesc{
|
||||
|
||||
// Init
|
||||
// Switch to pub keys required
|
||||
{Name: EventDKGPubKeysSendingRequiredInternal, SrcState: []fsm.State{StateDkgInitial}, DstState: StateDkgPubKeysSendingRequired, IsInternal: true},
|
||||
|
||||
// Pub keys sending
|
||||
{Name: EventDKGPubKeysSent, SrcState: []fsm.State{StateDkgPubKeysSendingRequired}, DstState: StateDkgPubKeysSendingAwaitConfirmations},
|
||||
{Name: EventDKGPubKeyConfirmationReceived, SrcState: []fsm.State{StateDkgPubKeysSendingAwaitConfirmations}, DstState: StateDkgPubKeysSendingAwaitConfirmations},
|
||||
// Cancelled
|
||||
{Name: EventDKGPubKeyConfirmationError, SrcState: []fsm.State{StateDkgPubKeysSendingAwaitConfirmations}, DstState: StateDkgPubKeysSendingCancelled},
|
||||
{Name: EventDKGPubKeysConfirmationCancelByTimeoutInternal, SrcState: []fsm.State{StateDkgPubKeysSendingAwaitConfirmations}, DstState: StateDkgPubKeysSendingCancelledByTimeout, IsInternal: true},
|
||||
// Confirmed
|
||||
{Name: EventDKGPubKeysConfirmedInternal, SrcState: []fsm.State{StateDkgPubKeysSendingAwaitConfirmations}, DstState: StateDkgPubKeysSendingConfirmed, IsInternal: true},
|
||||
|
||||
// Switch to commits required
|
||||
{Name: EventDKGCommitsSendingRequiredInternal, SrcState: []fsm.State{StateDkgPubKeysSendingConfirmed}, DstState: StateDkgCommitsSendingRequired, IsInternal: true},
|
||||
|
||||
// Commits
|
||||
{Name: EventDKGCommitsSent, SrcState: []fsm.State{StateDkgCommitsSendingRequired}, DstState: StateDkgCommitsSendingAwaitConfirmations},
|
||||
{Name: EventDKGCommitConfirmationReceived, SrcState: []fsm.State{StateDkgCommitsSendingAwaitConfirmations}, DstState: StateDkgCommitsSendingAwaitConfirmations},
|
||||
// Cancelled
|
||||
{Name: EventDKGCommitConfirmationError, SrcState: []fsm.State{StateDkgCommitsSendingAwaitConfirmations}, DstState: StateDkgCommitsSendingCancelled},
|
||||
{Name: EventDKGCommitsConfirmationCancelByTimeoutInternal, SrcState: []fsm.State{StateDkgCommitsSendingAwaitConfirmations}, DstState: StateDkgCommitsSendingCancelledByTimeout, IsInternal: true},
|
||||
// Confirmed
|
||||
{Name: EventDKGCommitsConfirmedInternal, SrcState: []fsm.State{StateDkgCommitsSendingAwaitConfirmations}, DstState: StateDkgCommitsSendingConfirmed, IsInternal: true},
|
||||
|
||||
// Switch to deals required
|
||||
{Name: EventDKGDealsSendingRequiredInternal, SrcState: []fsm.State{StateDkgDealsSendingConfirmed}, DstState: StateDkgDealsSendingRequired, IsInternal: true},
|
||||
|
||||
// Deals
|
||||
{Name: EventDKGDealsSent, SrcState: []fsm.State{StateDkgDealsSendingRequired}, DstState: StateDkgDealsSendingAwaitConfirmations},
|
||||
{Name: EventDKGDealConfirmationReceived, SrcState: []fsm.State{StateDkgDealsSendingAwaitConfirmations}, DstState: StateDkgDealsSendingAwaitConfirmations},
|
||||
// Cancelled
|
||||
{Name: EventDKGDealConfirmationError, SrcState: []fsm.State{StateDkgCommitsSendingAwaitConfirmations}, DstState: StateDkgDealsSendingCancelled},
|
||||
{Name: EventDKGDealsConfirmationCancelByTimeoutInternal, SrcState: []fsm.State{StateDkgCommitsSendingAwaitConfirmations}, DstState: StateDkgDealsSendingCancelledByTimeout, IsInternal: true},
|
||||
|
||||
// Done
|
||||
{Name: EventDKGMasterKeyRequiredInternal, SrcState: []fsm.State{StateDkgCommitsSendingAwaitConfirmations}, DstState: fsm.StateGlobalDone, IsInternal: true},
|
||||
},
|
||||
fsm.Callbacks{
|
||||
EventDKGPubKeysSent: machine.actionDKGPubKeysSent,
|
||||
EventDKGPubKeyConfirmationReceived: machine.actionDKGPubKeyConfirmationReceived,
|
||||
EventDKGPubKeyConfirmationError: machine.actionDKGPubKeyConfirmationError,
|
||||
|
||||
EventDKGCommitsSent: machine.actionDKGCommitsSent,
|
||||
EventDKGCommitConfirmationReceived: machine.actionDKGCommitConfirmationReceived,
|
||||
EventDKGCommitConfirmationError: machine.actionDKGCommitConfirmationError,
|
||||
|
||||
EventDKGDealsSent: machine.actionDKGDealsSent,
|
||||
EventDKGDealConfirmationReceived: machine.actionDKGDealConfirmationReceived,
|
||||
EventDKGDealConfirmationError: machine.actionDKGDealConfirmationError,
|
||||
},
|
||||
)
|
||||
return machine
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package internal
|
||||
|
||||
type MachineStatePayload struct {
|
||||
ProposalPayload ProposalConfirmationPrivateQuorum
|
||||
SigningPayload map[string]interface{}
|
||||
ConfirmationProposalPayload ConfirmationProposalPrivateQuorum
|
||||
DKGProposalPayload DKGProposalPrivateQuorum
|
||||
}
|
||||
|
||||
// Using combine response for modify data with chain
|
||||
|
|
|
@ -4,6 +4,7 @@ import "time"
|
|||
|
||||
type ProposalParticipantPrivate struct {
|
||||
// Public title for address, such as name, nickname, organization
|
||||
ParticipantId int
|
||||
Title string
|
||||
PublicKey []byte
|
||||
// For validation user confirmation: sign(InvitationSecret, PublicKey) => user
|
||||
|
@ -14,4 +15,14 @@ type ProposalParticipantPrivate struct {
|
|||
// Unique alias for map iteration - Public Key Fingerprint
|
||||
// Excludes array merge and rotate operations
|
||||
|
||||
type ProposalConfirmationPrivateQuorum map[string]ProposalParticipantPrivate
|
||||
type ConfirmationProposalPrivateQuorum map[string]ProposalParticipantPrivate
|
||||
|
||||
type ProposalDKGParticipantPrivate struct {
|
||||
Title string
|
||||
PublicKey []byte
|
||||
Commit []byte
|
||||
Deal []byte
|
||||
UpdatedAt *time.Time
|
||||
}
|
||||
|
||||
type DKGProposalPrivateQuorum map[int]ProposalParticipantPrivate
|
||||
|
|
|
@ -3,11 +3,11 @@ package state_machines
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
|
||||
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"github.com/depools/dc4bc/fsm/fsm_pool"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/signature_construct_fsm"
|
||||
"github.com/depools/dc4bc/fsm/state_machines/signature_proposal_fsm"
|
||||
)
|
||||
|
||||
|
@ -30,7 +30,7 @@ var (
|
|||
func init() {
|
||||
fsmPoolProvider = fsm_pool.Init(
|
||||
signature_proposal_fsm.New(),
|
||||
signature_construct_fsm.New(),
|
||||
dkg_proposal_fsm.New(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
package signature_construct_fsm
|
||||
|
||||
import (
|
||||
"github.com/depools/dc4bc/fsm/fsm"
|
||||
"github.com/depools/dc4bc/fsm/fsm_pool"
|
||||
)
|
||||
|
||||
const (
|
||||
fsmName = "signature_construct_fsm"
|
||||
|
||||
stateConstructorEntryPoint = "process_sig"
|
||||
awaitConstructor = "validate_process_sig" // waiting participants
|
||||
|
||||
eventInitSignatureConstructor = "process_sig_init"
|
||||
eventInitSignatureFinishTmp = "process_sig_fin"
|
||||
)
|
||||
|
||||
type SignatureConstructFSM struct {
|
||||
*fsm.FSM
|
||||
}
|
||||
|
||||
func New() fsm_pool.MachineProvider {
|
||||
machine := &SignatureConstructFSM{}
|
||||
|
||||
machine.FSM = fsm.MustNewFSM(
|
||||
fsmName,
|
||||
stateConstructorEntryPoint,
|
||||
[]fsm.EventDesc{
|
||||
// {Name: "", SrcState: []string{""}, DstState: ""},
|
||||
|
||||
// Init
|
||||
{Name: eventInitSignatureConstructor, SrcState: []fsm.State{stateConstructorEntryPoint}, DstState: awaitConstructor},
|
||||
{Name: eventInitSignatureFinishTmp, SrcState: []fsm.State{awaitConstructor}, DstState: "dkg_proposal_fsm"},
|
||||
},
|
||||
fsm.Callbacks{},
|
||||
)
|
||||
|
||||
return machine
|
||||
}
|
|
@ -45,7 +45,7 @@ func (s *SignatureProposalFSM) actionInitProposal(event fsm.Event, args ...inter
|
|||
return
|
||||
}
|
||||
|
||||
request, ok := args[2].(requests.ProposalParticipantsListRequest)
|
||||
request, ok := args[2].(requests.SignatureProposalParticipantsListRequest)
|
||||
|
||||
if !ok {
|
||||
err = errors.New("cannot cast participants list")
|
||||
|
@ -56,15 +56,16 @@ func (s *SignatureProposalFSM) actionInitProposal(event fsm.Event, args ...inter
|
|||
return
|
||||
}
|
||||
|
||||
payload.ProposalPayload = make(internal.ProposalConfirmationPrivateQuorum)
|
||||
payload.ConfirmationProposalPayload = make(internal.ConfirmationProposalPrivateQuorum)
|
||||
|
||||
for _, participant := range request {
|
||||
for participantIntId, participant := range request {
|
||||
participantId := createFingerprint(&participant.PublicKey)
|
||||
secret, err := generateRandomString(32)
|
||||
if err != nil {
|
||||
return nil, errors.New("cannot generateRandomString")
|
||||
}
|
||||
payload.ProposalPayload[participantId] = internal.ProposalParticipantPrivate{
|
||||
payload.ConfirmationProposalPayload[participantId] = internal.ProposalParticipantPrivate{
|
||||
ParticipantId: participantIntId,
|
||||
Title: participant.Title,
|
||||
PublicKey: participant.PublicKey,
|
||||
InvitationSecret: secret,
|
||||
|
@ -74,16 +75,16 @@ func (s *SignatureProposalFSM) actionInitProposal(event fsm.Event, args ...inter
|
|||
|
||||
// Make response
|
||||
|
||||
responseData := make(responses.ProposalParticipantInvitationsResponse, 0)
|
||||
responseData := make(responses.SignatureProposalParticipantInvitationsResponse, 0)
|
||||
|
||||
for participantId, proposal := range payload.ProposalPayload {
|
||||
for pubKeyFingerprint, proposal := range payload.ConfirmationProposalPayload {
|
||||
encryptedInvitationSecret, err := encryptWithPubKey(proposal.PublicKey, proposal.InvitationSecret)
|
||||
if err != nil {
|
||||
return nil, errors.New("cannot encryptWithPubKey")
|
||||
}
|
||||
responseEntry := &responses.ProposalParticipantInvitationEntryResponse{
|
||||
responseEntry := &responses.SignatureProposalParticipantInvitationEntry{
|
||||
Title: proposal.Title,
|
||||
PubKeyFingerprint: participantId,
|
||||
PubKeyFingerprint: pubKeyFingerprint,
|
||||
EncryptedInvitation: encryptedInvitationSecret,
|
||||
}
|
||||
responseData = append(responseData, responseEntry)
|
||||
|
|
|
@ -11,10 +11,10 @@ import (
|
|||
|
||||
// Request and response mutators
|
||||
|
||||
func ProposalParticipantsQuorumToResponse(list *internal.ProposalConfirmationPrivateQuorum) responses.ProposalParticipantInvitationsResponse {
|
||||
var response responses.ProposalParticipantInvitationsResponse
|
||||
func ProposalParticipantsQuorumToResponse(list *internal.ConfirmationProposalPrivateQuorum) responses.SignatureProposalParticipantInvitationsResponse {
|
||||
var response responses.SignatureProposalParticipantInvitationsResponse
|
||||
for quorumId, parcipant := range *list {
|
||||
response = append(response, &responses.ProposalParticipantInvitationEntryResponse{
|
||||
response = append(response, &responses.SignatureProposalParticipantInvitationEntry{
|
||||
Title: parcipant.Title,
|
||||
PubKeyFingerprint: quorumId,
|
||||
// TODO: Add encryption
|
||||
|
|
|
@ -9,21 +9,23 @@ const (
|
|||
fsmName = "signature_proposal_fsm"
|
||||
signingIdLen = 32
|
||||
|
||||
stateAwaitProposalConfirmation = fsm.State("validate_proposal") // waiting participants
|
||||
StateAwaitParticipantsConfirmations = fsm.State("state_validation_await_participants_confirmations") // waiting participants
|
||||
|
||||
stateValidationCanceledByParticipant = fsm.State("validation_canceled_by_participant")
|
||||
stateValidationCanceledByTimeout = fsm.State("validation_canceled_by_timeout")
|
||||
StateValidationCanceledByParticipant = fsm.State("state_validation_canceled_by_participant")
|
||||
StateValidationCanceledByTimeout = fsm.State("state_validation_canceled_by_timeout")
|
||||
|
||||
stateProposed = "proposed"
|
||||
StateValidationCompleted = fsm.State("state_validation_completed")
|
||||
|
||||
eventInitProposal = fsm.Event("proposal_init")
|
||||
eventConfirmProposal = fsm.Event("proposal_confirm_by_participant")
|
||||
eventDeclineProposal = fsm.Event("proposal_decline_by_participant")
|
||||
eventValidateProposal = fsm.Event("proposal_validate")
|
||||
eventSetProposalValidated = fsm.Event("proposal_set_validated")
|
||||
EventInitProposal = fsm.Event("event_proposal_init")
|
||||
EventConfirmProposal = fsm.Event("event_proposal_confirm_by_participant")
|
||||
EventDeclineProposal = fsm.Event("event_proposal_decline_by_participant")
|
||||
EventValidateProposal = fsm.Event("event_proposal_validate")
|
||||
EventSetProposalValidated = fsm.Event("event_proposal_set_validated")
|
||||
|
||||
eventSetValidationCanceledByTimeout = fsm.Event("proposal_canceled_timeout")
|
||||
eventSwitchProposedToSigning = fsm.Event("switch_state_to_signing")
|
||||
|
||||
// Switch to next fsm
|
||||
|
||||
)
|
||||
|
||||
type SignatureProposalFSM struct {
|
||||
|
@ -40,28 +42,28 @@ func New() fsm_pool.MachineProvider {
|
|||
// {Name: "", SrcState: []string{""}, DstState: ""},
|
||||
|
||||
// Init
|
||||
{Name: eventInitProposal, SrcState: []fsm.State{fsm.StateGlobalIdle}, DstState: stateAwaitProposalConfirmation},
|
||||
{Name: EventInitProposal, SrcState: []fsm.State{fsm.StateGlobalIdle}, DstState: StateAwaitParticipantsConfirmations},
|
||||
|
||||
// Validate by participants
|
||||
{Name: eventConfirmProposal, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateAwaitProposalConfirmation},
|
||||
{Name: EventConfirmProposal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateAwaitParticipantsConfirmations},
|
||||
// Is decline event should auto change state to default, or it process will initiated by client (external emit)?
|
||||
// Now set for external emitting.
|
||||
{Name: eventDeclineProposal, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateValidationCanceledByParticipant},
|
||||
{Name: EventDeclineProposal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateValidationCanceledByParticipant},
|
||||
|
||||
{Name: eventValidateProposal, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateAwaitProposalConfirmation},
|
||||
{Name: EventValidateProposal, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateAwaitParticipantsConfirmations},
|
||||
|
||||
// eventProposalValidate internal or from client?
|
||||
// yay
|
||||
// Exit point
|
||||
{Name: eventSetProposalValidated, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: "process_sig", IsInternal: true},
|
||||
{Name: EventSetProposalValidated, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: fsm.State("state_dkg_pub_keys_sending_required"), IsInternal: true},
|
||||
// nan
|
||||
{Name: eventSetValidationCanceledByTimeout, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateValidationCanceledByTimeout, IsInternal: true},
|
||||
{Name: eventSetValidationCanceledByTimeout, SrcState: []fsm.State{StateAwaitParticipantsConfirmations}, DstState: StateValidationCanceledByTimeout, IsInternal: true},
|
||||
},
|
||||
fsm.Callbacks{
|
||||
eventInitProposal: machine.actionInitProposal,
|
||||
eventConfirmProposal: machine.actionConfirmProposalByParticipant,
|
||||
eventDeclineProposal: machine.actionDeclineProposalByParticipant,
|
||||
eventValidateProposal: machine.actionValidateProposal,
|
||||
EventInitProposal: machine.actionInitProposal,
|
||||
EventConfirmProposal: machine.actionConfirmProposalByParticipant,
|
||||
EventDeclineProposal: machine.actionDeclineProposalByParticipant,
|
||||
EventValidateProposal: machine.actionValidateProposal,
|
||||
},
|
||||
)
|
||||
return machine
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package requests
|
||||
|
||||
// Event: "event_dkg_pub_keys_sent"
|
||||
type DKGProposalPubKeysSendingRequest struct {
|
||||
PubKeys map[int][]byte
|
||||
}
|
||||
|
||||
// Event: "event_dkg_commits_sent"
|
||||
type DKGProposalCommitsSendingRequest struct {
|
||||
Commits map[int][]byte
|
||||
}
|
||||
|
||||
// Event: "event_dkg_deals_sent"
|
||||
type DKGProposalDealsSendingRequest struct {
|
||||
Deals map[int][]byte
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
package requests
|
|
@ -1,49 +1,17 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/depools/dc4bc/fsm/config"
|
||||
)
|
||||
|
||||
// Requests
|
||||
|
||||
type ProposalParticipantsListRequest []ProposalParticipantsEntryRequest
|
||||
type SignatureProposalParticipantsListRequest []SignatureProposalParticipantsEntry
|
||||
|
||||
type ProposalParticipantsEntryRequest struct {
|
||||
type SignatureProposalParticipantsEntry struct {
|
||||
// Public title for address, such as name, nickname, organization
|
||||
Title string
|
||||
PublicKey []byte
|
||||
}
|
||||
|
||||
func (r *ProposalParticipantsListRequest) Validate() error {
|
||||
if len(*r) < config.ParticipantsMinCount {
|
||||
return errors.New("too few participants")
|
||||
}
|
||||
|
||||
for _, participant := range *r {
|
||||
if len(participant.Title) < 3 {
|
||||
return errors.New("title too short")
|
||||
}
|
||||
|
||||
if len(participant.Title) > 150 {
|
||||
return errors.New("title too long")
|
||||
}
|
||||
|
||||
if len(participant.PublicKey) < 10 {
|
||||
return errors.New("pub key too short")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ProposalParticipantConfirmationRequest struct {
|
||||
// Public title for address, such as name, nickname, organization
|
||||
ParticipantId string
|
||||
type SignatureProposalParticipantRequest struct {
|
||||
// Key for link invitations to participants
|
||||
PubKeyFingerprint string
|
||||
EncryptedInvitation string
|
||||
}
|
||||
|
||||
func (r *ProposalParticipantConfirmationRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/depools/dc4bc/fsm/config"
|
||||
)
|
||||
|
||||
func (r *SignatureProposalParticipantsListRequest) Validate() error {
|
||||
if len(*r) < config.ParticipantsMinCount {
|
||||
return errors.New("too few participants")
|
||||
}
|
||||
|
||||
for _, participant := range *r {
|
||||
if len(participant.Title) < 3 {
|
||||
return errors.New("title too short")
|
||||
}
|
||||
|
||||
if len(participant.Title) > 150 {
|
||||
return errors.New("title too long")
|
||||
}
|
||||
|
||||
if len(participant.PublicKey) < 10 {
|
||||
return errors.New("pub key too short")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *SignatureProposalParticipantRequest) Validate() error {
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package responses
|
||||
|
||||
type DKGProposalPubKeyParticipantResponse []*DKGProposalPubKeyParticipantEntry
|
||||
|
||||
type DKGProposalPubKeyParticipantEntry struct {
|
||||
ParticipantId int
|
||||
Title string
|
||||
PubKey []byte
|
||||
}
|
||||
|
||||
type DKGProposalCommitParticipantResponse []*DKGProposalCommitParticipantEntry
|
||||
|
||||
type DKGProposalCommitParticipantEntry struct {
|
||||
ParticipantId int
|
||||
Title string
|
||||
Commit []byte
|
||||
}
|
||||
|
||||
type DKGProposalDealParticipantResponse []*DKGProposalDealParticipantEntry
|
||||
|
||||
type DKGProposalDealParticipantEntry struct {
|
||||
ParticipantId int
|
||||
Title string
|
||||
Deal []byte
|
||||
}
|
|
@ -2,9 +2,19 @@ package responses
|
|||
|
||||
// Responses
|
||||
|
||||
type ProposalParticipantInvitationsResponse []*ProposalParticipantInvitationEntryResponse
|
||||
const (
|
||||
ProposalConfirmationStatusIdle = iota
|
||||
ProposalConfirmationStatusAccepted
|
||||
ProposalConfirmationStatusCanceled
|
||||
ProposalConfirmationStatusTimeout
|
||||
)
|
||||
|
||||
type ProposalParticipantInvitationEntryResponse struct {
|
||||
// States: "validate_proposal"
|
||||
|
||||
type SignatureProposalParticipantInvitationsResponse []*SignatureProposalParticipantInvitationEntry
|
||||
|
||||
type SignatureProposalParticipantInvitationEntry struct {
|
||||
ParticipantId int
|
||||
// Public title for address, such as name, nickname, organization
|
||||
Title string
|
||||
// Key for link invitations to participants
|
||||
|
@ -12,3 +22,14 @@ type ProposalParticipantInvitationEntryResponse struct {
|
|||
// Encrypted with public key secret
|
||||
EncryptedInvitation string
|
||||
}
|
||||
|
||||
// Public lists for proposal confirmation process
|
||||
// States: "validation_canceled_by_participant", "validation_canceled_by_timeout",
|
||||
type SignatureProposalParticipantStatusResponse []*SignatureProposalParticipantStatusEntry
|
||||
|
||||
type SignatureProposalParticipantStatusEntry struct {
|
||||
ParticipantId int
|
||||
Title string
|
||||
PubKeyFingerprint string
|
||||
Status int
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue