mirror of https://github.com/certusone/dc4bc.git
Merge branch 'master' into feat/client-http
# Conflicts: # fsm/cmd/test/test.go # fsm/fsm_pool/fsm_pool.go # fsm/state_machines/provider.go # fsm/state_machines/signature_proposal_fsm/actions.go # fsm/state_machines/signature_proposal_fsm/helpers.go # fsm/types/requests/signature_proposal.go # mocks/clientMocks/state_mock.go # mocks/storageMocks/storage_mock.go
This commit is contained in:
commit
533dc9375c
|
@ -19,33 +19,45 @@ import (
|
||||||
|
|
||||||
// Temporary global finish state for deprecating operations
|
// Temporary global finish state for deprecating operations
|
||||||
const (
|
const (
|
||||||
StateGlobalIdle = "__idle"
|
StateGlobalIdle = State("__idle")
|
||||||
StateGlobalDone = "__done"
|
StateGlobalDone = State("__done")
|
||||||
)
|
)
|
||||||
|
|
||||||
// FSMResponse returns result for processing with clientMocks events
|
type State string
|
||||||
type FSMResponse struct {
|
|
||||||
|
func (s *State) String() string {
|
||||||
|
return string(*s)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Event string
|
||||||
|
|
||||||
|
func (e *Event) String() string {
|
||||||
|
return string(*e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Response returns result for processing with clientMocks events
|
||||||
|
type Response struct {
|
||||||
// Returns machine execution result state
|
// Returns machine execution result state
|
||||||
State string
|
State State
|
||||||
// Must be cast, according to mapper event_name->response_type
|
// Must be cast, according to mapper event_name->response_type
|
||||||
Data interface{}
|
Data interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type FSM struct {
|
type FSM struct {
|
||||||
name string
|
name string
|
||||||
initialState string
|
initialState State
|
||||||
currentState string
|
currentState State
|
||||||
|
|
||||||
// May be mapping must require pair source + event?
|
// May be mapping must require pair source + event?
|
||||||
transitions map[trKey]*trEvent
|
transitions map[trKey]*trEvent
|
||||||
|
|
||||||
callbacks Callbacks
|
callbacks Callbacks
|
||||||
|
|
||||||
initialEvent string
|
initialEvent Event
|
||||||
|
|
||||||
// Finish states, for switch machine or fin,
|
// Finish states, for switch machine or fin,
|
||||||
// These states cannot be linked as SrcState in this machine
|
// These states cannot be linked as SrcState in this machine
|
||||||
finStates map[string]bool
|
finStates map[State]bool
|
||||||
|
|
||||||
// stateMu guards access to the currentState state.
|
// stateMu guards access to the currentState state.
|
||||||
stateMu sync.RWMutex
|
stateMu sync.RWMutex
|
||||||
|
@ -55,36 +67,36 @@ type FSM struct {
|
||||||
|
|
||||||
// Transition key source + dst
|
// Transition key source + dst
|
||||||
type trKey struct {
|
type trKey struct {
|
||||||
source string
|
source State
|
||||||
event string
|
event Event
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition lightweight event description
|
// Transition lightweight event description
|
||||||
type trEvent struct {
|
type trEvent struct {
|
||||||
dstState string
|
dstState State
|
||||||
isInternal bool
|
isInternal bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Event struct {
|
type EventDesc struct {
|
||||||
Name string
|
Name Event
|
||||||
|
|
||||||
SrcState []string
|
SrcState []State
|
||||||
|
|
||||||
// Dst state changes after callback
|
// Dst state changes after callback
|
||||||
DstState string
|
DstState State
|
||||||
|
|
||||||
// Internal events, cannot be emitted from external call
|
// Internal events, cannot be emitted from external call
|
||||||
IsInternal bool
|
IsInternal bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type Callback func(event string, args ...interface{}) (interface{}, error)
|
type Callback func(event Event, args ...interface{}) (interface{}, error)
|
||||||
|
|
||||||
type Callbacks map[string]Callback
|
type Callbacks map[Event]Callback
|
||||||
|
|
||||||
// TODO: Exports
|
// TODO: Exports
|
||||||
func MustNewFSM(machineName, initialState string, events []Event, callbacks map[string]Callback) *FSM {
|
func MustNewFSM(machineName string, initialState State, events []EventDesc, callbacks Callbacks) *FSM {
|
||||||
machineName = strings.TrimSpace(machineName)
|
machineName = strings.TrimSpace(machineName)
|
||||||
initialState = strings.TrimSpace(initialState)
|
initialState = State(strings.TrimSpace(initialState.String()))
|
||||||
|
|
||||||
if machineName == "" {
|
if machineName == "" {
|
||||||
panic("machine name cannot be empty")
|
panic("machine name cannot be empty")
|
||||||
|
@ -104,20 +116,20 @@ func MustNewFSM(machineName, initialState string, events []Event, callbacks map[
|
||||||
currentState: initialState,
|
currentState: initialState,
|
||||||
initialState: initialState,
|
initialState: initialState,
|
||||||
transitions: make(map[trKey]*trEvent),
|
transitions: make(map[trKey]*trEvent),
|
||||||
finStates: make(map[string]bool),
|
finStates: make(map[State]bool),
|
||||||
callbacks: make(map[string]Callback),
|
callbacks: make(map[Event]Callback),
|
||||||
}
|
}
|
||||||
|
|
||||||
allEvents := make(map[string]bool)
|
allEvents := make(map[Event]bool)
|
||||||
|
|
||||||
// Required for find finStates
|
// Required for find finStates
|
||||||
allSources := make(map[string]bool)
|
allSources := make(map[State]bool)
|
||||||
allStates := make(map[string]bool)
|
allStates := make(map[State]bool)
|
||||||
|
|
||||||
// Validate events
|
// Validate events
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
event.Name = strings.TrimSpace(event.Name)
|
event.Name = Event(strings.TrimSpace(event.Name.String()))
|
||||||
event.DstState = strings.TrimSpace(event.DstState)
|
event.DstState = State(strings.TrimSpace(event.DstState.String()))
|
||||||
|
|
||||||
if event.Name == "" {
|
if event.Name == "" {
|
||||||
panic("cannot init empty event")
|
panic("cannot init empty event")
|
||||||
|
@ -137,7 +149,7 @@ func MustNewFSM(machineName, initialState string, events []Event, callbacks map[
|
||||||
trimmedSourcesCounter := 0
|
trimmedSourcesCounter := 0
|
||||||
|
|
||||||
for _, sourceState := range event.SrcState {
|
for _, sourceState := range event.SrcState {
|
||||||
sourceState := strings.TrimSpace(sourceState)
|
sourceState := State(strings.TrimSpace(sourceState.String()))
|
||||||
|
|
||||||
if sourceState == "" {
|
if sourceState == "" {
|
||||||
continue
|
continue
|
||||||
|
@ -209,7 +221,7 @@ func MustNewFSM(machineName, initialState string, events []Event, callbacks map[
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FSM) Do(event string, args ...interface{}) (resp *FSMResponse, err error) {
|
func (f *FSM) Do(event Event, args ...interface{}) (resp *Response, err error) {
|
||||||
f.eventMu.Lock()
|
f.eventMu.Lock()
|
||||||
defer f.eventMu.Unlock()
|
defer f.eventMu.Unlock()
|
||||||
|
|
||||||
|
@ -221,7 +233,7 @@ func (f *FSM) Do(event string, args ...interface{}) (resp *FSMResponse, err erro
|
||||||
return nil, errors.New("event is internal")
|
return nil, errors.New("event is internal")
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = &FSMResponse{
|
resp = &Response{
|
||||||
State: f.State(),
|
State: f.State(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +250,7 @@ func (f *FSM) Do(event string, args ...interface{}) (resp *FSMResponse, err erro
|
||||||
}
|
}
|
||||||
|
|
||||||
// State returns the currentState state of the FSM.
|
// State returns the currentState state of the FSM.
|
||||||
func (f *FSM) State() string {
|
func (f *FSM) State() State {
|
||||||
f.stateMu.RLock()
|
f.stateMu.RLock()
|
||||||
defer f.stateMu.RUnlock()
|
defer f.stateMu.RUnlock()
|
||||||
return f.currentState
|
return f.currentState
|
||||||
|
@ -246,7 +258,7 @@ func (f *FSM) State() string {
|
||||||
|
|
||||||
// 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.
|
// The call does not trigger any callbacks, if defined.
|
||||||
func (f *FSM) setState(event string) error {
|
func (f *FSM) setState(event Event) error {
|
||||||
f.stateMu.Lock()
|
f.stateMu.Lock()
|
||||||
defer f.stateMu.Unlock()
|
defer f.stateMu.Unlock()
|
||||||
|
|
||||||
|
@ -264,12 +276,12 @@ func (f *FSM) Name() string {
|
||||||
return f.name
|
return f.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FSM) InitialState() string {
|
func (f *FSM) InitialState() State {
|
||||||
return f.initialState
|
return f.initialState
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check entry event for available emitting as global entry event
|
// Check entry event for available emitting as global entry event
|
||||||
func (f *FSM) GlobalInitialEvent() (event string) {
|
func (f *FSM) GlobalInitialEvent() (event Event) {
|
||||||
if initialEvent, exists := f.transitions[trKey{StateGlobalIdle, f.initialEvent}]; exists {
|
if initialEvent, exists := f.transitions[trKey{StateGlobalIdle, f.initialEvent}]; exists {
|
||||||
if !initialEvent.isInternal {
|
if !initialEvent.isInternal {
|
||||||
event = f.initialEvent
|
event = f.initialEvent
|
||||||
|
@ -278,7 +290,7 @@ func (f *FSM) GlobalInitialEvent() (event string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FSM) EntryEvent() (event string) {
|
func (f *FSM) EntryEvent() (event Event) {
|
||||||
if entryEvent, exists := f.transitions[trKey{f.initialState, f.initialEvent}]; exists {
|
if entryEvent, exists := f.transitions[trKey{f.initialState, f.initialEvent}]; exists {
|
||||||
if !entryEvent.isInternal {
|
if !entryEvent.isInternal {
|
||||||
event = f.initialEvent
|
event = f.initialEvent
|
||||||
|
@ -287,8 +299,8 @@ func (f *FSM) EntryEvent() (event string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FSM) EventsList() (events []string) {
|
func (f *FSM) EventsList() (events []Event) {
|
||||||
var eventsMap = map[string]bool{}
|
var eventsMap = map[Event]bool{}
|
||||||
if len(f.transitions) > 0 {
|
if len(f.transitions) > 0 {
|
||||||
for trKey, trEvent := range f.transitions {
|
for trKey, trEvent := range f.transitions {
|
||||||
if !trEvent.isInternal {
|
if !trEvent.isInternal {
|
||||||
|
@ -310,8 +322,8 @@ func (f *FSM) EventsList() (events []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FSM) StatesSourcesList() (states []string) {
|
func (f *FSM) StatesSourcesList() (states []State) {
|
||||||
var allStates = map[string]bool{}
|
var allStates = map[State]bool{}
|
||||||
if len(f.transitions) > 0 {
|
if len(f.transitions) > 0 {
|
||||||
for trKey, _ := range f.transitions {
|
for trKey, _ := range f.transitions {
|
||||||
allStates[trKey.source] = true
|
allStates[trKey.source] = true
|
||||||
|
@ -327,7 +339,7 @@ func (f *FSM) StatesSourcesList() (states []string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FSM) IsFinState(state string) bool {
|
func (f *FSM) IsFinState(state State) bool {
|
||||||
_, exists := f.finStates[state]
|
_, exists := f.finStates[state]
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +1,66 @@
|
||||||
package fsm
|
package fsm
|
||||||
|
|
||||||
|
type testMachineFSM struct {
|
||||||
|
*FSM
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FSM1Name = "fsm1"
|
FSM1Name = "fsm1"
|
||||||
// Init process from global idle state
|
// Init process from global idle state
|
||||||
FSM1StateInit = StateGlobalIdle
|
FSM1StateInit = StateGlobalIdle
|
||||||
// Set up data
|
// Set up data
|
||||||
FSM1StateStage1 = "state_fsm1_stage1"
|
FSM1StateStage1 = State("state_fsm1_stage1")
|
||||||
// Process data
|
// Process data
|
||||||
FSM1StateStage2 = "state_fsm1_stage2"
|
FSM1StateStage2 = State("state_fsm1_stage2")
|
||||||
// Cancelled with internal event
|
// Cancelled with internal event
|
||||||
FSM1StateCanceledByInternal = "state_fsm1_canceled1"
|
FSM1StateCanceledByInternal = State("state_fsm1_canceled")
|
||||||
// Cancelled with external event
|
// Cancelled with external event
|
||||||
FSM1StateCanceled2 = "state_fsm1_canceled2"
|
FSM1StateCanceled2 = State("state_fsm1_canceled2")
|
||||||
// Out endpoint to switch
|
// Out endpoint to switch
|
||||||
FSM1StateOutToFSM2 = "state_fsm1_out_to_fsm2"
|
FSM1StateOutToFSM2 = State("state_fsm1_out_to_fsm2")
|
||||||
FSM1StateOutToFSM3 = "state_fsm1_out_to_fsm3"
|
FSM1StateOutToFSM3 = State("state_fsm1_out_to_fsm3")
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
EventFSM1Init = "event_fsm1_init"
|
EventFSM1Init = Event("event_fsm1_init")
|
||||||
EventFSM1Cancel = "event_fsm1_cancel"
|
EventFSM1Cancel = Event("event_fsm1_cancel")
|
||||||
EventFSM1Process = "event_fsm1_process"
|
EventFSM1Process = Event("event_fsm1_process")
|
||||||
|
|
||||||
// Internal events
|
// Internal events
|
||||||
EventFSM1Internal = "event_internal_fsm1"
|
EventFSM1Internal = Event("event_internal_fsm1")
|
||||||
EventFSM1CancelByInternal = "event_internal_fsm1_cancel"
|
EventFSM1CancelByInternal = Event("event_internal_fsm1_cancel")
|
||||||
EventFSM1InternalOut2 = "event_internal_fsm1_out"
|
EventFSM1InternalOut2 = Event("event_internal_fsm1_out")
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testingEvents = []Event{
|
testing1Events = []EventDesc{
|
||||||
// Init
|
// Init
|
||||||
{Name: EventFSM1Init, SrcState: []string{FSM1StateInit}, DstState: FSM1StateStage1},
|
{Name: EventFSM1Init, SrcState: []State{FSM2StateInit}, DstState: FSM1StateStage1},
|
||||||
{Name: EventFSM1Internal, SrcState: []string{FSM1StateStage1}, DstState: FSM1StateStage2, IsInternal: true},
|
{Name: EventFSM1Internal, SrcState: []State{FSM1StateStage1}, DstState: FSM1StateStage2, IsInternal: true},
|
||||||
|
|
||||||
// Cancellation events
|
// Cancellation events
|
||||||
{Name: EventFSM1CancelByInternal, SrcState: []string{FSM1StateStage2}, DstState: FSM1StateCanceledByInternal, IsInternal: true},
|
{Name: EventFSM1CancelByInternal, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateCanceledByInternal, IsInternal: true},
|
||||||
{Name: EventFSM1Cancel, SrcState: []string{FSM1StateStage2}, DstState: FSM1StateCanceled2},
|
{Name: EventFSM1Cancel, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateCanceled2},
|
||||||
|
|
||||||
// Out
|
// Out
|
||||||
{Name: EventFSM1Process, SrcState: []string{FSM1StateStage2}, DstState: FSM1StateOutToFSM2},
|
{Name: EventFSM1Process, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateOutToFSM2},
|
||||||
{Name: EventFSM1InternalOut2, SrcState: []string{FSM1StateStage2}, DstState: FSM1StateOutToFSM3, IsInternal: true},
|
{Name: EventFSM1InternalOut2, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateOutToFSM3, IsInternal: true},
|
||||||
}
|
}
|
||||||
|
|
||||||
testingCallbacks = Callbacks{
|
testing1Callbacks = Callbacks{
|
||||||
EventFSM1Init: actionSetUpData,
|
EventFSM1Init: actionSetUpData,
|
||||||
EventFSM1InternalOut2: actionEmitOut2,
|
EventFSM1InternalOut2: actionEmitOut2,
|
||||||
EventFSM1Process: actionProcessData,
|
EventFSM1Process: actionProcessData,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type testMachineFSM struct {
|
func actionSetUpData(event Event, args ...interface{}) (response interface{}, err error) {
|
||||||
*FSM
|
|
||||||
}
|
|
||||||
|
|
||||||
/*func new() fsm_pool.IStateMachine {
|
|
||||||
machine := &testMachineFSM{}
|
|
||||||
machine.FSM = MustNewFSM(
|
|
||||||
FSM1Name,
|
|
||||||
FSM1StateInit,
|
|
||||||
testingEvents,
|
|
||||||
testingCallbacks,
|
|
||||||
)
|
|
||||||
return machine
|
|
||||||
}*/
|
|
||||||
|
|
||||||
func actionSetUpData(event string, args ...interface{}) (response interface{}, err error) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func actionProcessData(event string, args ...interface{}) (response interface{}, err error) {
|
func actionProcessData(event Event, args ...interface{}) (response interface{}, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func actionEmitOut2(event string, args ...interface{}) (response interface{}, err error) {
|
func actionEmitOut2(event Event, args ...interface{}) (response interface{}, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package fsm
|
package fsm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,8 +10,8 @@ func init() {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
FSM1Name,
|
FSM1Name,
|
||||||
FSM1StateInit,
|
FSM1StateInit,
|
||||||
testingEvents,
|
testing1Events,
|
||||||
testingCallbacks,
|
testing1Callbacks,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,12 +28,38 @@ func compareRecoverStr(t *testing.T, r interface{}, assertion string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func compareArrays(src, dst []string) bool {
|
func compareStatesArr(src, dst []State) bool {
|
||||||
if len(src) != len(dst) {
|
if len(src) != len(dst) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// create a map of string -> int
|
// create a map of string -> int
|
||||||
diff := make(map[string]int, len(src))
|
diff := make(map[State]int, len(src))
|
||||||
|
for _, _x := range src {
|
||||||
|
// 0 value for int is 0, so just increment a counter for the string
|
||||||
|
diff[_x]++
|
||||||
|
}
|
||||||
|
for _, _y := range dst {
|
||||||
|
// If the string _y is not in diff bail out early
|
||||||
|
if _, ok := diff[_y]; !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
diff[_y] -= 1
|
||||||
|
if diff[_y] == 0 {
|
||||||
|
delete(diff, _y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(diff) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func compareEventsArr(src, dst []Event) bool {
|
||||||
|
if len(src) != len(dst) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// create a map of string -> int
|
||||||
|
diff := make(map[Event]int, len(src))
|
||||||
for _, _x := range src {
|
for _, _x := range src {
|
||||||
// 0 value for int is 0, so just increment a counter for the string
|
// 0 value for int is 0, so just increment a counter for the string
|
||||||
diff[_x]++
|
diff[_x]++
|
||||||
|
@ -62,7 +87,7 @@ func TestMustNewFSM_Empty_Name_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"",
|
"",
|
||||||
"init_state",
|
"init_state",
|
||||||
[]Event{},
|
[]EventDesc{},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -77,7 +102,7 @@ func TestMustNewFSM_Empty_Initial_State_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"fsm",
|
"fsm",
|
||||||
"",
|
"",
|
||||||
[]Event{},
|
[]EventDesc{},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -92,7 +117,7 @@ func TestMustNewFSM_Empty_Events_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"fsm",
|
"fsm",
|
||||||
"init_state",
|
"init_state",
|
||||||
[]Event{},
|
[]EventDesc{},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -107,8 +132,8 @@ func TestMustNewFSM_Event_Empty_Name_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"fsm",
|
"fsm",
|
||||||
"init_state",
|
"init_state",
|
||||||
[]Event{
|
[]EventDesc{
|
||||||
{Name: "", SrcState: []string{"init_state"}, DstState: StateGlobalDone},
|
{Name: "", SrcState: []State{"init_state"}, DstState: StateGlobalDone},
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
@ -124,8 +149,8 @@ func TestMustNewFSM_Event_Empty_Source_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"fsm",
|
"fsm",
|
||||||
"init_state",
|
"init_state",
|
||||||
[]Event{
|
[]EventDesc{
|
||||||
{Name: "event", SrcState: []string{}, DstState: StateGlobalDone},
|
{Name: "event", SrcState: []State{}, DstState: StateGlobalDone},
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
@ -141,8 +166,8 @@ func TestMustNewFSM_States_Min_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"fsm",
|
"fsm",
|
||||||
"init_state",
|
"init_state",
|
||||||
[]Event{
|
[]EventDesc{
|
||||||
{Name: "event", SrcState: []string{"init_state"}, DstState: StateGlobalDone},
|
{Name: "event", SrcState: []State{"init_state"}, DstState: StateGlobalDone},
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
@ -158,9 +183,9 @@ func TestMustNewFSM_State_Entry_Conflict_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"fsm",
|
"fsm",
|
||||||
"init_state",
|
"init_state",
|
||||||
[]Event{
|
[]EventDesc{
|
||||||
{Name: "event1", SrcState: []string{"init_state"}, DstState: "state"},
|
{Name: "event1", SrcState: []State{"init_state"}, DstState: "state"},
|
||||||
{Name: "event2", SrcState: []string{"init_state"}, DstState: "state"},
|
{Name: "event2", SrcState: []State{"init_state"}, DstState: "state"},
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
@ -176,9 +201,9 @@ func TestMustNewFSM_State_Final_Not_Found_Panic(t *testing.T) {
|
||||||
testingFSM = MustNewFSM(
|
testingFSM = MustNewFSM(
|
||||||
"fsm",
|
"fsm",
|
||||||
"init_state",
|
"init_state",
|
||||||
[]Event{
|
[]EventDesc{
|
||||||
{Name: "event1", SrcState: []string{"init_state"}, DstState: "state2"},
|
{Name: "event1", SrcState: []State{"init_state"}, DstState: "state2"},
|
||||||
{Name: "event2", SrcState: []string{"state2"}, DstState: "init_state"},
|
{Name: "event2", SrcState: []State{"state2"}, DstState: "init_state"},
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
)
|
)
|
||||||
|
@ -199,27 +224,26 @@ func TestFSM_EntryEvent(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFSM_EventsList(t *testing.T) {
|
func TestFSM_EventsList(t *testing.T) {
|
||||||
eventsList := []string{
|
eventsList := []Event{
|
||||||
EventFSM1Init,
|
EventFSM1Init,
|
||||||
EventFSM1Cancel,
|
EventFSM1Cancel,
|
||||||
EventFSM1Process,
|
EventFSM1Process,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !compareArrays(testingFSM.EventsList(), eventsList) {
|
if !compareEventsArr(testingFSM.EventsList(), eventsList) {
|
||||||
t.Error("expected public events", eventsList)
|
t.Error("expected public events", eventsList)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFSM_StatesList(t *testing.T) {
|
func TestFSM_StatesList(t *testing.T) {
|
||||||
log.Println(testingFSM.StatesSourcesList())
|
statesList := []State{
|
||||||
statesList := []string{
|
|
||||||
FSM1StateInit,
|
FSM1StateInit,
|
||||||
FSM1StateStage1,
|
FSM1StateStage1,
|
||||||
FSM1StateStage2,
|
FSM1StateStage2,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !compareArrays(testingFSM.StatesSourcesList(), statesList) {
|
if !compareStatesArr(testingFSM.StatesSourcesList(), statesList) {
|
||||||
t.Error("expected states", statesList)
|
t.Error("expected states", statesList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,50 +6,52 @@ import (
|
||||||
"github.com/depools/dc4bc/fsm/fsm"
|
"github.com/depools/dc4bc/fsm/fsm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IStateMachine interface {
|
type MachineProvider interface {
|
||||||
// Returns machine state from scope dump
|
// Returns machine state from scope dump
|
||||||
// For nil argument returns fsm with process initiation
|
// For nil argument returns fsm with process initiation
|
||||||
// Get() IStateMachine
|
// Get() MachineProvider
|
||||||
|
|
||||||
Name() string
|
Name() string
|
||||||
|
|
||||||
InitialState() string
|
InitialState() fsm.State
|
||||||
|
|
||||||
// Process event
|
// Process event
|
||||||
Do(event string, args ...interface{}) (*fsm.FSMResponse, error)
|
Do(event fsm.Event, args ...interface{}) (*fsm.Response, error)
|
||||||
|
|
||||||
GlobalInitialEvent() string
|
GlobalInitialEvent() fsm.Event
|
||||||
|
|
||||||
EventsList() []string
|
EventsList() []fsm.Event
|
||||||
|
|
||||||
StatesSourcesList() []string
|
StatesSourcesList() []fsm.State
|
||||||
|
|
||||||
IsFinState(state string) bool
|
IsFinState(state fsm.State) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type FSMMapper map[string]IStateMachine
|
type FSMMapper map[string]MachineProvider
|
||||||
|
|
||||||
type FSMRouteMapper map[string]string
|
type FSMEventsMapper map[fsm.Event]string
|
||||||
|
|
||||||
type FSMPoolProvider struct {
|
type FSMStatesMapper map[fsm.State]string
|
||||||
fsmInitialEvent string
|
|
||||||
|
type FSMPool struct {
|
||||||
|
fsmInitialEvent fsm.Event
|
||||||
// Pool mapper by names
|
// Pool mapper by names
|
||||||
mapper FSMMapper
|
mapper FSMMapper
|
||||||
events FSMRouteMapper
|
events FSMEventsMapper
|
||||||
states FSMRouteMapper
|
states FSMStatesMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init(machines ...IStateMachine) *FSMPoolProvider {
|
func Init(machines ...MachineProvider) *FSMPool {
|
||||||
if len(machines) == 0 {
|
if len(machines) == 0 {
|
||||||
panic("cannot initialize empty pool")
|
panic("cannot initialize empty pool")
|
||||||
}
|
}
|
||||||
p := &FSMPoolProvider{
|
p := &FSMPool{
|
||||||
mapper: make(FSMMapper),
|
mapper: make(FSMMapper),
|
||||||
events: make(FSMRouteMapper),
|
events: make(FSMEventsMapper),
|
||||||
states: make(FSMRouteMapper),
|
states: make(FSMStatesMapper),
|
||||||
}
|
}
|
||||||
|
|
||||||
allInitStatesMap := make(map[string]string)
|
allInitStatesMap := make(map[fsm.State]string)
|
||||||
|
|
||||||
// Fill up mapper
|
// Fill up mapper
|
||||||
for _, machine := range machines {
|
for _, machine := range machines {
|
||||||
|
@ -99,7 +101,7 @@ func Init(machines ...IStateMachine) *FSMPoolProvider {
|
||||||
if machine.IsFinState(state) {
|
if machine.IsFinState(state) {
|
||||||
// If state is initial for another machine,
|
// If state is initial for another machine,
|
||||||
if initMachineName, exists := allInitStatesMap[state]; exists {
|
if initMachineName, exists := allInitStatesMap[state]; exists {
|
||||||
p.states[allInitStatesMap[state]] = initMachineName
|
p.states[state] = initMachineName
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -117,7 +119,7 @@ func Init(machines ...IStateMachine) *FSMPoolProvider {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *FSMPoolProvider) EntryPointMachine() (IStateMachine, error) {
|
func (p *FSMPool) EntryPointMachine() (MachineProvider, error) {
|
||||||
// StateGlobalIdle
|
// StateGlobalIdle
|
||||||
// TODO: Short code
|
// TODO: Short code
|
||||||
entryStateMachineName := p.events[p.fsmInitialEvent]
|
entryStateMachineName := p.events[p.fsmInitialEvent]
|
||||||
|
@ -130,7 +132,7 @@ func (p *FSMPoolProvider) EntryPointMachine() (IStateMachine, error) {
|
||||||
return machine, nil
|
return machine, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *FSMPoolProvider) MachineByEvent(event string) (IStateMachine, error) {
|
func (p *FSMPool) MachineByEvent(event fsm.Event) (MachineProvider, error) {
|
||||||
eventMachineName := p.events[event]
|
eventMachineName := p.events[event]
|
||||||
machine, exists := p.mapper[eventMachineName]
|
machine, exists := p.mapper[eventMachineName]
|
||||||
|
|
||||||
|
@ -140,7 +142,7 @@ func (p *FSMPoolProvider) MachineByEvent(event string) (IStateMachine, error) {
|
||||||
return machine, nil
|
return machine, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *FSMPoolProvider) MachineByState(state string) (IStateMachine, error) {
|
func (p *FSMPool) MachineByState(state fsm.State) (MachineProvider, error) {
|
||||||
eventMachineName := p.states[state]
|
eventMachineName := p.states[state]
|
||||||
machine, exists := p.mapper[eventMachineName]
|
machine, exists := p.mapper[eventMachineName]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package fsm_pool
|
||||||
|
|
||||||
|
/*
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_InitPool(t *testing.T) {
|
||||||
|
|
||||||
|
} */
|
|
@ -14,17 +14,17 @@ import (
|
||||||
// Is machine state scope dump will be locked?
|
// Is machine state scope dump will be locked?
|
||||||
type FSMDump struct {
|
type FSMDump struct {
|
||||||
Id string
|
Id string
|
||||||
State string
|
State fsm.State
|
||||||
Payload internal.MachineStatePayload
|
Payload internal.MachineStatePayload
|
||||||
}
|
}
|
||||||
|
|
||||||
type FSMInstance struct {
|
type FSMInstance struct {
|
||||||
machine fsm_pool.IStateMachine
|
machine fsm_pool.MachineProvider
|
||||||
dump *FSMDump
|
dump *FSMDump
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
fsmPoolProvider *fsm_pool.FSMPoolProvider
|
fsmPoolProvider *fsm_pool.FSMPool
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -53,7 +53,7 @@ func New(data []byte) (*FSMInstance, error) {
|
||||||
return i, err
|
return i, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *FSMInstance) Do(event string, args ...interface{}) (*fsm.FSMResponse, []byte, error) {
|
func (i *FSMInstance) Do(event fsm.Event, args ...interface{}) (*fsm.Response, []byte, error) {
|
||||||
// Provide payload as first argument ever
|
// Provide payload as first argument ever
|
||||||
result, err := i.machine.Do(event, append([]interface{}{i.dump.Payload}, args...)...)
|
result, err := i.machine.Do(event, append([]interface{}{i.dump.Payload}, args...)...)
|
||||||
|
|
||||||
|
|
|
@ -19,18 +19,18 @@ type SignatureConstructFSM struct {
|
||||||
*fsm.FSM
|
*fsm.FSM
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() fsm_pool.IStateMachine {
|
func New() fsm_pool.MachineProvider {
|
||||||
machine := &SignatureConstructFSM{}
|
machine := &SignatureConstructFSM{}
|
||||||
|
|
||||||
machine.FSM = fsm.MustNewFSM(
|
machine.FSM = fsm.MustNewFSM(
|
||||||
fsmName,
|
fsmName,
|
||||||
stateConstructorEntryPoint,
|
stateConstructorEntryPoint,
|
||||||
[]fsm.Event{
|
[]fsm.EventDesc{
|
||||||
// {Name: "", SrcState: []string{""}, DstState: ""},
|
// {Name: "", SrcState: []string{""}, DstState: ""},
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
{Name: eventInitSignatureConstructor, SrcState: []string{stateConstructorEntryPoint}, DstState: awaitConstructor},
|
{Name: eventInitSignatureConstructor, SrcState: []fsm.State{stateConstructorEntryPoint}, DstState: awaitConstructor},
|
||||||
{Name: eventInitSignatureFinishTmp, SrcState: []string{awaitConstructor}, DstState: "dkg_proposal_fsm"},
|
{Name: eventInitSignatureFinishTmp, SrcState: []fsm.State{awaitConstructor}, DstState: "dkg_proposal_fsm"},
|
||||||
},
|
},
|
||||||
fsm.Callbacks{},
|
fsm.Callbacks{},
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
"github.com/depools/dc4bc/fsm/fsm"
|
||||||
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
"github.com/depools/dc4bc/fsm/state_machines/internal"
|
||||||
"github.com/depools/dc4bc/fsm/types/requests"
|
"github.com/depools/dc4bc/fsm/types/requests"
|
||||||
"github.com/depools/dc4bc/fsm/types/responses"
|
"github.com/depools/dc4bc/fsm/types/responses"
|
||||||
|
@ -11,7 +12,7 @@ import (
|
||||||
|
|
||||||
// init -> awaitingConfirmations
|
// init -> awaitingConfirmations
|
||||||
// args: payload, signing id, participants list
|
// args: payload, signing id, participants list
|
||||||
func (s *SignatureProposalFSM) actionInitProposal(event string, args ...interface{}) (response interface{}, err error) {
|
func (s *SignatureProposalFSM) actionInitProposal(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||||
var payload internal.MachineStatePayload
|
var payload internal.MachineStatePayload
|
||||||
// Init proposal
|
// Init proposal
|
||||||
log.Println("I'm actionInitProposal")
|
log.Println("I'm actionInitProposal")
|
||||||
|
@ -83,17 +84,17 @@ func (s *SignatureProposalFSM) actionInitProposal(event string, args ...interfac
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
func (s *SignatureProposalFSM) actionConfirmProposalByParticipant(event string, args ...interface{}) (response interface{}, err error) {
|
func (s *SignatureProposalFSM) actionConfirmProposalByParticipant(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||||
log.Println("I'm actionConfirmProposalByParticipant")
|
log.Println("I'm actionConfirmProposalByParticipant")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignatureProposalFSM) actionDeclineProposalByParticipant(event string, args ...interface{}) (response interface{}, err error) {
|
func (s *SignatureProposalFSM) actionDeclineProposalByParticipant(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||||
log.Println("I'm actionDeclineProposalByParticipant")
|
log.Println("I'm actionDeclineProposalByParticipant")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SignatureProposalFSM) actionValidateProposal(event string, args ...interface{}) (response interface{}, err error) {
|
func (s *SignatureProposalFSM) actionValidateProposal(event fsm.Event, args ...interface{}) (response interface{}, err error) {
|
||||||
log.Println("I'm actionValidateProposal")
|
log.Println("I'm actionValidateProposal")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,53 +9,53 @@ const (
|
||||||
fsmName = "signature_proposal_fsm"
|
fsmName = "signature_proposal_fsm"
|
||||||
signingIdLen = 32
|
signingIdLen = 32
|
||||||
|
|
||||||
stateAwaitProposalConfirmation = "validate_proposal" // waiting participants
|
stateAwaitProposalConfirmation = fsm.State("validate_proposal") // waiting participants
|
||||||
|
|
||||||
stateValidationCanceledByParticipant = "validation_canceled_by_participant"
|
stateValidationCanceledByParticipant = fsm.State("validation_canceled_by_participant")
|
||||||
stateValidationCanceledByTimeout = "validation_canceled_by_timeout"
|
stateValidationCanceledByTimeout = fsm.State("validation_canceled_by_timeout")
|
||||||
|
|
||||||
stateProposed = "proposed"
|
stateProposed = "proposed"
|
||||||
|
|
||||||
eventInitProposal = "proposal_init"
|
eventInitProposal = fsm.Event("proposal_init")
|
||||||
eventConfirmProposal = "proposal_confirm_by_participant"
|
eventConfirmProposal = fsm.Event("proposal_confirm_by_participant")
|
||||||
eventDeclineProposal = "proposal_decline_by_participant"
|
eventDeclineProposal = fsm.Event("proposal_decline_by_participant")
|
||||||
eventValidateProposal = "proposal_validate"
|
eventValidateProposal = fsm.Event("proposal_validate")
|
||||||
eventSetProposalValidated = "proposal_set_validated"
|
eventSetProposalValidated = fsm.Event("proposal_set_validated")
|
||||||
|
|
||||||
eventSetValidationCanceledByTimeout = "proposal_canceled_timeout"
|
eventSetValidationCanceledByTimeout = fsm.Event("proposal_canceled_timeout")
|
||||||
eventSwitchProposedToSigning = "switch_state_to_signing"
|
eventSwitchProposedToSigning = fsm.Event("switch_state_to_signing")
|
||||||
)
|
)
|
||||||
|
|
||||||
type SignatureProposalFSM struct {
|
type SignatureProposalFSM struct {
|
||||||
*fsm.FSM
|
*fsm.FSM
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() fsm_pool.IStateMachine {
|
func New() fsm_pool.MachineProvider {
|
||||||
machine := &SignatureProposalFSM{}
|
machine := &SignatureProposalFSM{}
|
||||||
|
|
||||||
machine.FSM = fsm.MustNewFSM(
|
machine.FSM = fsm.MustNewFSM(
|
||||||
fsmName,
|
fsmName,
|
||||||
fsm.StateGlobalIdle,
|
fsm.StateGlobalIdle,
|
||||||
[]fsm.Event{
|
[]fsm.EventDesc{
|
||||||
// {Name: "", SrcState: []string{""}, DstState: ""},
|
// {Name: "", SrcState: []string{""}, DstState: ""},
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
{Name: eventInitProposal, SrcState: []string{fsm.StateGlobalIdle}, DstState: stateAwaitProposalConfirmation},
|
{Name: eventInitProposal, SrcState: []fsm.State{fsm.StateGlobalIdle}, DstState: stateAwaitProposalConfirmation},
|
||||||
|
|
||||||
// Validate by participants
|
// Validate by participants
|
||||||
{Name: eventConfirmProposal, SrcState: []string{stateAwaitProposalConfirmation}, DstState: stateAwaitProposalConfirmation},
|
{Name: eventConfirmProposal, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateAwaitProposalConfirmation},
|
||||||
// Is decline event should auto change state to default, or it process will initiated by client (external emit)?
|
// Is decline event should auto change state to default, or it process will initiated by client (external emit)?
|
||||||
// Now set for external emitting.
|
// Now set for external emitting.
|
||||||
{Name: eventDeclineProposal, SrcState: []string{stateAwaitProposalConfirmation}, DstState: stateValidationCanceledByParticipant},
|
{Name: eventDeclineProposal, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateValidationCanceledByParticipant},
|
||||||
|
|
||||||
{Name: eventValidateProposal, SrcState: []string{stateAwaitProposalConfirmation}, DstState: stateAwaitProposalConfirmation},
|
{Name: eventValidateProposal, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateAwaitProposalConfirmation},
|
||||||
|
|
||||||
// eventProposalValidate internal or from client?
|
// eventProposalValidate internal or from client?
|
||||||
// yay
|
// yay
|
||||||
// Exit point
|
// Exit point
|
||||||
{Name: eventSetProposalValidated, SrcState: []string{stateAwaitProposalConfirmation}, DstState: "process_sig", IsInternal: true},
|
{Name: eventSetProposalValidated, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: "process_sig", IsInternal: true},
|
||||||
// nan
|
// nan
|
||||||
{Name: eventSetValidationCanceledByTimeout, SrcState: []string{stateAwaitProposalConfirmation}, DstState: stateValidationCanceledByTimeout, IsInternal: true},
|
{Name: eventSetValidationCanceledByTimeout, SrcState: []fsm.State{stateAwaitProposalConfirmation}, DstState: stateValidationCanceledByTimeout, IsInternal: true},
|
||||||
},
|
},
|
||||||
fsm.Callbacks{
|
fsm.Callbacks{
|
||||||
eventInitProposal: machine.actionInitProposal,
|
eventInitProposal: machine.actionInitProposal,
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -8,7 +8,6 @@ require (
|
||||||
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b
|
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b
|
||||||
github.com/looplab/fsm v0.1.0
|
github.com/looplab/fsm v0.1.0
|
||||||
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7
|
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7
|
||||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f // indirect
|
|
||||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||||
github.com/stretchr/testify v1.6.1
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/syndtr/goleveldb v1.0.0
|
github.com/syndtr/goleveldb v1.0.0
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -20,10 +20,6 @@ github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20=
|
||||||
github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
|
github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
|
||||||
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7 h1:CfWnkHgRG8zmxQI7RAhLIUFPkg+RfDdWiEtoE3y1+4w=
|
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7 h1:CfWnkHgRG8zmxQI7RAhLIUFPkg+RfDdWiEtoE3y1+4w=
|
||||||
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7/go.mod h1:WoI7z45M7ZNA5BJxiJHaB+x7+k8S/3phW5Y13IR4yWY=
|
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7/go.mod h1:WoI7z45M7ZNA5BJxiJHaB+x7+k8S/3phW5Y13IR4yWY=
|
||||||
github.com/mattn/go-gtk v0.0.0-20191030024613-af2e013261f5 h1:GMB3MVJnxysGrSvjWGsgK8L3XGI3F4etQQq37Py6W5A=
|
|
||||||
github.com/mattn/go-gtk v0.0.0-20191030024613-af2e013261f5/go.mod h1:PwzwfeB5syFHXORC3MtPylVcjIoTDT/9cvkKpEndGVI=
|
|
||||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f h1:QTRRO+ozoYgT3CQRIzNVYJRU3DB8HRnkZv6mr4ISmMA=
|
|
||||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
|
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
@ -51,9 +47,11 @@ golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7
|
||||||
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI=
|
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI=
|
||||||
|
|
Loading…
Reference in New Issue