-
Notifications
You must be signed in to change notification settings - Fork 199
/
interface.go
282 lines (250 loc) · 10.5 KB
/
interface.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
package dataRetriever
import (
"time"
"github.com/ElrondNetwork/elrond-go/data"
"github.com/ElrondNetwork/elrond-go/data/block"
"github.com/ElrondNetwork/elrond-go/p2p"
"github.com/ElrondNetwork/elrond-go/storage"
)
// UnitType is the type for Storage unit identifiers
type UnitType uint8
const (
// TransactionUnit is the transactions storage unit identifier
TransactionUnit UnitType = 0
// MiniBlockUnit is the transaction block body storage unit identifier
MiniBlockUnit UnitType = 1
// PeerChangesUnit is the peer change block body storage unit identifier
PeerChangesUnit UnitType = 2
// BlockHeaderUnit is the Block Headers Storage unit identifier
BlockHeaderUnit UnitType = 3
// MetaBlockUnit is the metachain blocks storage unit identifier
MetaBlockUnit UnitType = 4
// UnsignedTransactionUnit is the unsigned transaction unit identifier
UnsignedTransactionUnit UnitType = 5
// RewardTransactionUnit is the reward transaction unit identifier
RewardTransactionUnit UnitType = 6
// MetaHdrNonceHashDataUnit is the meta header nonce-hash pair data unit identifier
MetaHdrNonceHashDataUnit UnitType = 7
// HeartbeatUnit is the heartbeat storage unit identifier
HeartbeatUnit UnitType = 8
// MiniBlockHeaderUnit is the miniblock header data unit identifier
MiniBlockHeaderUnit UnitType = 9
// BootstrapUnit is the bootstrap storage unit identifier
BootstrapUnit UnitType = 10
//StatusMetricsUnit is the status metrics storage unit identifier
StatusMetricsUnit UnitType = 11
// ShardHdrNonceHashDataUnit is the header nonce-hash pair data unit identifier
//TODO: Add only unit types lower than 100
ShardHdrNonceHashDataUnit UnitType = 100
//TODO: Do not add unit type greater than 100 as the metachain creates this kind of unit type for each shard.
//100 -> shard 0, 101 -> shard 1 and so on. This should be replaced with a factory which will manage the unit types
//creation
)
// Resolver defines what a data resolver should do
type Resolver interface {
RequestDataFromHash(hash []byte, epoch uint32) error
ProcessReceivedMessage(message p2p.MessageP2P, broadcastHandler func(buffToSend []byte)) error
IsInterfaceNil() bool
}
// HeaderResolver defines what a block header resolver should do
type HeaderResolver interface {
Resolver
RequestDataFromNonce(nonce uint64, epoch uint32) error
RequestDataFromEpoch(identifier []byte) error
SetEpochHandler(epochHandler EpochHandler) error
}
// MiniBlocksResolver defines what a mini blocks resolver should do
type MiniBlocksResolver interface {
Resolver
RequestDataFromHashArray(hashes [][]byte, epoch uint32) error
GetMiniBlocks(hashes [][]byte) (block.MiniBlockSlice, [][]byte)
GetMiniBlocksFromPool(hashes [][]byte) (block.MiniBlockSlice, [][]byte)
}
// TopicResolverSender defines what sending operations are allowed for a topic resolver
type TopicResolverSender interface {
SendOnRequestTopic(rd *RequestData) error
Send(buff []byte, peer p2p.PeerID) error
TopicRequestSuffix() string
TargetShardID() uint32
IsInterfaceNil() bool
}
// ResolversContainer defines a resolvers holder data type with basic functionality
type ResolversContainer interface {
Get(key string) (Resolver, error)
Add(key string, val Resolver) error
AddMultiple(keys []string, resolvers []Resolver) error
Replace(key string, val Resolver) error
Remove(key string)
Len() int
IsInterfaceNil() bool
}
// ResolversFinder extends a container resolver and have 2 additional functionality
type ResolversFinder interface {
ResolversContainer
IntraShardResolver(baseTopic string) (Resolver, error)
MetaChainResolver(baseTopic string) (Resolver, error)
CrossShardResolver(baseTopic string, crossShard uint32) (Resolver, error)
}
// ResolversContainerFactory defines the functionality to create a resolvers container
type ResolversContainerFactory interface {
Create() (ResolversContainer, error)
IsInterfaceNil() bool
}
// EpochHandler defines the functionality to get the current epoch
type EpochHandler interface {
Epoch() uint32
IsInterfaceNil() bool
}
// EpochProviderByNonce defines the functionality needed for calculating an epoch based on nonce
type EpochProviderByNonce interface {
EpochForNonce(nonce uint64) (uint32, error)
IsInterfaceNil() bool
}
// MessageHandler defines the functionality needed by structs to send data to other peers
type MessageHandler interface {
ConnectedPeersOnTopic(topic string) []p2p.PeerID
SendToConnectedPeer(topic string, buff []byte, peerID p2p.PeerID) error
IsInterfaceNil() bool
}
// TopicHandler defines the functionality needed by structs to manage topics and message processors
type TopicHandler interface {
HasTopic(name string) bool
CreateTopic(name string, createChannelForTopic bool) error
RegisterMessageProcessor(topic string, handler p2p.MessageProcessor) error
}
// TopicMessageHandler defines the functionality needed by structs to manage topics, message processors and to send data
// to other peers
type TopicMessageHandler interface {
MessageHandler
TopicHandler
}
// IntRandomizer interface provides functionality over generating integer numbers
type IntRandomizer interface {
Intn(n int) (int, error)
IsInterfaceNil() bool
}
// StorageType defines the storage levels on a node
type StorageType uint8
// DataRetriever interface provides functionality over high level data request component
type DataRetriever interface {
// Get methods searches for data in storage units and returns results, it is a blocking function
Get(keys [][]byte, identifier string, lowestLevel StorageType, haveTime func() time.Duration) (map[string]interface{}, [][]byte, error)
// Has searches for a value identifier by a key in storage
Has(key []byte, identifier string, level StorageType) (StorageType, error)
// HasOrAdd searches and adds a value if not exist in storage
HasOrAdd(key []byte, value interface{}, identifier string, level StorageType)
// Remove deletes an element from storage level
Remove(key []byte, identifier string, lowestLevel StorageType) error
// Put saves a key-value pair into storage
Put(key []byte, value interface{}, identifier string, level StorageType) error
// Keys returns all the keys from an identifier and storage type
Keys(identifier string, level StorageType)
// Request searches for data in specified storage level, if not present launches threads to search in network
Request(keys [][]byte, identifier string, level StorageType, haveTime func() time.Duration, callbackHandler func(key []byte)) (map[string]interface{}, [][]byte, error)
// IsInterfaceNil returns true if there is no value under the interface
IsInterfaceNil() bool
}
// Notifier defines a way to register funcs that get called when something useful happens
type Notifier interface {
RegisterHandler(func(key []byte))
IsInterfaceNil() bool
}
// PeerListCreator is used to create a peer list
type PeerListCreator interface {
PeerList() []p2p.PeerID
IsInterfaceNil() bool
}
// ShardedDataCacherNotifier defines what a sharded-data structure can perform
type ShardedDataCacherNotifier interface {
Notifier
ShardDataStore(cacheId string) (c storage.Cacher)
AddData(key []byte, data interface{}, cacheId string)
SearchFirstData(key []byte) (value interface{}, ok bool)
RemoveData(key []byte, cacheId string)
RemoveSetOfDataFromPool(keys [][]byte, cacheId string)
RemoveDataFromAllShards(key []byte)
MergeShardStores(sourceCacheID, destCacheID string)
Clear()
ClearShardStore(cacheId string)
CreateShardStore(cacheId string)
}
// ShardIdHashMap represents a map for shardId and hash
type ShardIdHashMap interface {
Load(shardId uint32) ([]byte, bool)
Store(shardId uint32, hash []byte)
Range(f func(shardId uint32, hash []byte) bool)
Delete(shardId uint32)
IsInterfaceNil() bool
}
// HeadersPool defines what a headers pool structure can perform
type HeadersPool interface {
Clear()
AddHeader(headerHash []byte, header data.HeaderHandler)
RemoveHeaderByHash(headerHash []byte)
RemoveHeaderByNonceAndShardId(headerNonce uint64, shardId uint32)
GetHeadersByNonceAndShardId(headerNonce uint64, shardId uint32) ([]data.HeaderHandler, [][]byte, error)
GetHeaderByHash(hash []byte) (data.HeaderHandler, error)
RegisterHandler(handler func(headerHandler data.HeaderHandler, headerHash []byte))
Nonces(shardId uint32) []uint64
Len() int
MaxSize() int
IsInterfaceNil() bool
}
// TransactionCacher defines the methods for the local cacher, info for current round
type TransactionCacher interface {
Clean()
GetTx(txHash []byte) (data.TransactionHandler, error)
AddTx(txHash []byte, tx data.TransactionHandler)
IsInterfaceNil() bool
}
// PoolsHolder defines getters for data pools
type PoolsHolder interface {
Transactions() ShardedDataCacherNotifier
UnsignedTransactions() ShardedDataCacherNotifier
RewardTransactions() ShardedDataCacherNotifier
Headers() HeadersPool
MiniBlocks() storage.Cacher
PeerChangesBlocks() storage.Cacher
TrieNodes() storage.Cacher
CurrentBlockTxs() TransactionCacher
IsInterfaceNil() bool
}
// StorageService is the interface for data storage unit provided services
type StorageService interface {
// GetStorer returns the storer from the chain map
GetStorer(unitType UnitType) storage.Storer
// AddStorer will add a new storer to the chain map
AddStorer(key UnitType, s storage.Storer)
// Has returns true if the key is found in the selected Unit or false otherwise
Has(unitType UnitType, key []byte) error
// Get returns the value for the given key if found in the selected storage unit, nil otherwise
Get(unitType UnitType, key []byte) ([]byte, error)
// Put stores the key, value pair in the selected storage unit
Put(unitType UnitType, key []byte, value []byte) error
// GetAll gets all the elements with keys in the keys array, from the selected storage unit
// If there is a missing key in the unit, it returns an error
GetAll(unitType UnitType, keys [][]byte) (map[string][]byte, error)
// Destroy removes the underlying files/resources used by the storage service
Destroy() error
//CloseAll will close all the units
CloseAll() error
// IsInterfaceNil returns true if there is no value under the interface
IsInterfaceNil() bool
}
// DataPacker can split a large slice of byte slices in smaller packets
type DataPacker interface {
PackDataInChunks(data [][]byte, limit int) ([][]byte, error)
IsInterfaceNil() bool
}
// TrieDataGetter returns requested data from the trie
type TrieDataGetter interface {
GetSerializedNodes([]byte, uint64) ([][]byte, error)
IsInterfaceNil() bool
}
// RequestedItemsHandler can determine if a certain key has or not been requested
type RequestedItemsHandler interface {
Add(key string) error
Has(key string) bool
Sweep()
IsInterfaceNil() bool
}