@leofcoin/chain 1.3.3 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/workers/machine-worker.js +0 -13
- package/dist/chain.js +136 -125
- package/dist/contracts/factory.js +1 -1
- package/dist/contracts/{nameService.js → name-service.js} +1 -1
- package/dist/contracts/native-token.js +1 -0
- package/dist/contracts/validators.js +1 -1
- package/dist/module/chain.js +133 -122
- package/dist/module/workers/machine-worker.js +0 -6
- package/dist/standards/token.js +1 -1
- package/dist/workers/machine-worker.js +1 -1
- package/package.json +20 -2
- package/rollup.config.js +4 -4
- package/src/chain.js +103 -97
- package/src/contracts/factory.js +58 -15
- package/src/contracts/{nameService.js → name-service.js} +3 -5
- package/src/contracts/{nativeToken.js → native-token.js} +2 -2
- package/src/contracts/{powerToken.js → power-token.js} +1 -1
- package/src/contracts/proxies/{factoryProxy.js → factory-proxy.js} +1 -1
- package/src/contracts/proxies/{nameServiceProxy.js → name-service-proxy.js} +1 -1
- package/src/contracts/proxies/{nativeTokenProxy.js → native-token-proxy.js} +1 -1
- package/src/contracts/proxies/{validatorsProxy.js → validators-proxy.js} +1 -1
- package/src/contracts/proxies/{votingProxy.js → voting-proxy.js} +1 -1
- package/src/contracts/{proxyManager.js → proxy-manager.js} +1 -1
- package/src/contracts/validators.js +35 -25
- package/src/fee/config.js +1 -1
- package/src/machine.js +30 -25
- package/src/standards/{proxyManager.js → proxy-manager.js} +0 -0
- package/src/standards/{Proxy.js → proxy.js} +4 -8
- package/src/standards/roles.js +7 -5
- package/src/standards/voting.js +1 -0
- package/src/transactions/transaction.js +1 -3
- package/src/transactions/validator.js +1 -1
- package/src/typer.js +1 -1
- package/dist/865.browser.js +0 -10
- package/dist/chain.browser.js +0 -59745
- package/dist/contracts/nativeToken.js +0 -1
- package/dist/generate-account.browser.js +0 -50
- package/dist/messages.browser.js +0 -328
- package/dist/multi-wallet.browser.js +0 -15
- package/dist/node.browser.js +0 -9858
- package/dist/pako.browser.js +0 -6900
- package/dist/peernet-swarm.browser.js +0 -839
- package/dist/storage.browser.js +0 -3724
- package/dist/wrtc.browser.js +0 -28
- package/src/standards/Voting.js +0 -3
|
@@ -11723,11 +11723,6 @@ var __webpack_exports__ = {};
|
|
|
11723
11723
|
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
|
|
11724
11724
|
!function() {
|
|
11725
11725
|
|
|
11726
|
-
// EXPORTS
|
|
11727
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
11728
|
-
"T": function() { return /* binding */ unique; }
|
|
11729
|
-
});
|
|
11730
|
-
|
|
11731
11726
|
;// CONCATENATED MODULE: ./node_modules/@vandeurenglenn/base-x/src/base-x.js
|
|
11732
11727
|
// base-x encoding / decoding
|
|
11733
11728
|
// Copyright (c) 2018 base-x contributors
|
|
@@ -13727,10 +13722,6 @@ globalThis.BigNumber = BigNumber;
|
|
|
13727
13722
|
globalThis.peernet = globalThis.peernet || {};
|
|
13728
13723
|
globalThis.contracts = {};
|
|
13729
13724
|
|
|
13730
|
-
const unique = arr => arr.filter((el, pos, arr) => {
|
|
13731
|
-
return arr.indexOf(el) == pos;
|
|
13732
|
-
});
|
|
13733
|
-
|
|
13734
13725
|
const get = (contract, method, params) => {
|
|
13735
13726
|
let result;
|
|
13736
13727
|
if (params?.length > 0) {
|
|
@@ -13916,8 +13907,4 @@ const tasks = async (e) => {
|
|
|
13916
13907
|
|
|
13917
13908
|
worker.onmessage(data => tasks(data));
|
|
13918
13909
|
|
|
13919
|
-
|
|
13920
|
-
|
|
13921
13910
|
}();
|
|
13922
|
-
var __webpack_exports__unique = __webpack_exports__.T;
|
|
13923
|
-
export { __webpack_exports__unique as unique };
|
package/dist/chain.js
CHANGED
|
@@ -5,8 +5,8 @@ var _BN = require('bn.js');
|
|
|
5
5
|
require('@ethersproject/bytes');
|
|
6
6
|
var logger = require('@ethersproject/logger');
|
|
7
7
|
require('@ethersproject/bignumber');
|
|
8
|
-
var
|
|
9
|
-
var
|
|
8
|
+
var node_crypto = require('node:crypto');
|
|
9
|
+
var node_path = require('node:path');
|
|
10
10
|
var EasyWorker = require('@vandeurenglenn/easy-worker');
|
|
11
11
|
var codecFormatInterface = require('@leofcoin/codec-format-interface');
|
|
12
12
|
var MultiWallet = require('@leofcoin/multi-wallet');
|
|
@@ -78,26 +78,31 @@ class Machine {
|
|
|
78
78
|
|
|
79
79
|
async #onmessage(data) {
|
|
80
80
|
switch (data.type) {
|
|
81
|
-
case 'contractError':
|
|
81
|
+
case 'contractError': {
|
|
82
82
|
console.warn(`removing contract ${await data.hash}`);
|
|
83
83
|
await contractStore.delete(await data.hash);
|
|
84
|
-
break
|
|
84
|
+
break
|
|
85
|
+
}
|
|
85
86
|
|
|
86
|
-
case 'executionError':
|
|
87
|
+
case 'executionError': {
|
|
87
88
|
// console.warn(`error executing transaction ${data.message}`);
|
|
88
89
|
pubsub.publish(data.id, {error: data.message});
|
|
89
|
-
break
|
|
90
|
+
break
|
|
91
|
+
}
|
|
90
92
|
|
|
91
|
-
case 'debug':
|
|
92
|
-
data.messages
|
|
93
|
-
break
|
|
94
|
-
|
|
93
|
+
case 'debug': {
|
|
94
|
+
for (const message of data.messages) debug(message);
|
|
95
|
+
break
|
|
96
|
+
}
|
|
97
|
+
case 'machine-ready': {
|
|
95
98
|
this.lastBlock = data.lastBlock;
|
|
96
99
|
pubsub.publish('machine.ready', true);
|
|
97
|
-
break
|
|
98
|
-
|
|
100
|
+
break
|
|
101
|
+
}
|
|
102
|
+
case 'response': {
|
|
99
103
|
pubsub.publish(data.id, data.value);
|
|
100
|
-
break
|
|
104
|
+
break
|
|
105
|
+
}
|
|
101
106
|
}
|
|
102
107
|
|
|
103
108
|
}
|
|
@@ -108,7 +113,7 @@ class Machine {
|
|
|
108
113
|
resolve(this);
|
|
109
114
|
});
|
|
110
115
|
|
|
111
|
-
this.worker = await new EasyWorker__default["default"](
|
|
116
|
+
this.worker = await new EasyWorker__default["default"](node_path.join(__dirname, './workers/machine-worker.js'), {serialization: 'advanced', type:'module'});
|
|
112
117
|
this.worker.onmessage(this.#onmessage.bind(this));
|
|
113
118
|
|
|
114
119
|
// const blocks = await blockStore.values()
|
|
@@ -133,19 +138,19 @@ class Machine {
|
|
|
133
138
|
}
|
|
134
139
|
|
|
135
140
|
async #runContract(contractMessage) {
|
|
136
|
-
const
|
|
141
|
+
const parameters = contractMessage.decoded.constructorParameters;
|
|
137
142
|
try {
|
|
138
143
|
|
|
139
|
-
const
|
|
140
|
-
const Contract =
|
|
144
|
+
const function_ = new Function(contractMessage.decoded.contract);
|
|
145
|
+
const Contract = function_();
|
|
141
146
|
|
|
142
147
|
globalThis.msg = this.#createMessage(contractMessage.decoded.creator);
|
|
143
148
|
// globalThis.msg = {sender: contractMessage.decoded.creator}
|
|
144
|
-
this.#contracts[await contractMessage.hash] = await new Contract(...
|
|
149
|
+
this.#contracts[await contractMessage.hash] = await new Contract(...parameters);
|
|
145
150
|
debug(`loaded contract: ${await contractMessage.hash}`);
|
|
146
151
|
debug(`size: ${formatBytes(contractMessage.encoded.length)}`);
|
|
147
|
-
} catch (
|
|
148
|
-
console.log(
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.log(error);
|
|
149
154
|
console.warn(`removing contract ${await contractMessage.hash}`);
|
|
150
155
|
await contractStore.delete(await contractMessage.hash, contractMessage.encoded);
|
|
151
156
|
}
|
|
@@ -162,9 +167,9 @@ class Machine {
|
|
|
162
167
|
throw new Error('duplicate contract')
|
|
163
168
|
}
|
|
164
169
|
|
|
165
|
-
async execute(contract, method,
|
|
170
|
+
async execute(contract, method, parameters) {
|
|
166
171
|
return new Promise((resolve, reject) => {
|
|
167
|
-
const id =
|
|
172
|
+
const id = node_crypto.randomBytes(20).toString('hex');
|
|
168
173
|
const message = message => {
|
|
169
174
|
if (message?.error) reject(message.error);
|
|
170
175
|
else resolve(message);
|
|
@@ -176,24 +181,24 @@ class Machine {
|
|
|
176
181
|
input: {
|
|
177
182
|
contract,
|
|
178
183
|
method,
|
|
179
|
-
params
|
|
184
|
+
params: parameters
|
|
180
185
|
}
|
|
181
186
|
});
|
|
182
187
|
})
|
|
183
188
|
|
|
184
189
|
}
|
|
185
190
|
|
|
186
|
-
addJob(contract, method,
|
|
191
|
+
addJob(contract, method, parameters, from, nonce) {
|
|
187
192
|
if (!this.#nonces[from]) this.#nonces[from] = nonce;
|
|
188
|
-
if (nonce === this.#nonces[from] + 1) return this.#contracts[contract][method](...
|
|
193
|
+
if (nonce === this.#nonces[from] + 1) return this.#contracts[contract][method](...parameters)
|
|
189
194
|
// return setTimeout(() => {
|
|
190
195
|
// return this.addJob(contract, method, params, from, nonce)
|
|
191
196
|
// }, 50)
|
|
192
197
|
}
|
|
193
198
|
|
|
194
|
-
get(contract, method,
|
|
199
|
+
get(contract, method, parameters) {
|
|
195
200
|
return new Promise((resolve, reject) => {
|
|
196
|
-
const id =
|
|
201
|
+
const id = node_crypto.randomBytes(20).toString();
|
|
197
202
|
const message = message => {
|
|
198
203
|
resolve(message);
|
|
199
204
|
};
|
|
@@ -204,7 +209,7 @@ class Machine {
|
|
|
204
209
|
input: {
|
|
205
210
|
contract,
|
|
206
211
|
method,
|
|
207
|
-
params
|
|
212
|
+
params: parameters
|
|
208
213
|
}
|
|
209
214
|
});
|
|
210
215
|
})
|
|
@@ -413,8 +418,10 @@ class Chain {
|
|
|
413
418
|
#blocks = []
|
|
414
419
|
#machine
|
|
415
420
|
#runningEpoch = false
|
|
421
|
+
#chainSyncing = false
|
|
416
422
|
#lastBlock = {index: 0, hash: '0x0', previousHash: '0x0'}
|
|
417
|
-
|
|
423
|
+
#participants = []
|
|
424
|
+
#participating = false
|
|
418
425
|
#jail = []
|
|
419
426
|
|
|
420
427
|
constructor() {
|
|
@@ -454,14 +461,14 @@ class Chain {
|
|
|
454
461
|
console.log(validators);
|
|
455
462
|
if (!validators[peernet.selectedAccount]?.active) return
|
|
456
463
|
|
|
457
|
-
const start =
|
|
464
|
+
const start = Date.now();
|
|
458
465
|
try {
|
|
459
466
|
await this.#createBlock();
|
|
460
|
-
} catch (
|
|
461
|
-
console.error(
|
|
467
|
+
} catch (error) {
|
|
468
|
+
console.error(error);
|
|
462
469
|
}
|
|
463
470
|
|
|
464
|
-
const end =
|
|
471
|
+
const end = Date.now();
|
|
465
472
|
console.log(((end - start) / 1000) + ' s');
|
|
466
473
|
|
|
467
474
|
if (await this.hasTransactionToHandle()) return this.#runEpoch()
|
|
@@ -498,7 +505,7 @@ class Chain {
|
|
|
498
505
|
const timeout = setTimeout(() => {
|
|
499
506
|
resolve([{index: 0, hash: '0x0'}]);
|
|
500
507
|
debug('sync timed out');
|
|
501
|
-
},
|
|
508
|
+
}, 10_000);
|
|
502
509
|
|
|
503
510
|
promises = await Promise.allSettled(promises);
|
|
504
511
|
promises = promises.filter(({status}) => status === 'fulfilled');
|
|
@@ -512,11 +519,11 @@ class Chain {
|
|
|
512
519
|
|
|
513
520
|
}
|
|
514
521
|
|
|
515
|
-
|
|
516
|
-
return this.#
|
|
522
|
+
getLatestBlock() {
|
|
523
|
+
return this.#getLatestBlock()
|
|
517
524
|
}
|
|
518
525
|
|
|
519
|
-
async #
|
|
526
|
+
async #getLatestBlock() {
|
|
520
527
|
let promises = [];
|
|
521
528
|
|
|
522
529
|
let data = await new peernet.protos['peernet-request']({request: 'lastBlock'});
|
|
@@ -528,26 +535,27 @@ class Chain {
|
|
|
528
535
|
} else if (!peer.connected || peer.readyState !== 'open') ;
|
|
529
536
|
}
|
|
530
537
|
promises = await this.promiseRequests(promises);
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
return set
|
|
538
|
-
}, {index: 0, hash: '0x0'});
|
|
539
|
-
// get lastblock
|
|
540
|
-
if (promises.hash && promises.hash !== '0x0') {
|
|
541
|
-
await peernet.get(promises.hash);
|
|
538
|
+
let latest = {index: 0, hash: '0x0'};
|
|
539
|
+
|
|
540
|
+
for (const value of promises) {
|
|
541
|
+
if (value.index > latest.index) {
|
|
542
|
+
latest.index = value.index;
|
|
543
|
+
latest.hash = value.hash;
|
|
542
544
|
}
|
|
543
|
-
|
|
544
|
-
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
if (latest.hash && latest.hash !== '0x0') {
|
|
548
|
+
let latestBlock = await peernet.get(latest.hash, block);
|
|
549
|
+
latestBlock = await new BlockMessage(latestBlock);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
return latestBlock
|
|
545
553
|
}
|
|
546
554
|
|
|
547
555
|
async #init() {
|
|
548
556
|
// this.node = await new Node()
|
|
549
|
-
this
|
|
550
|
-
this
|
|
557
|
+
this.#participants = [];
|
|
558
|
+
this.#participating = false;
|
|
551
559
|
const initialized = await contractStore.has(addresses.contractFactory);
|
|
552
560
|
if (!initialized) await this.#setup();
|
|
553
561
|
|
|
@@ -558,7 +566,7 @@ class Chain {
|
|
|
558
566
|
let localBlock;
|
|
559
567
|
try {
|
|
560
568
|
localBlock = await chainStore.get('lastBlock');
|
|
561
|
-
} catch
|
|
569
|
+
} catch{
|
|
562
570
|
await chainStore.put('lastBlock', '0x0');
|
|
563
571
|
localBlock = await chainStore.get('lastBlock');
|
|
564
572
|
}
|
|
@@ -568,13 +576,11 @@ class Chain {
|
|
|
568
576
|
localBlock = await new BlockMessage(localBlock);
|
|
569
577
|
this.#lastBlock = {...localBlock.decoded, hash: await localBlock.hash};
|
|
570
578
|
} else {
|
|
571
|
-
await this.#
|
|
579
|
+
const latestBlock = await this.#getLatestBlock();
|
|
580
|
+
await this.#syncChain(latestBlock);
|
|
572
581
|
}
|
|
573
|
-
} catch (
|
|
574
|
-
console.log({e});
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
// this.#setup()
|
|
582
|
+
} catch (error) {
|
|
583
|
+
console.log({e: error});
|
|
578
584
|
}
|
|
579
585
|
|
|
580
586
|
await peernet.addRequestHandler('bw-request-message', () => {
|
|
@@ -596,9 +602,6 @@ class Chain {
|
|
|
596
602
|
// load local blocks
|
|
597
603
|
await this.resolveBlocks();
|
|
598
604
|
this.#machine = await new Machine(this.#blocks);
|
|
599
|
-
// for (const block of this.#blocks) {
|
|
600
|
-
// block.loaded = true
|
|
601
|
-
// }
|
|
602
605
|
await this.#loadBlocks(this.#blocks);
|
|
603
606
|
return this
|
|
604
607
|
}
|
|
@@ -610,29 +613,33 @@ class Chain {
|
|
|
610
613
|
this.#jail.push(validatorInfo.address);
|
|
611
614
|
}
|
|
612
615
|
|
|
613
|
-
async #
|
|
614
|
-
|
|
615
|
-
node = await peernet.prepareMessage(node);
|
|
616
|
-
let response = await peer.request(node.encoded);
|
|
617
|
-
response = await new globalThis.peernet.protos['peernet-response'](response);
|
|
618
|
-
let lastBlock = response.decoded.response;
|
|
616
|
+
async #syncChain(lastBlock) {
|
|
617
|
+
if (this.#chainSyncing) return
|
|
619
618
|
|
|
620
619
|
if (!this.lastBlock || Number(this.lastBlock.index) < Number(lastBlock.index)) {
|
|
621
|
-
|
|
620
|
+
this.#chainSyncing = true;
|
|
621
|
+
// TODO: check if valid
|
|
622
622
|
const localIndex = this.lastBlock ? this.lastBlock.index : 0;
|
|
623
623
|
const index = lastBlock.index;
|
|
624
624
|
await this.resolveBlock(lastBlock.hash);
|
|
625
|
-
let blocksSynced = localIndex > 0 ? localIndex > index ? localIndex - index : index - localIndex : index;
|
|
625
|
+
let blocksSynced = localIndex > 0 ? (localIndex > index ? localIndex - index : index - localIndex) : index;
|
|
626
626
|
debug(`synced ${blocksSynced} ${blocksSynced > 1 ? 'blocks' : 'block'}`);
|
|
627
627
|
|
|
628
628
|
this.#blocks.length;
|
|
629
|
-
const start =
|
|
629
|
+
const start = this.#blocks.length - blocksSynced;
|
|
630
630
|
await this.#loadBlocks(this.blocks.slice(start));
|
|
631
|
-
this.#
|
|
632
|
-
|
|
633
|
-
await blockStore.put(await message.hash, message.encoded);
|
|
634
|
-
await chainStore.put('lastBlock', this.lastBlock.hash);
|
|
631
|
+
await this.#updateState(this.#blocks[this.#blocks.length - 1]);
|
|
632
|
+
this.#chainSyncing = false;
|
|
635
633
|
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
async #peerConnected(peer) {
|
|
637
|
+
let node = await new peernet.protos['peernet-request']({request: 'lastBlock'});
|
|
638
|
+
node = await peernet.prepareMessage(node);
|
|
639
|
+
let response = await peer.request(node.encoded);
|
|
640
|
+
response = await new globalThis.peernet.protos['peernet-response'](response);
|
|
641
|
+
let lastBlock = response.decoded.response;
|
|
642
|
+
this.#syncChain(lastBlock);
|
|
636
643
|
}
|
|
637
644
|
|
|
638
645
|
#epochTimeout
|
|
@@ -642,9 +649,9 @@ class Chain {
|
|
|
642
649
|
transaction = await new TransactionMessage(transaction);
|
|
643
650
|
const has = await transactionPoolStore.has(await transaction.hash);
|
|
644
651
|
if (!has) await transactionPoolStore.put(await transaction.hash, transaction.encoded);
|
|
645
|
-
if (this
|
|
646
|
-
} catch
|
|
647
|
-
throw Error('invalid transaction')
|
|
652
|
+
if (this.#participating && !this.#runningEpoch) this.#runEpoch();
|
|
653
|
+
} catch {
|
|
654
|
+
throw new Error('invalid transaction')
|
|
648
655
|
}
|
|
649
656
|
}
|
|
650
657
|
|
|
@@ -657,7 +664,7 @@ async resolveBlock(hash) {
|
|
|
657
664
|
let block = await peernet.get(hash, 'block');
|
|
658
665
|
block = await new BlockMessage(block);
|
|
659
666
|
if (!await peernet.has(hash, 'block')) await peernet.put(hash, block.encoded, 'block');
|
|
660
|
-
const size = block.encoded.length
|
|
667
|
+
const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
|
|
661
668
|
block = {...block.decoded, hash};
|
|
662
669
|
if (this.#blocks[block.index] && this.#blocks[block.index].hash !== block.hash) throw `invalid block ${hash} @${block.index}`
|
|
663
670
|
this.#blocks[block.index] = block;
|
|
@@ -676,7 +683,7 @@ async resolveBlock(hash) {
|
|
|
676
683
|
await this.resolveBlock(hash);
|
|
677
684
|
this.#lastBlock = this.#blocks[this.#blocks.length - 1];
|
|
678
685
|
|
|
679
|
-
} catch
|
|
686
|
+
} catch {
|
|
680
687
|
await chainStore.put('lastBlock', new TextEncoder().encode('0x0'));
|
|
681
688
|
return this.resolveBlocks()
|
|
682
689
|
// console.log(e);
|
|
@@ -690,8 +697,8 @@ async resolveBlock(hash) {
|
|
|
690
697
|
try {
|
|
691
698
|
await this.#machine.execute(transaction.to, transaction.method, transaction.params);
|
|
692
699
|
|
|
693
|
-
} catch (
|
|
694
|
-
console.log(
|
|
700
|
+
} catch (error) {
|
|
701
|
+
console.log(error);
|
|
695
702
|
}
|
|
696
703
|
}
|
|
697
704
|
this.#blocks[block.index].loaded = true;
|
|
@@ -723,10 +730,10 @@ async resolveBlock(hash) {
|
|
|
723
730
|
let result = await this.#machine.execute(to, method, params, from, nonce);
|
|
724
731
|
// if (!result) result = this.#machine.state
|
|
725
732
|
pubsub.publish(`transaction.completed.${hash}`, {status: 'fulfilled', hash});
|
|
726
|
-
return result
|
|
727
|
-
} catch (
|
|
728
|
-
pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error:
|
|
729
|
-
throw
|
|
733
|
+
return result || 'no state change'
|
|
734
|
+
} catch (error) {
|
|
735
|
+
pubsub.publish(`transaction.completed.${hash}`, {status: 'fail', hash, error: error});
|
|
736
|
+
throw error
|
|
730
737
|
}
|
|
731
738
|
}
|
|
732
739
|
|
|
@@ -763,11 +770,15 @@ async resolveBlock(hash) {
|
|
|
763
770
|
// await transactionStore.put(transaction.hash, transaction.encoded)
|
|
764
771
|
const index = contracts.indexOf(transaction.to);
|
|
765
772
|
if (index === -1) contracts.push(transaction.to);
|
|
773
|
+
// Todo: go trough all accounts
|
|
766
774
|
promises.push(this.#executeTransaction(transaction));
|
|
775
|
+
|
|
767
776
|
}
|
|
768
777
|
try {
|
|
769
778
|
promises = await Promise.allSettled(promises);
|
|
770
779
|
for (let transaction of blockMessage.decoded.transactions) {
|
|
780
|
+
pubsub.publish('transaction-processed', transaction);
|
|
781
|
+
if (transaction.to === peernet.selectedAccount) pubsub.publish('account-transaction-processed', transaction);
|
|
771
782
|
await accountsStore.put(transaction.from, String(transaction.nonce));
|
|
772
783
|
}
|
|
773
784
|
|
|
@@ -780,8 +791,9 @@ async resolveBlock(hash) {
|
|
|
780
791
|
|
|
781
792
|
|
|
782
793
|
pubsub.publish('block-processed', blockMessage.decoded);
|
|
783
|
-
|
|
784
|
-
|
|
794
|
+
|
|
795
|
+
} catch (error) {
|
|
796
|
+
console.log({e: error});
|
|
785
797
|
}
|
|
786
798
|
|
|
787
799
|
}
|
|
@@ -801,7 +813,7 @@ async resolveBlock(hash) {
|
|
|
801
813
|
// introduce peer-reputation
|
|
802
814
|
// peerReputation(peerId)
|
|
803
815
|
// {bandwith: {up, down}, uptime}
|
|
804
|
-
this
|
|
816
|
+
this.#participating = true;
|
|
805
817
|
if (!await this.staticCall(addresses.validators, 'has', [address])) await this.createTransactionFrom(address, addresses.validators, 'addValidator', [address]);
|
|
806
818
|
if (await this.hasTransactionToHandle() && !this.#runningEpoch) await this.#runEpoch();
|
|
807
819
|
|
|
@@ -863,7 +875,7 @@ async resolveBlock(hash) {
|
|
|
863
875
|
block.transactions.push(transaction);
|
|
864
876
|
block.fees += Number(calculateFee(transaction));
|
|
865
877
|
await accountsStore.put(transaction.from, new TextEncoder().encode(String(transaction.nonce)));
|
|
866
|
-
} catch
|
|
878
|
+
} catch {
|
|
867
879
|
transaction = await new TransactionMessage(transaction);
|
|
868
880
|
await transactionPoolStore.delete(await transaction.hash);
|
|
869
881
|
}
|
|
@@ -896,9 +908,7 @@ async resolveBlock(hash) {
|
|
|
896
908
|
address: validator,
|
|
897
909
|
bw: bw.up + bw.down
|
|
898
910
|
});
|
|
899
|
-
} catch
|
|
900
|
-
|
|
901
|
-
}
|
|
911
|
+
} catch{}
|
|
902
912
|
|
|
903
913
|
} else if (peernet.selectedAccount === validator) {
|
|
904
914
|
block.validators.push({
|
|
@@ -926,17 +936,17 @@ async resolveBlock(hash) {
|
|
|
926
936
|
else block.index += 1;
|
|
927
937
|
|
|
928
938
|
block.previousHash = this.lastBlock?.hash || '0x0';
|
|
929
|
-
block.timestamp =
|
|
939
|
+
block.timestamp = Date.now();
|
|
930
940
|
|
|
931
941
|
const parts = String(block.fees).split('.');
|
|
932
942
|
let decimals = 0;
|
|
933
943
|
if (parts[1]) {
|
|
934
944
|
const potentional = parts[1].split('e');
|
|
935
|
-
if (potentional[0]
|
|
936
|
-
parts[1] = potentional[0];
|
|
937
|
-
decimals = Number(potentional[1]?.replace(/\-|\+/g, '')) + Number(potentional[0].length);
|
|
938
|
-
} else {
|
|
945
|
+
if (potentional[0] === parts[1]) {
|
|
939
946
|
decimals = parts[1].length;
|
|
947
|
+
} else {
|
|
948
|
+
parts[1] = potentional[0];
|
|
949
|
+
decimals = Number(potentional[1]?.replace(/[+-]/g, '')) + Number(potentional[0].length);
|
|
940
950
|
}
|
|
941
951
|
|
|
942
952
|
}
|
|
@@ -956,9 +966,10 @@ async resolveBlock(hash) {
|
|
|
956
966
|
debug(`created block: ${hash}`);
|
|
957
967
|
|
|
958
968
|
peernet.publish('add-block', blockMessage.encoded);
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
969
|
+
pubsub.publish('add-block', blockMessage.decoded);
|
|
970
|
+
} catch (error) {
|
|
971
|
+
console.log(error);
|
|
972
|
+
throw new Error(`invalid block ${block}`)
|
|
962
973
|
}
|
|
963
974
|
// data = await this.#machine.execute(to, method, params)
|
|
964
975
|
// transactionStore.put(message.hash, message.encoded)
|
|
@@ -1027,8 +1038,8 @@ async resolveBlock(hash) {
|
|
|
1027
1038
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1028
1039
|
* @param {Number} nonce - total transaction count [optional]
|
|
1029
1040
|
*/
|
|
1030
|
-
async createTransaction(to, method,
|
|
1031
|
-
return this.createTransactionFrom(peernet.selectedAccount, to, method,
|
|
1041
|
+
async createTransaction(to, method, parameters, nonce, signature) {
|
|
1042
|
+
return this.createTransactionFrom(peernet.selectedAccount, to, method, parameters, nonce)
|
|
1032
1043
|
}
|
|
1033
1044
|
|
|
1034
1045
|
|
|
@@ -1088,8 +1099,8 @@ async #signTransaction (transaction, wallet) {
|
|
|
1088
1099
|
} else {
|
|
1089
1100
|
let nonce = await accountsStore.get(transaction.from);
|
|
1090
1101
|
nonce = new TextDecoder().decode(nonce);
|
|
1091
|
-
if (transaction.nonce < nonce) throw Error(`a transaction with a higher nonce already exists`)
|
|
1092
|
-
if (transaction.nonce === nonce) throw Error(`a transaction with the same nonce already exists`)
|
|
1102
|
+
if (transaction.nonce < nonce) throw new Error(`a transaction with a higher nonce already exists`)
|
|
1103
|
+
if (transaction.nonce === nonce) throw new Error(`a transaction with the same nonce already exists`)
|
|
1093
1104
|
}
|
|
1094
1105
|
return transaction
|
|
1095
1106
|
}
|
|
@@ -1104,10 +1115,10 @@ async #signTransaction (transaction, wallet) {
|
|
|
1104
1115
|
* @param {Array} params - array of paramters to apply to the contract method
|
|
1105
1116
|
* @param {Number} nonce - total transaction count [optional]
|
|
1106
1117
|
*/
|
|
1107
|
-
async createTransactionFrom(from, to, method,
|
|
1118
|
+
async createTransactionFrom(from, to, method, parameters, nonce) {
|
|
1108
1119
|
try {
|
|
1109
1120
|
|
|
1110
|
-
const rawTransaction = await this.createRawTransaction({from, to, nonce, method, params});
|
|
1121
|
+
const rawTransaction = await this.createRawTransaction({from, to, nonce, method, params: parameters});
|
|
1111
1122
|
const transaction = await this.signTransaction(rawTransaction, from);
|
|
1112
1123
|
const message = await new TransactionMessage(transaction);
|
|
1113
1124
|
|
|
@@ -1123,7 +1134,7 @@ async #signTransaction (transaction, wallet) {
|
|
|
1123
1134
|
|
|
1124
1135
|
setTimeout(async () => {
|
|
1125
1136
|
pubsub.unsubscribe(`transaction.completed.${await message.hash}`, completed);
|
|
1126
|
-
},
|
|
1137
|
+
}, 10_000);
|
|
1127
1138
|
};
|
|
1128
1139
|
pubsub.subscribe(`transaction.completed.${await message.hash}`, completed);
|
|
1129
1140
|
}
|
|
@@ -1135,9 +1146,9 @@ async #signTransaction (transaction, wallet) {
|
|
|
1135
1146
|
peernet.publish('add-transaction', message.encoded);
|
|
1136
1147
|
this.#addTransaction(message.encoded);
|
|
1137
1148
|
return {hash: await message.hash, data, fee: await calculateFee(message.decoded), wait}
|
|
1138
|
-
} catch (
|
|
1139
|
-
console.log(
|
|
1140
|
-
throw
|
|
1149
|
+
} catch (error) {
|
|
1150
|
+
console.log(error);
|
|
1151
|
+
throw error
|
|
1141
1152
|
}
|
|
1142
1153
|
|
|
1143
1154
|
}
|
|
@@ -1155,15 +1166,15 @@ async #signTransaction (transaction, wallet) {
|
|
|
1155
1166
|
*
|
|
1156
1167
|
* @param {String} contract - a contract string (see plugins/deployContract)
|
|
1157
1168
|
*/
|
|
1158
|
-
async deployContract(contract,
|
|
1169
|
+
async deployContract(contract, parameters = []) {
|
|
1159
1170
|
globalThis.msg = {sender: peernet.selectedAccount, call: this.call};
|
|
1160
1171
|
|
|
1161
|
-
const hash = await this.createContractAddress(creator, contract,
|
|
1172
|
+
const hash = await this.createContractAddress(creator, contract, parameters);
|
|
1162
1173
|
console.log(hash);
|
|
1163
1174
|
try {
|
|
1164
1175
|
const tx = await this.createTransactionFrom(peernet.selectedAccount, addresses.contractFactory, 'deployContract', [hash, creator, contract, constructorParameters]);
|
|
1165
|
-
} catch (
|
|
1166
|
-
throw
|
|
1176
|
+
} catch (error) {
|
|
1177
|
+
throw error
|
|
1167
1178
|
}
|
|
1168
1179
|
return this.#machine.addContract(message)
|
|
1169
1180
|
}
|
|
@@ -1178,33 +1189,33 @@ console.log(hash);
|
|
|
1178
1189
|
}
|
|
1179
1190
|
}
|
|
1180
1191
|
|
|
1181
|
-
internalCall(sender, contract, method,
|
|
1192
|
+
internalCall(sender, contract, method, parameters) {
|
|
1182
1193
|
globalThis.msg = this.#createMessage(sender);
|
|
1183
1194
|
|
|
1184
|
-
return this.#machine.execute(contract, method,
|
|
1195
|
+
return this.#machine.execute(contract, method, parameters)
|
|
1185
1196
|
}
|
|
1186
1197
|
|
|
1187
|
-
call(contract, method,
|
|
1198
|
+
call(contract, method, parameters) {
|
|
1188
1199
|
globalThis.msg = this.#createMessage();
|
|
1189
1200
|
|
|
1190
|
-
return this.#machine.execute(contract, method,
|
|
1201
|
+
return this.#machine.execute(contract, method, parameters)
|
|
1191
1202
|
}
|
|
1192
1203
|
|
|
1193
|
-
staticCall(contract, method,
|
|
1204
|
+
staticCall(contract, method, parameters) {
|
|
1194
1205
|
globalThis.msg = this.#createMessage();
|
|
1195
|
-
return this.#machine.get(contract, method,
|
|
1206
|
+
return this.#machine.get(contract, method, parameters)
|
|
1196
1207
|
}
|
|
1197
1208
|
|
|
1198
|
-
delegate(contract, method,
|
|
1209
|
+
delegate(contract, method, parameters) {
|
|
1199
1210
|
globalThis.msg = this.#createMessage();
|
|
1200
1211
|
|
|
1201
|
-
return this.#machine.execute(contract, method,
|
|
1212
|
+
return this.#machine.execute(contract, method, parameters)
|
|
1202
1213
|
}
|
|
1203
1214
|
|
|
1204
|
-
staticDelegate(contract, method,
|
|
1215
|
+
staticDelegate(contract, method, parameters) {
|
|
1205
1216
|
globalThis.msg = this.#createMessage();
|
|
1206
1217
|
|
|
1207
|
-
return this.#machine.get(contract, method,
|
|
1218
|
+
return this.#machine.get(contract, method, parameters)
|
|
1208
1219
|
}
|
|
1209
1220
|
|
|
1210
1221
|
mint(to, amount) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class Factory{#name="ArtOnlineContractFactory";#totalContracts=0;#contracts=[];constructor(state){state&&(this.#contracts=state.contracts,this.#totalContracts=state.totalContracts)}get state(){return{totalContracts:this.#totalContracts,contracts:this.#contracts}}get name(){return this.#name}get contracts(){return[...this.#contracts]}get totalContracts(){return this.#totalContracts}
|
|
1
|
+
class Factory{#name="ArtOnlineContractFactory";#totalContracts=0;#contracts=[];#implementations={};constructor(state){state&&(this.#contracts=state.contracts,this.#totalContracts=state.totalContracts,this.#implementations=state.implementations)}get state(){return{totalContracts:this.#totalContracts,contracts:this.#contracts,implementations:this.#implementations}}get name(){return this.#name}get contracts(){return[...this.#contracts]}get totalContracts(){return this.#totalContracts}get implementations(){return{...this.#implementations}}async registerContract(address){let isAllowed=!1;if(isAllowed=await msg.staticCall(address,"hasRole",[msg.sender,"IMPLEMENTATION_MANAGER"]),!isAllowed)throw new Error("only the implementation manager can update");if(this.#implementations[address])throw new Error("already registered");this.#totalContracts+=1,this.#implementations[address]=[],this.#implementations[address].push(address),this.#contracts.push(address)}async updateImplementation(address,newAddress){let isAllowed=!1;if(isAllowed=await msg.staticCall(address,"hasRole",[msg.sender,"IMPLEMENTATION_MANAGER"]),!isAllowed)throw new Error("only the implementation manager can update");if(!this.#implementations[address])throw new Error(`register ${address} before updating to ${newAddress}`);this.#implementations[address].push(newAddress)}getImplementations(address){return this.#implementations[address]}getImplementation(address,index){return index=index||this.#implementations[address].length-1,this.#implementations[address][index]}}export{Factory as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class NameService{#name="ArtOnlineNameService";#owner;#price=0;#registry={};#currency;get name(){return this.#name}get registry(){return{...this.#registry}}get state(){}constructor(factoryAddress,currency,validatorAddress,price,state){state?(this.#owner=state.owner,this.#registry=state.registry,this.#currency=state.currency,this.#price=state.price):(this.#owner=msg.sender,this.#price=price,this.#registry.ArtOnlineContractFactory={owner:msg.sender,address:factoryAddress},this.#registry.ArtOnlineToken={owner:msg.sender,address:currency},this.#registry.ArtOnlineValidators={owner:msg.sender,address:validatorAddress},this.#currency=currency)}changeOwner(owner){if(msg.sender!==this.#owner)throw new Error("no owner");this.#owner=owner}changePrice(price){if(msg.sender!==this.#owner)throw new Error("no owner");this.#price=price}changeCurrency(currency){if(msg.sender!==this.#owner)throw new Error("no owner");this.#currency=currency}async purchaseName(name,address){if(await msg.call(this.#currency,"balanceOf",[msg.sender])<this.#price)throw new Error("price exceeds balance");try{await msg.call(this.#currency,"transfer",[msg.sender,this.#owner,this.#price])}catch(
|
|
1
|
+
class NameService{#name="ArtOnlineNameService";#owner;#price=0;#registry={};#currency;get name(){return this.#name}get registry(){return{...this.#registry}}get state(){}constructor(factoryAddress,currency,validatorAddress,price,state){state?(this.#owner=state.owner,this.#registry=state.registry,this.#currency=state.currency,this.#price=state.price):(this.#owner=msg.sender,this.#price=price,this.#registry.ArtOnlineContractFactory={owner:msg.sender,address:factoryAddress},this.#registry.ArtOnlineToken={owner:msg.sender,address:currency},this.#registry.ArtOnlineValidators={owner:msg.sender,address:validatorAddress},this.#currency=currency)}changeOwner(owner){if(msg.sender!==this.#owner)throw new Error("no owner");this.#owner=owner}changePrice(price){if(msg.sender!==this.#owner)throw new Error("no owner");this.#price=price}changeCurrency(currency){if(msg.sender!==this.#owner)throw new Error("no owner");this.#currency=currency}async purchaseName(name,address){if(await msg.call(this.#currency,"balanceOf",[msg.sender])<this.#price)throw new Error("price exceeds balance");try{await msg.call(this.#currency,"transfer",[msg.sender,this.#owner,this.#price])}catch(error){throw error}this.#registry[name]={owner:msg.sender,address}}lookup(name){return this.#registry[name]}transferOwnership(name,to){if(msg.sender!==this.#registry.owner)throw new Error("not a owner");this.#registry[name].owner=to}changeAddress(name,address){if(msg.sender!==this.#registry.owner)throw new Error("not a owner");this.#registry[name].address=address}}export{NameService as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class Roles{#roles={IMPLEMENTATION_MANAGER:[],OWNER:[],MINT:[],BURN:[]};constructor(roles){if(roles){if(!(roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER"),this.#grantRole(msg.sender,"IMPLEMENTATION_MANAGER")}get state(){return{roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Token extends Roles{#name;#symbol;#holders=0;#balances={};#approvals={};#decimals=18;#totalSupply=BigNumber.from(0);constructor(name,symbol,decimals=18,state){if(!name)throw new Error("name undefined");if(!symbol)throw new Error("symbol undefined");super(state?.roles),this.#name=name,this.#symbol=symbol,this.#decimals=decimals}get state(){return{...super.state,holders:this.holders,balances:this.balances,approvals:{...this.#approvals},totalSupply:this.totalSupply}}get totalSupply(){return this.#totalSupply}get name(){return this.#name}get symbol(){return this.#symbol}get holders(){return this.#holders}get balances(){return{...this.#balances}}mint(to,amount){if(!this.hasRole(msg.sender,"MINT"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.add(amount),this.#increaseBalance(to,amount)}burn(to,amount){if(!this.hasRole(msg.sender,"BURN"))throw new Error("not allowed");this.#totalSupply=this.#totalSupply.sub(amount),this.#decreaseBalance(to,amount)}#beforeTransfer(from,to,amount){if(!this.#balances[from]||this.#balances[from]<amount)throw new Error("amount exceeds balance")}#updateHolders(address,previousBalance){"0x00"===this.#balances[address].toHexString()?this.#holders-=1:"0x00"!==this.#balances[address].toHexString()&&"0x00"===previousBalance.toHexString()&&(this.#holders+=1)}#increaseBalance(address,amount){this.#balances[address]||(this.#balances[address]=BigNumber.from(0));const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].add(amount),this.#updateHolders(address,previousBalance)}#decreaseBalance(address,amount){const previousBalance=this.#balances[address];this.#balances[address]=this.#balances[address].sub(amount),this.#updateHolders(address,previousBalance)}balanceOf(address){return this.#balances[address]}setApproval(operator,amount){const owner=globalThis.msg.sender;this.#approvals[owner]||(this.#approvals[owner]={}),this.#approvals[owner][operator]=amount}approved(owner,operator,amount){return this.#approvals[owner][operator]===amount}transfer(from,to,amount){amount=BigNumber.from(amount),this.#beforeTransfer(from,to,amount),this.#decreaseBalance(from,amount),this.#increaseBalance(to,amount)}}class ArtOnline extends Token{constructor(state){super("ArtOnline","ART",18,state)}}export{ArtOnline as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class Validators{#name="ArtOnlineValidators";#totalValidators=0;#validators={};#
|
|
1
|
+
class Roles{#roles={IMPLEMENTATION_MANAGER:[],OWNER:[],MINT:[],BURN:[]};constructor(roles){if(roles){if(!(roles instanceof Object))throw new TypeError("expected roles to be an object");this.#roles={...roles,...this.#roles}}else this.#grantRole(msg.sender,"OWNER"),this.#grantRole(msg.sender,"IMPLEMENTATION_MANAGER")}get state(){return{roles:this.roles}}get roles(){return{...this.#roles}}hasRole(address,role){return!!this.#roles[role]&&this.#roles[role].includes(address)}#grantRole(address,role){if(this.hasRole(address,role))throw new Error(`${role} role already granted for ${address}`);this.#roles[role].push(address)}#revokeRole(address,role){if(!this.hasRole(address,role))throw new Error(`${role} role already revoked for ${address}`);if("OWNER"===role&&1===this.#roles[role].length)throw new Error("atleast one owner is needed!");this.#roles[role].splice(this.#roles[role].indexOf(address))}grantRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#grantRole(address,role)}revokeRole(address,role){if(!this.hasRole(address,"OWNER"))throw new Error("Not allowed");this.#revokeRole(address,role)}}class Validators extends Roles{#name="ArtOnlineValidators";#totalValidators=0;#activeValidators=0;#validators={};#currency;#minimumBalance;get state(){return{...super.state,minimumBalance:this.#minimumBalance,currency:this.#currency,totalValidators:this.#totalValidators,activeValidators:this.#activeValidators,validators:this.#validators}}constructor(tokenAddress,state){super(state?.roles),state?(this.#minimumBalance=state.minimumBalance,this.#currency=state.currency,this.#totalValidators=state.totalValidators,this.#activeValidators=state.activeValidators,this.#validators=state.validators):(this.#minimumBalance=5e4,this.#currency=tokenAddress,this.#totalValidators+=1,this.#activeValidators+=1,this.#validators[msg.sender]={firstSeen:Date.now(),lastSeen:Date.now(),active:!0})}get name(){return this.#name}get currency(){return this.#currency}get validators(){return{...this.#validators}}get totalValidators(){return this.#totalValidators}get minimumBalance(){return this.#minimumBalance}changeCurrency(currency){if(!this.hasRole(msg.sender,"OWNER"))throw new Error("not an owner");this.#currency=currency}has(validator){return Boolean(void 0!==this.#validators[validator])}#isAllowed(address){if(msg.sender!==address&&!this.hasRole(msg.sender,"OWNER"))throw new Error("sender is not the validator or owner");return!0}async addValidator(validator){if(this.#isAllowed(validator),this.has(validator))throw new Error("already a validator");const balance=await msg.staticCall(this.currency,"balanceOf",[validator]);if(balance<this.minimumBalance)throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);this.#totalValidators+=1,this.#activeValidators+=1,this.#validators[validator]={firstSeen:Date.now(),lastSeen:Date.now(),active:!0}}removeValidator(validator){if(this.#isAllowed(validator),!this.has(validator))throw new Error("validator not found");this.#totalValidators-=1,this.#validators[validator].active&&(this.#activeValidators-=1),delete this.#validators[validator]}async updateValidator(validator,active){if(this.#isAllowed(validator),!this.has(validator))throw new Error("validator not found");const balance=await msg.staticCall(this.currency,"balanceOf",[validator]);if(balance<this.minimumBalance&&active)throw new Error(`balance to low! got: ${balance} need: ${this.#minimumBalance}`);if(this.#validators[validator].active===active)throw new Error("already "+(active?"activated":"deactivated"));active?this.#activeValidators+=1:this.#activeValidators-=1,this.#validators[validator].active=active}}export{Validators as default};
|