1// SPDX-License-Identifier: ISC
2// Copyright (c) 2014-2020 Bitmark Inc.
3// Use of this source code is governed by an ISC
4// license that can be found in the LICENSE file.
5
6package proof
7
8import (
9	"sync"
10
11	"github.com/bitmark-inc/bitmarkd/background"
12	"github.com/bitmark-inc/bitmarkd/chain"
13	"github.com/bitmark-inc/bitmarkd/fault"
14	"github.com/bitmark-inc/bitmarkd/mode"
15	"github.com/bitmark-inc/logger"
16)
17
18const (
19	internalHasherRequest = "inproc://internal-hasher-request"
20	internalHasherReply   = "inproc://internal-hasher-reply"
21)
22
23// Configuration - server identification in Z85 (ZeroMQ Base-85 Encoding) see: http://rfc.zeromq.org/spec:32
24// a block of configuration data
25// this is read from the configuration file
26type Configuration struct {
27	Publish            []string          `gluamapper:"publish" json:"publish"`
28	Submit             []string          `gluamapper:"submit" json:"submit"`
29	PrivateKey         string            `gluamapper:"private_key" json:"private_key"`
30	PublicKey          string            `gluamapper:"public_key" json:"public_key"`
31	SigningKey         string            `gluamapper:"signing_key" json:"signing_key"`
32	PaymentAddr        map[string]string `gluamapper:"payment_address" json:"payment_address"`
33	InternalHashEnable bool              `gluamapper:"local_use_internal_hash" json:"local_use_internal_hash"`
34}
35
36// globals for background process
37type proofData struct {
38	sync.RWMutex // to allow locking
39
40	// logger
41	log *logger.L
42
43	// for publisher
44	pub publisher
45
46	// for submission
47	sub submission
48
49	// for background
50	background *background.T
51
52	// set once during initialise
53	initialised bool
54}
55
56// global data
57var globalData proofData
58
59// Initialise - start proofer background processes
60func Initialise(configuration *Configuration) error {
61
62	globalData.Lock()
63	defer globalData.Unlock()
64
65	// no need to start if already started
66	if globalData.initialised {
67		return fault.AlreadyInitialised
68	}
69
70	globalData.log = logger.New("proof")
71	globalData.log.Info("starting…")
72
73	if err := globalData.pub.initialise(configuration); nil != err {
74		return err
75	}
76	if err := globalData.sub.initialise(configuration); nil != err {
77		return err
78	}
79
80	// create tae job queue
81	initialiseJobQueue()
82
83	// all data initialised
84	globalData.initialised = true
85
86	// start background processes
87	globalData.log.Info("start background…")
88
89	// list of background processes to start
90	processes := background.Processes{
91		&globalData.pub,
92		&globalData.sub,
93	}
94
95	globalData.background = background.Start(processes, nil)
96
97	// start internal hasher for local chain
98	if mode.ChainName() == chain.Local && configuration.InternalHashEnable {
99		h, err := NewInternalHasherForTest(internalHasherRequest, internalHasherReply)
100		if nil != err {
101			return err
102		}
103		err = h.Initialise()
104		if nil != err {
105			return err
106		}
107		h.Start()
108	}
109
110	return nil
111}
112
113// Finalise - stop all background tasks
114func Finalise() error {
115
116	if !globalData.initialised {
117		return fault.NotInitialised
118	}
119
120	globalData.log.Info("shutting down…")
121	globalData.log.Flush()
122
123	// stop background
124	globalData.background.Stop()
125
126	// finally...
127	globalData.initialised = false
128
129	globalData.log.Info("finished")
130	globalData.log.Flush()
131
132	return nil
133}
134