forked from status-im/status-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.go
413 lines (326 loc) · 13 KB
/
types.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
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
package common
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"os"
"strings"
"time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/les"
"github.com/ethereum/go-ethereum/node"
whisper "github.com/ethereum/go-ethereum/whisper/whisperv5"
"github.com/robertkrimen/otto"
"github.com/status-im/status-go/geth/params"
"github.com/status-im/status-go/geth/rpc"
"github.com/status-im/status-go/static"
)
// errors
var (
ErrDeprecatedMethod = errors.New("Method is depricated and will be removed in future release")
)
// SelectedExtKey is a container for currently selected (logged in) account
type SelectedExtKey struct {
Address common.Address
AccountKey *keystore.Key
SubAccounts []accounts.Account
}
// Hex dumps address of a given extended key as hex string
func (k *SelectedExtKey) Hex() string {
if k == nil {
return "0x0"
}
return k.Address.Hex()
}
// NodeManager defines expected methods for managing Status node
type NodeManager interface {
// StartNode start Status node, fails if node is already started
StartNode(config *params.NodeConfig) (<-chan struct{}, error)
// StopNode stop the running Status node.
// Stopped node cannot be resumed, one starts a new node instead.
StopNode() (<-chan struct{}, error)
// RestartNode restart running Status node, fails if node is not running
RestartNode() (<-chan struct{}, error)
// ResetChainData remove chain data from data directory.
// Node is stopped, and new node is started, with clean data directory.
ResetChainData() (<-chan struct{}, error)
// IsNodeRunning confirm that node is running
IsNodeRunning() bool
// NodeConfig returns reference to running node's configuration
NodeConfig() (*params.NodeConfig, error)
// Node returns underlying Status node
Node() (*node.Node, error)
// PopulateStaticPeers populates node's list of static bootstrap peers
PopulateStaticPeers() error
// AddPeer adds URL of static peer
AddPeer(url string) error
// LightEthereumService exposes reference to LES service running on top of the node
LightEthereumService() (*les.LightEthereum, error)
// WhisperService returns reference to running Whisper service
WhisperService() (*whisper.Whisper, error)
// AccountManager returns reference to node's account manager
AccountManager() (*accounts.Manager, error)
// AccountKeyStore returns reference to account manager's keystore
AccountKeyStore() (*keystore.KeyStore, error)
// RPCClient exposes reference to RPC client connected to the running node
RPCClient() *rpc.Client
}
// AccountManager defines expected methods for managing Status accounts
type AccountManager interface {
// CreateAccount creates an internal geth account
// BIP44-compatible keys are generated: CKD#1 is stored as account key, CKD#2 stored as sub-account root
// Public key of CKD#1 is returned, with CKD#2 securely encoded into account key file (to be used for
// sub-account derivations)
CreateAccount(password string) (address, pubKey, mnemonic string, err error)
// CreateChildAccount creates sub-account for an account identified by parent address.
// CKD#2 is used as root for master accounts (when parentAddress is "").
// Otherwise (when parentAddress != ""), child is derived directly from parent.
CreateChildAccount(parentAddress, password string) (address, pubKey string, err error)
// RecoverAccount re-creates master key using given details.
// Once master key is re-generated, it is inserted into keystore (if not already there).
RecoverAccount(password, mnemonic string) (address, pubKey string, err error)
// VerifyAccountPassword tries to decrypt a given account key file, with a provided password.
// If no error is returned, then account is considered verified.
VerifyAccountPassword(keyStoreDir, address, password string) (*keystore.Key, error)
// SelectAccount selects current account, by verifying that address has corresponding account which can be decrypted
// using provided password. Once verification is done, decrypted key is injected into Whisper (as a single identity,
// all previous identities are removed).
SelectAccount(address, password string) error
// ReSelectAccount selects previously selected account, often, after node restart.
ReSelectAccount() error
// SelectedAccount returns currently selected account
SelectedAccount() (*SelectedExtKey, error)
// Logout clears whisper identities
Logout() error
// Accounts returns handler to process account list request
Accounts() ([]common.Address, error)
// AccountsRPCHandler returns RPC wrapper for Accounts()
AccountsRPCHandler() rpc.Handler
// AddressToDecryptedAccount tries to load decrypted key for a given account.
// The running node, has a keystore directory which is loaded on start. Key file
// for a given address is expected to be in that directory prior to node start.
AddressToDecryptedAccount(address, password string) (accounts.Account, *keystore.Key, error)
}
// RawCompleteTransactionResult is a JSON returned from transaction complete function (used internally)
type RawCompleteTransactionResult struct {
Hash common.Hash
Error error
}
// RawDiscardTransactionResult is list of results from CompleteTransactions() (used internally)
type RawDiscardTransactionResult struct {
Error error
}
// QueuedTxID queued transaction identifier
type QueuedTxID string
// QueuedTx holds enough information to complete the queued transaction.
type QueuedTx struct {
ID QueuedTxID
Hash common.Hash
Context context.Context
Args SendTxArgs
Done chan struct{}
Err error
}
// SendTxArgs represents the arguments to submit a new transaction into the transaction pool.
type SendTxArgs struct {
From common.Address `json:"from"`
To *common.Address `json:"to"`
Gas *hexutil.Big `json:"gas"`
GasPrice *hexutil.Big `json:"gasPrice"`
Value *hexutil.Big `json:"value"`
Data hexutil.Bytes `json:"data"`
Nonce *hexutil.Uint64 `json:"nonce"`
}
// TxQueue is a queue of transactions.
type TxQueue interface {
// Remove removes a transaction from the queue.
Remove(id QueuedTxID)
// Reset resets the state of the queue.
Reset()
// Count returns a number of transactions in the queue.
Count() int
// Has returns true if a transaction is in the queue.
Has(id QueuedTxID) bool
}
// TxQueueManager defines expected methods for managing transaction queue
type TxQueueManager interface {
// Start starts accepting new transaction in the queue.
Start()
// Stop stops accepting new transactions in the queue.
Stop()
// TransactionQueue returns a transaction queue.
TransactionQueue() TxQueue
// QueueTransaction adds a new transaction to the queue.
QueueTransaction(tx *QueuedTx) error
// WaitForTransactions blocks until transaction is completed, discarded or timed out.
WaitForTransaction(tx *QueuedTx) error
SendTransactionRPCHandler(ctx context.Context, args ...interface{}) (interface{}, error)
// CompleteTransaction instructs backend to complete sending of a given transaction
CompleteTransaction(id QueuedTxID, password string) (common.Hash, error)
// CompleteTransactions instructs backend to complete sending of multiple transactions
CompleteTransactions(ids []QueuedTxID, password string) map[QueuedTxID]RawCompleteTransactionResult
// DiscardTransaction discards a given transaction from transaction queue
DiscardTransaction(id QueuedTxID) error
// DiscardTransactions discards given multiple transactions from transaction queue
DiscardTransactions(ids []QueuedTxID) map[QueuedTxID]RawDiscardTransactionResult
}
// JailCell represents single jail cell, which is basically a JavaScript VM.
// It's designed to be a transparent wrapper around otto.VM's methods.
type JailCell interface {
// Set a value inside VM.
Set(string, interface{}) error
// Get a value from VM.
Get(string) (otto.Value, error)
// Run an arbitrary JS code. Input maybe string or otto.Script.
Run(interface{}) (otto.Value, error)
// Call an arbitrary JS function by name and args.
Call(item string, this interface{}, args ...interface{}) (otto.Value, error)
// Stop stops background execution of cell.
Stop() error
}
// JailManager defines methods for managing jailed environments
type JailManager interface {
// Call executes given JavaScript function w/i a jail cell context identified by the chatID.
Call(chatID, this, args string) string
// CreateCell creates a new jail cell.
CreateCell(chatID string) (JailCell, error)
// Parse creates a new jail cell context, with the given chatID as identifier.
// New context executes provided JavaScript code, right after the initialization.
// DEPRECATED in favour of CreateAndInitCell.
Parse(chatID, js string) string
// CreateAndInitCell creates a new jail cell and initialize it
// with web3 and other handlers.
CreateAndInitCell(chatID string, code ...string) string
// Cell returns an existing instance of JailCell.
Cell(chatID string) (JailCell, error)
// Execute allows to run arbitrary JS code within a cell.
Execute(chatID, code string) string
// SetBaseJS allows to setup initial JavaScript to be loaded on each jail.CreateAndInitCell().
SetBaseJS(js string)
// Stop stops all background activity of jail
Stop()
}
// APIResponse generic response from API
type APIResponse struct {
Error string `json:"error"`
}
// APIDetailedResponse represents a generic response
// with possible errors.
type APIDetailedResponse struct {
Status bool `json:"status"`
Message string `json:"message,omitempty"`
FieldErrors []APIFieldError `json:"field_errors,omitempty"`
}
func (r APIDetailedResponse) Error() string {
buf := bytes.NewBufferString("")
for _, err := range r.FieldErrors {
buf.WriteString(err.Error() + "\n") // nolint: gas
}
return strings.TrimSpace(buf.String())
}
// APIFieldError represents a set of errors
// related to a parameter.
type APIFieldError struct {
Parameter string `json:"parameter,omitempty"`
Errors []APIError `json:"errors"`
}
func (e APIFieldError) Error() string {
if len(e.Errors) == 0 {
return ""
}
buf := bytes.NewBufferString(fmt.Sprintf("Parameter: %s\n", e.Parameter))
for _, err := range e.Errors {
buf.WriteString(err.Error() + "\n") // nolint: gas
}
return strings.TrimSpace(buf.String())
}
// APIError represents a single error.
type APIError struct {
Message string `json:"message"`
}
func (e APIError) Error() string {
return fmt.Sprintf("message=%s", e.Message)
}
// AccountInfo represents account's info
type AccountInfo struct {
Address string `json:"address"`
PubKey string `json:"pubkey"`
Mnemonic string `json:"mnemonic"`
Error string `json:"error"`
}
// StopRPCCallError defines a error type specific for killing a execution process.
type StopRPCCallError struct {
Err error
}
// Error returns the internal error associated with the critical error.
func (c StopRPCCallError) Error() string {
return c.Err.Error()
}
// CompleteTransactionResult is a JSON returned from transaction complete function (used in exposed method)
type CompleteTransactionResult struct {
ID string `json:"id"`
Hash string `json:"hash"`
Error string `json:"error"`
}
// CompleteTransactionsResult is list of results from CompleteTransactions() (used in exposed method)
type CompleteTransactionsResult struct {
Results map[string]CompleteTransactionResult `json:"results"`
}
// DiscardTransactionResult is a JSON returned from transaction discard function
type DiscardTransactionResult struct {
ID string `json:"id"`
Error string `json:"error"`
}
// DiscardTransactionsResult is a list of results from DiscardTransactions()
type DiscardTransactionsResult struct {
Results map[string]DiscardTransactionResult `json:"results"`
}
type account struct {
Address string
Password string
}
// TestConfig contains shared (among different test packages) parameters
type TestConfig struct {
Node struct {
SyncSeconds time.Duration
HTTPPort int
WSPort int
}
Account1 account
Account2 account
Account3 account
}
// NotifyResult is a JSON returned from notify message
type NotifyResult struct {
Status bool `json:"status"`
Error string `json:"error,omitempty"`
}
const passphraseEnvName = "ACCOUNT_PASSWORD"
// LoadTestConfig loads test configuration values from disk
func LoadTestConfig(networkID int) (*TestConfig, error) {
var testConfig TestConfig
configData := static.MustAsset("config/test-data.json")
if err := json.Unmarshal(configData, &testConfig); err != nil {
return nil, err
}
if networkID == params.StatusChainNetworkID {
accountsData := static.MustAsset("config/status-chain-accounts.json")
if err := json.Unmarshal(accountsData, &testConfig); err != nil {
return nil, err
}
} else {
accountsData := static.MustAsset("config/public-chain-accounts.json")
if err := json.Unmarshal(accountsData, &testConfig); err != nil {
return nil, err
}
pass := os.Getenv(passphraseEnvName)
testConfig.Account1.Password = pass
testConfig.Account2.Password = pass
}
return &testConfig, nil
}