forked from FactomProject/factomd
-
Notifications
You must be signed in to change notification settings - Fork 0
/
state.go
375 lines (316 loc) · 12.9 KB
/
state.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
// Copyright 2017 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package interfaces
import (
"regexp"
"time"
"github.com/FactomProject/factomd/activations"
"github.com/FactomProject/factomd/common/constants/runstate"
)
type DBStateSent struct {
DBHeight uint32
Sent Timestamp
}
// IQueue is the interface returned by returning queue functions
type IQueue interface {
Length() int
Cap() int
Enqueue(msg IMsg)
Dequeue() IMsg
BlockingDequeue() IMsg
}
// Holds the state information for factomd. This does imply that we will be
// using accessors to access state information in the consensus algorithm.
// This is a bit tedious, but does provide single choke points where information
// can be logged about the execution of Factom. Also ensures that we do not
// accidentally
type IState interface {
GetRunState() runstate.RunState
GetRunLeader() bool
// Server
GetFactomNodeName() string
GetSalt(Timestamp) uint32 // A secret number computed from a TS that tests if a message was issued from this server or not
Clone(number int) IState
GetCfg() IFactomConfig
GetConfigPath() string
LoadConfig(filename string, networkFlag string)
Init()
String() string
GetIdentityChainID() IHash
SetIdentityChainID(IHash)
Sign([]byte) IFullSignature
Log(level string, message string)
Logf(level string, format string, args ...interface{})
GetServerPublicKeyString() string
GetDBStatesSent() []*DBStateSent
SetDBStatesSent([]*DBStateSent)
GetDirectoryBlockInSeconds() int
SetDirectoryBlockInSeconds(int)
GetFactomdVersion() string
GetDBHeightComplete() uint32
GetDBHeightAtBoot() uint32
DatabaseContains(hash IHash) bool
SetOut(bool) // Output is turned on if set to true
GetOut() bool // Return true if Print or Println write output
LoadDataByHash(requestedHash IHash) (BinaryMarshallable, int, error)
LoadDBState(dbheight uint32) (IMsg, error)
LoadSpecificMsg(dbheight uint32, vm int, plistheight uint32) (IMsg, error)
LoadSpecificMsgAndAck(dbheight uint32, vm int, plistheight uint32) (IMsg, IMsg, error)
SetString()
ShortString() string
GetStatus() []string
AddStatus(status string)
AddDBSig(dbheight uint32, chainID IHash, sig IFullSignature)
AddPrefix(string)
AddFedServer(uint32, IHash) int
GetFedServers(uint32) []IServer
RemoveFedServer(uint32, IHash)
AddAuditServer(uint32, IHash) int
GetAuditServers(uint32) []IServer
GetOnlineAuditServers(uint32) []IServer
//RPC
GetRpcUser() string
GetRpcPass() string
SetRpcAuthHash(authHash []byte)
GetRpcAuthHash() []byte
GetTlsInfo() (bool, string, string)
GetFactomdLocations() string
GetCorsDomains() []string
// Routine for handling the syncroniztion of the leader and follower processes
// and how they process messages.
Process() (progress bool)
// This is the highest block completed. It may or may not be saved in the Database. This
// is a follower's state, but it is also critical to validation; we cannot
// validate transactions where the HighestRecordedBlock+1 != block holding said
// transaction.
GetHighestSavedBlk() uint32
// This is the highest block saved in the Database. A block is completed, then validated
// then saved.
GetHighestCompletedBlk() uint32
// This is the Leader's view of the Height. It must be == HighestRecordedBlock+1. Since
// Recording a block can take time, messages must be queued until the previous block is
// recorded (either by processing messages, or timing out and Leaders signing off the block)
GetLeaderHeight() uint32
// The highest block for which we have received a message. This is a
// Follower's understanding of the Height, and reflects what block
// is receiving messages.
GetHighestKnownBlock() uint32
// Find a Directory Block by height
GetDirectoryBlockByHeight(dbheight uint32) IDirectoryBlock
// Channels
//==========
// Network Processor
TickerQueue() chan int
TimerMsgQueue() chan IMsg
NetworkOutMsgQueue() IQueue
NetworkInvalidMsgQueue() chan IMsg
// Journaling
JournalMessage(IMsg)
GetJournalMessages() [][]byte
// Consensus
APIQueue() IQueue // Input Queue from the API
InMsgQueue() IQueue // Read by Validate
AckQueue() chan IMsg // Ack Message Queue
MsgQueue() chan IMsg // Other Messages Queue
ElectionsQueue() IQueue
// Lists and Maps
// =====
GetAuditHeartBeats() []IMsg // The checklist of HeartBeats for this period
GetNewEBlocks(dbheight uint32, hash IHash) IEntryBlock
PutNewEBlocks(dbheight uint32, hash IHash, eb IEntryBlock)
PutNewEntries(dbheight uint32, hash IHash, eb IEntry)
GetPendingEntries(interface{}) []IPendingEntry
NextCommit(hash IHash) IMsg
PutCommit(hash IHash, msg IMsg)
IncEntryChains()
IncEntries()
IncECCommits()
IncECommits()
IncFCTSubmits()
// Server Configuration
// ====================
//Network MAIN = 0, TEST = 1, LOCAL = 2, CUSTOM = 3
GetNetworkNumber() int // Encoded into Directory Blocks
GetNetworkName() string // Some networks have defined names
GetNetworkID() uint32
// Bootstrap Identity Information is dependent on Network
GetNetworkBootStrapKey() IHash
GetNetworkBootStrapIdentity() IHash
// Skeleton Identity Information.
GetNetworkSkeletonIdentity() IHash
GetNetworkSkeletonKey() IHash
IntiateNetworkSkeletonIdentity() error
// Getting info about an identity
GetSigningKey(id IHash) (IHash, int)
GetMatryoshka(dbheight uint32) IHash // Reverse Hash
// These are methods run by the consensus algorithm to track what servers are the leaders
// and what lists they are responsible for.
ComputeVMIndex(hash []byte) int // Returns the VMIndex determined by some hash (usually) for the current processlist
IsLeader() bool // Returns true if this is the leader in the current minute
GetLeaderVM() int // Get the Leader VM (only good within a minute)
// Returns the list of VirtualServers at a given directory block height and minute
GetVirtualServers(dbheight uint32, minute int, identityChainID IHash) (found bool, index int)
// Returns true if between minutes
// Get the message for the given vm index, dbheight, and height. Returns nil if I
// have no such message.
GetMsg(vmIndex int, dbheight int, height int) (IMsg, error)
GetEBlockKeyMRFromEntryHash(entryHash IHash) IHash
GetAnchor() IAnchor
// Database
GetDB() DBOverlaySimple
// Web Services
// ============
SetPort(int)
GetPort() int
// Factoid State
// =============
UpdateState() bool
GetSystemHeight(dbheight uint32) int
GetFactoidState() IFactoidState
SetFactoidState(dbheight uint32, fs IFactoidState)
GetFactoshisPerEC() uint64
SetFactoshisPerEC(factoshisPerEC uint64)
IncFactoidTrans()
IncDBStateAnswerCnt()
GetPendingTransactions(interface{}) []IPendingTransaction
// MISC
// ====
Reset() // Trim back the state to the last saved block
GetSystemMsg(dbheight, height uint32) IMsg // Return the system message at the given height.
SendDBSig(dbheight uint32, vmIndex int) // If a Leader, we have to send a DBSig out for the previous block
FollowerExecuteMsg(IMsg) // Messages that go into the process list
FollowerExecuteEOM(IMsg) // Messages that go into the process list
FollowerExecuteAck(IMsg) // Ack Msg calls this function.
FollowerExecuteDBState(IMsg) // Add the given DBState to this server
FollowerExecuteSFault(IMsg) // Handling of Server Fault Messages
FollowerExecuteFullFault(IMsg) // Handle Server Full-Fault Messages
FollowerExecuteMMR(IMsg) // Handle Missing Message Responses
FollowerExecuteDataResponse(IMsg) // Handle Data Response
FollowerExecuteMissingMsg(IMsg) // Handle requests for missing messages
FollowerExecuteCommitChain(IMsg) // CommitChain needs to look for a Reveal Entry
FollowerExecuteCommitEntry(IMsg) // CommitEntry needs to look for a Reveal Entry
FollowerExecuteRevealEntry(IMsg)
ProcessAddServer(dbheight uint32, addServerMsg IMsg) bool
ProcessRemoveServer(dbheight uint32, removeServerMsg IMsg) bool
ProcessChangeServerKey(dbheight uint32, changeServerKeyMsg IMsg) bool
ProcessCommitChain(dbheight uint32, commitChain IMsg) bool
ProcessCommitEntry(dbheight uint32, commitChain IMsg) bool
ProcessDBSig(dbheight uint32, commitChain IMsg) bool
ProcessEOM(dbheight uint32, eom IMsg) bool
ProcessRevealEntry(dbheight uint32, m IMsg) bool
// For messages that go into the Process List
LeaderExecute(IMsg)
LeaderExecuteEOM(IMsg)
LeaderExecuteDBSig(IMsg)
LeaderExecuteRevealEntry(IMsg)
LeaderExecuteCommitChain(IMsg)
LeaderExecuteCommitEntry(IMsg)
GetNetStateOff() bool // If true, all network communications are disabled
SetNetStateOff(bool)
GetTimestamp() Timestamp
GetTimeOffset() Timestamp
GetTrueLeaderHeight() uint32
Print(a ...interface{}) (n int, err error)
Println(a ...interface{}) (n int, err error)
ValidatorLoop()
UpdateECs(IEntryCreditBlock)
SetIsReplaying()
SetIsDoneReplaying()
CrossReplayAddSalt(height uint32, salt [8]byte) error
// No Entry Yet returns true if no Entry Hash is found in the Replay structs.
// Returns false if we have seen an Entry Replay in the current period.
NoEntryYet(IHash, Timestamp) bool
// Calculates the transaction rate this node is seeing.
// totalTPS : Total transactions / total time node running
// instantTPS : Weighted transactions per second to get a better value for
// current transaction rate.
CalculateTransactionRate() (totalTPS float64, instantTPS float64)
//For ACK
GetACKStatus(hash IHash) (int, IHash, Timestamp, Timestamp, error)
GetSpecificACKStatus(hash IHash) (int, IHash, Timestamp, Timestamp, error)
// Acks with ChainIDs so you can select which hash type
GetEntryCommitAckByEntryHash(hash IHash) (status int, commit IMsg)
GetEntryRevealAckByEntryHash(hash IHash) (status int, blktime Timestamp, commit IMsg)
GetEntryCommitAckByTXID(hash IHash) (status int, blktime Timestamp, commit IMsg, entryhash IHash)
IsNewOrPendingEBlocks(dbheight uint32, hash IHash) bool
// Used in API to reject commits properly and inform user
IsHighestCommit(hash IHash, msg IMsg) bool
FetchPaidFor(hash IHash) (IHash, error)
FetchFactoidTransactionByHash(hash IHash) (ITransaction, error)
FetchECTransactionByHash(hash IHash) (IECBlockEntry, error)
FetchEntryByHash(IHash) (IEBEntry, error)
FetchEntryHashFromProcessListsByTxID(string) (IHash, error)
// FER section
ProcessRecentFERChainEntries()
ExchangeRateAuthorityIsValid(IEBEntry) bool
FerEntryIsValid(passedFEREntry IFEREntry) bool
GetPredictiveFER() uint64
// Identity Section
VerifyIsAuthority(cid IHash) bool // True if is authority
UpdateAuthorityFromABEntry(entry IABEntry) error
VerifyAuthoritySignature(Message []byte, signature *[64]byte, dbheight uint32) (int, error)
FastVerifyAuthoritySignature(Message []byte, signature IFullSignature, dbheight uint32) (int, error)
UpdateAuthSigningKeys(height uint32)
AddIdentityFromChainID(cid IHash) error
AddAuthorityDelta(changeString string)
GetElections() IElections
GetAuthorities() []IAuthority
GetAuthorityInterface(chainid IHash) IAuthority
GetLeaderPL() IProcessList
GetLLeaderHeight() uint32
GetEntryDBHeightComplete() uint32
GetMissingEntryCount() uint32
GetEntryBlockDBHeightProcessing() uint32
GetEntryBlockDBHeightComplete() uint32
GetCurrentBlockStartTime() int64
GetCurrentMinute() int
GetCurrentMinuteStartTime() int64
GetPreviousMinuteStartTime() int64
GetCurrentTime() int64
IsStalled() bool
GetDelay() int64
SetDelay(int64)
GetDropRate() int
SetDropRate(int)
GetBootTime() int64
IsSyncing() bool
IsSyncingEOMs() bool
IsSyncingDBSigs() bool
DidCreateLastBlockFromDBState() bool
GetUnsyncedServers() (ids []IHash, vms []int)
Validate(msg IMsg) (validToSend int, validToExecute int)
GetIgnoreDone() bool
// Access to Holding Queue
LoadHoldingMap() map[[32]byte]IMsg
LoadAcksMap() map[[32]byte]IMsg
// Plugins
UsingTorrent() bool
GetMissingDBState(height uint32) error
LogMessage(logName string, comment string, msg IMsg)
LogPrintf(logName string, format string, more ...interface{})
GetHighestAck() uint32
SetHighestAck(uint32)
DebugExec() bool
CheckFileName(string) bool
// Filters
AddToReplayFilter(mask int, hash [32]byte, timestamp Timestamp, systemtime Timestamp) bool
// Activations -------------------------------------------------------
IsActive(id activations.ActivationType) bool
// Holding of dependent messages -------------------------------------
// Add a message to a dependent holding list
Add(h [32]byte, msg IMsg) int
// expire any dependent messages that are in holding but are older than limit
// Execute messages when a dependency is met
ExecuteFromHolding(h [32]byte)
// create a hash to hold messages that depend on height
HoldForHeight(ht uint32, minute int, msg IMsg) int
// test/debug filters
PassOutputRegEx(*regexp.Regexp, string)
GetOutputRegEx() (*regexp.Regexp, string)
PassInputRegEx(*regexp.Regexp, string)
GetInputRegEx() (*regexp.Regexp, string)
GotHeartbeat(heartbeatTS Timestamp, dbheight uint32)
GetDBFinished() bool
FactomSecond() time.Duration
}