@ocap/tx-protocols 1.13.65 → 1.13.69
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/lib/execute.js +1 -1
- package/lib/protocols/account/declare.js +2 -1
- package/lib/protocols/account/delegate.js +2 -1
- package/lib/protocols/account/migrate.js +2 -1
- package/lib/protocols/account/revoke-delegate.js +2 -1
- package/lib/protocols/asset/acquire-v3.js +8 -8
- package/lib/protocols/asset/create.js +16 -7
- package/lib/protocols/asset/mint.js +1 -1
- package/lib/protocols/asset/pipes/verify-mint-limit.js +1 -1
- package/lib/protocols/asset/update.js +2 -1
- package/lib/protocols/factory/create.js +12 -5
- package/lib/protocols/governance/claim-stake.js +6 -5
- package/lib/protocols/governance/revoke-stake.js +2 -2
- package/lib/protocols/governance/stake.js +11 -10
- package/lib/protocols/rollup/claim-reward.js +8 -4
- package/lib/protocols/rollup/create-block.js +9 -8
- package/lib/protocols/rollup/create.js +18 -5
- package/lib/protocols/rollup/join.js +4 -3
- package/lib/protocols/rollup/leave.js +4 -3
- package/lib/protocols/rollup/pipes/ensure-tx-fee.js +38 -0
- package/lib/protocols/rollup/update.js +2 -1
- package/lib/protocols/token/create.js +21 -10
- package/lib/protocols/token/deposit-v2.js +4 -3
- package/lib/protocols/token/withdraw-v2.js +3 -2
- package/lib/util.js +9 -9
- package/package.json +13 -12
package/lib/execute.js
CHANGED
|
@@ -29,7 +29,7 @@ module.exports = ({ filter, runAsLambda }) => {
|
|
|
29
29
|
// Since bloom-filters may give false positive, we need to check for statedb if replay detected
|
|
30
30
|
const exist = await context.statedb.tx.get(context.txHash, context);
|
|
31
31
|
if (exist) {
|
|
32
|
-
return next(new Error('
|
|
32
|
+
return next(new Error('DUPLICATE_TX', 'Can not execute duplicate transaction'));
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
2
3
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
3
|
-
const { account
|
|
4
|
+
const { account } = require('@ocap/state');
|
|
4
5
|
const { toBase58 } = require('@ocap/util');
|
|
5
6
|
|
|
6
7
|
const runner = new Runner();
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* eslint-disable max-len */
|
|
2
2
|
const get = require('lodash/get');
|
|
3
|
+
const Joi = require('@ocap/validator');
|
|
3
4
|
const Error = require('@ocap/util/lib/error');
|
|
4
5
|
const getListField = require('@ocap/util/lib/get-list-field');
|
|
5
|
-
const { delegation, account
|
|
6
|
+
const { delegation, account } = require('@ocap/state');
|
|
6
7
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
7
8
|
const { toDelegateAddress } = require('@arcblock/did-util');
|
|
8
9
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
2
3
|
const getRelatedAddresses = require('@ocap/util/lib/get-related-addr');
|
|
3
4
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
4
5
|
const { fromPublicKey, toTypeInfo } = require('@arcblock/did');
|
|
5
|
-
const { account
|
|
6
|
+
const { account } = require('@ocap/state');
|
|
6
7
|
|
|
7
8
|
// eslint-disable-next-line global-require
|
|
8
9
|
const debug = require('debug')(`${require('../../../package.json').name}:migrate`);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const get = require('lodash/get');
|
|
2
2
|
const cloneDeep = require('lodash/cloneDeep');
|
|
3
|
+
const Joi = require('@ocap/validator');
|
|
3
4
|
const getListField = require('@ocap/util/lib/get-list-field');
|
|
4
5
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
5
|
-
const { delegation, account
|
|
6
|
+
const { delegation, account } = require('@ocap/state');
|
|
6
7
|
const { toDelegateAddress } = require('@arcblock/did-util');
|
|
7
8
|
|
|
8
9
|
// eslint-disable-next-line global-require
|
|
@@ -82,7 +82,7 @@ runner.use(
|
|
|
82
82
|
);
|
|
83
83
|
|
|
84
84
|
// 5. verify sender & signer & owner
|
|
85
|
-
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: '
|
|
85
|
+
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'OK', table: 'account' })); // prettier-ignore
|
|
86
86
|
runner.use(pipes.ExtractState({ from: 'senders', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
|
|
87
87
|
runner.use(pipes.ExtractState({ from: 'itx.owner', to: 'ownerState', status: 'OK', table: 'account' }));
|
|
88
88
|
runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
|
|
@@ -152,7 +152,7 @@ runner.use(
|
|
|
152
152
|
);
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
-
const isAlsoSigner = !!signerUpdates[
|
|
155
|
+
const isAlsoSigner = !!signerUpdates[tx.from];
|
|
156
156
|
const owner = ownerState ? ownerState.address : itx.owner;
|
|
157
157
|
|
|
158
158
|
// Factory updates
|
|
@@ -166,12 +166,12 @@ runner.use(
|
|
|
166
166
|
|
|
167
167
|
const [newSenderState, newReceiverState, assetState, newSignerStates, newFactoryState, newAssetStates] =
|
|
168
168
|
await Promise.all([
|
|
169
|
-
//
|
|
170
|
-
statedb.account.
|
|
171
|
-
senderState
|
|
172
|
-
account.
|
|
169
|
+
// update sender
|
|
170
|
+
statedb.account.updateOrCreate(
|
|
171
|
+
senderState,
|
|
172
|
+
account.updateOrCreate(
|
|
173
173
|
senderState,
|
|
174
|
-
Object.assign({ nonce: tx.nonce, pk: tx.pk }, signerUpdates[
|
|
174
|
+
Object.assign({ address: tx.from, nonce: tx.nonce, pk: tx.pk }, signerUpdates[tx.from] || {}),
|
|
175
175
|
context
|
|
176
176
|
),
|
|
177
177
|
context
|
|
@@ -192,7 +192,7 @@ runner.use(
|
|
|
192
192
|
// Update signer state
|
|
193
193
|
Promise.all(
|
|
194
194
|
signerStates
|
|
195
|
-
.filter((x) => x.address !==
|
|
195
|
+
.filter((x) => x.address !== tx.from)
|
|
196
196
|
.map((x) =>
|
|
197
197
|
statedb.account.update(x.address, account.update(x, signerUpdates[x.address], context), context)
|
|
198
198
|
)
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
/* eslint-disable indent */
|
|
2
2
|
const Error = require('@ocap/util/lib/error');
|
|
3
|
+
const isEmpty = require('lodash/isEmpty');
|
|
3
4
|
const cloneDeep = require('lodash/cloneDeep');
|
|
5
|
+
const Joi = require('@ocap/validator');
|
|
4
6
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
5
|
-
const { account, asset
|
|
7
|
+
const { account, asset } = require('@ocap/state');
|
|
6
8
|
const { toAssetAddress } = require('@arcblock/did-util');
|
|
7
9
|
|
|
8
10
|
// eslint-disable-next-line global-require
|
|
9
11
|
const debug = require('debug')(`${require('../../../package.json').name}:create-asset`);
|
|
10
12
|
|
|
11
13
|
const { decodeAnySafe } = require('../../util');
|
|
14
|
+
const ensureTxFee = require('../rollup/pipes/ensure-tx-fee');
|
|
12
15
|
|
|
13
16
|
const runner = new Runner();
|
|
14
17
|
|
|
@@ -74,7 +77,7 @@ runner.use(
|
|
|
74
77
|
// For security consideration, user can not create fake assets from a factory
|
|
75
78
|
// https://github.com/ArcBlock/asset-chain/issues/97
|
|
76
79
|
{
|
|
77
|
-
error: '
|
|
80
|
+
error: 'CREATE_FROM_FACTORY',
|
|
78
81
|
message: 'You can only get asset from factory from acquire or mint',
|
|
79
82
|
fn: ({ itx, factoryState }) => !(itx.parent && factoryState),
|
|
80
83
|
persist: true,
|
|
@@ -85,28 +88,34 @@ runner.use(
|
|
|
85
88
|
// Ensure parent exist
|
|
86
89
|
runner.use(pipes.ExtractState({ from: 'itx.parent', to: 'parentAsset', status: 'INVALID_ASSET', table: 'asset' }));
|
|
87
90
|
|
|
91
|
+
runner.use(ensureTxFee);
|
|
92
|
+
|
|
88
93
|
// Update asset state
|
|
89
94
|
runner.use(
|
|
90
95
|
async (context, next) => {
|
|
91
|
-
const { tx, itx, assetData, statedb, senderState } = context;
|
|
96
|
+
const { tx, itx, assetData, statedb, senderState, senderUpdates, vaultState, vaultUpdates } = context;
|
|
92
97
|
|
|
93
|
-
const [newSenderState, assetState] = await Promise.all([
|
|
94
|
-
// Update owner state
|
|
98
|
+
const [newSenderState, assetState, newVaultState] = await Promise.all([
|
|
95
99
|
statedb.account.update(
|
|
96
100
|
senderState.address,
|
|
97
|
-
account.update(senderState, { nonce: tx.nonce, pk: tx.pk }, context),
|
|
101
|
+
account.update(senderState, { nonce: tx.nonce, pk: tx.pk, ...senderUpdates }, context),
|
|
98
102
|
context
|
|
99
103
|
),
|
|
100
|
-
|
|
104
|
+
|
|
101
105
|
statedb.asset.create(
|
|
102
106
|
itx.address,
|
|
103
107
|
asset.create({ ...itx, data: assetData, owner: senderState.address }, context),
|
|
104
108
|
context
|
|
105
109
|
),
|
|
110
|
+
|
|
111
|
+
isEmpty(vaultUpdates)
|
|
112
|
+
? vaultState
|
|
113
|
+
: statedb.account.update(vaultState.address, account.update(vaultState, vaultUpdates, context), context),
|
|
106
114
|
]);
|
|
107
115
|
|
|
108
116
|
context.senderState = newSenderState;
|
|
109
117
|
context.assetState = assetState;
|
|
118
|
+
context.vaultState = newVaultState;
|
|
110
119
|
|
|
111
120
|
debug('createAsset', assetState);
|
|
112
121
|
|
|
@@ -31,7 +31,7 @@ runner.use(pipes.ExtractState({ from: 'itx.owner', to: 'ownerState', status: 'OK
|
|
|
31
31
|
runner.use(
|
|
32
32
|
pipes.VerifyInfo([
|
|
33
33
|
{
|
|
34
|
-
error: '
|
|
34
|
+
error: 'OWNER_ONLY_OPERATION',
|
|
35
35
|
message: 'Only factory owner is allowed to mint',
|
|
36
36
|
fn: ({ factoryState, senderState }) => factoryState.owner === senderState.address,
|
|
37
37
|
persist: true,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
2
3
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
3
|
-
const { account, asset
|
|
4
|
+
const { account, asset } = require('@ocap/state');
|
|
4
5
|
|
|
5
6
|
// eslint-disable-next-line global-require
|
|
6
7
|
const debug = require('debug')(`${require('../../../package.json').name}:update-asset`);
|
|
@@ -14,6 +14,7 @@ const { toFactoryAddress } = require('@arcblock/did-util');
|
|
|
14
14
|
const debug = require('debug')(`${require('../../../package.json').name}:create-factory`);
|
|
15
15
|
|
|
16
16
|
const { decodeAnySafe } = require('../../util');
|
|
17
|
+
const ensureTxFee = require('../rollup/pipes/ensure-tx-fee');
|
|
17
18
|
|
|
18
19
|
const runner = new Runner();
|
|
19
20
|
|
|
@@ -71,7 +72,7 @@ runner.use(pipes.ExtractState({ from: 'itx.address', to: 'factoryState', status:
|
|
|
71
72
|
runner.use(
|
|
72
73
|
pipes.VerifyInfo([
|
|
73
74
|
{
|
|
74
|
-
error: '
|
|
75
|
+
error: 'DUPLICATE_FACTORY',
|
|
75
76
|
message: 'This asset factory already exist on chain',
|
|
76
77
|
fn: (context) => isEmpty(context.factoryState),
|
|
77
78
|
},
|
|
@@ -101,18 +102,19 @@ runner.use((context, next) => {
|
|
|
101
102
|
return next(new Error('INVALID_FACTORY_INPUT', 'Not all input.assets exist on chain'));
|
|
102
103
|
});
|
|
103
104
|
|
|
105
|
+
runner.use(ensureTxFee);
|
|
106
|
+
|
|
104
107
|
// Create factory state
|
|
105
|
-
// TODO: we need to support charging when creating new nft-factory
|
|
106
108
|
runner.use(
|
|
107
109
|
async (context, next) => {
|
|
108
|
-
const { tx, itx, statedb, senderState, factoryProps } = context;
|
|
110
|
+
const { tx, itx, statedb, senderState, senderUpdates, vaultState, vaultUpdates, factoryProps } = context;
|
|
109
111
|
const tokens = { [context.config.token.address]: '0' };
|
|
110
112
|
|
|
111
|
-
const [newSenderState, factoryState] = await Promise.all([
|
|
113
|
+
const [newSenderState, factoryState, newVaultState] = await Promise.all([
|
|
112
114
|
// Update owner state
|
|
113
115
|
statedb.account.update(
|
|
114
116
|
senderState.address,
|
|
115
|
-
account.update(senderState, { nonce: tx.nonce, pk: tx.pk }, context),
|
|
117
|
+
account.update(senderState, { nonce: tx.nonce, pk: tx.pk, ...senderUpdates }, context),
|
|
116
118
|
context
|
|
117
119
|
),
|
|
118
120
|
|
|
@@ -122,10 +124,15 @@ runner.use(
|
|
|
122
124
|
factory.create({ ...factoryProps, tokens, owner: senderState.address }, context),
|
|
123
125
|
context
|
|
124
126
|
),
|
|
127
|
+
|
|
128
|
+
isEmpty(vaultUpdates)
|
|
129
|
+
? vaultState
|
|
130
|
+
: statedb.account.update(vaultState.address, account.update(vaultState, vaultUpdates, context), context),
|
|
125
131
|
]);
|
|
126
132
|
|
|
127
133
|
context.senderState = newSenderState;
|
|
128
134
|
context.factoryState = factoryState;
|
|
135
|
+
context.vaultState = newVaultState;
|
|
129
136
|
|
|
130
137
|
debug('createFactory', factoryState);
|
|
131
138
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
2
3
|
const { BN } = require('@ocap/util');
|
|
3
4
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
4
|
-
const { account, asset, stake, evidence
|
|
5
|
+
const { account, asset, stake, evidence } = require('@ocap/state');
|
|
5
6
|
|
|
6
7
|
// eslint-disable-next-line global-require
|
|
7
8
|
const debug = require('debug')(`${require('../../../package.json').name}:acquire-asset-v2`);
|
|
@@ -16,7 +17,7 @@ runner.use(pipes.VerifyMultiSig(0));
|
|
|
16
17
|
const schema = Joi.object({
|
|
17
18
|
address: Joi.DID().role('ROLE_STAKE').required(),
|
|
18
19
|
evidence: Joi.object({
|
|
19
|
-
hash: Joi.string().regex(Joi.
|
|
20
|
+
hash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
20
21
|
}).required(),
|
|
21
22
|
data: Joi.any().optional(),
|
|
22
23
|
}).options({ stripUnknown: true, noDefaults: false });
|
|
@@ -30,7 +31,7 @@ runner.use(pipes.ExtractState({ from: 'itx.address', to: 'stakeState', status: '
|
|
|
30
31
|
runner.use(
|
|
31
32
|
pipes.VerifyInfo([
|
|
32
33
|
{
|
|
33
|
-
error: '
|
|
34
|
+
error: 'SENDER_NOT_MATCH',
|
|
34
35
|
message: 'You are not allowed to claim stake from this address',
|
|
35
36
|
fn: ({ tx, stakeState }) => tx.from === stakeState.sender,
|
|
36
37
|
},
|
|
@@ -42,7 +43,7 @@ runner.use(pipes.ExtractState({ from: 'itx.evidence.hash', to: 'evidenceState',
|
|
|
42
43
|
runner.use(
|
|
43
44
|
pipes.VerifyInfo([
|
|
44
45
|
{
|
|
45
|
-
error: '
|
|
46
|
+
error: 'ALREADY_CLAIMED',
|
|
46
47
|
message: 'Revoke evidence already seen on this chain',
|
|
47
48
|
fn: ({ evidenceState }) => !evidenceState,
|
|
48
49
|
},
|
|
@@ -69,7 +70,7 @@ runner.use(
|
|
|
69
70
|
fn: ({ txState, itx }) => txState.tx.itxJson.address === itx.address,
|
|
70
71
|
},
|
|
71
72
|
{
|
|
72
|
-
error: '
|
|
73
|
+
error: 'WITHIN_WAITING_PERIOD',
|
|
73
74
|
message: 'You can not claim stake before waiting period ends',
|
|
74
75
|
fn: ({ txState, stakeState, txTime }) => {
|
|
75
76
|
const end = +new Date(txState.time) + (stakeState.revokeWaitingPeriod || 0) * 1000;
|
|
@@ -49,12 +49,12 @@ runner.use(
|
|
|
49
49
|
runner.use(
|
|
50
50
|
pipes.VerifyInfo([
|
|
51
51
|
{
|
|
52
|
-
error: '
|
|
52
|
+
error: 'SENDER_NOT_MATCH',
|
|
53
53
|
message: 'You are not allowed to revoke stake from this address',
|
|
54
54
|
fn: ({ tx, stakeState }) => tx.from === stakeState.sender,
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
|
-
error: '
|
|
57
|
+
error: 'STAKE_NOT_REVOCABLE',
|
|
58
58
|
message: 'This stake address is not revocable',
|
|
59
59
|
fn: ({ stakeState }) => stakeState.revocable,
|
|
60
60
|
},
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const pick = require('lodash/pick');
|
|
2
2
|
const { promisify } = require('util');
|
|
3
3
|
const isEmpty = require('empty-value');
|
|
4
|
+
const Joi = require('@ocap/validator');
|
|
4
5
|
const Error = require('@ocap/util/lib/error');
|
|
5
6
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
6
7
|
const { toStakeAddress } = require('@arcblock/did-util');
|
|
7
|
-
const { account, asset, stake
|
|
8
|
+
const { account, asset, stake } = require('@ocap/state');
|
|
8
9
|
|
|
9
10
|
// eslint-disable-next-line global-require
|
|
10
11
|
const debug = require('debug')(`${require('../../../package.json').name}:acquire-asset-v2`);
|
|
@@ -63,9 +64,9 @@ runner.use(pipes.VerifyMultiSigV2({ signersKey: 'senders' }));
|
|
|
63
64
|
runner.use(pipes.ExtractState({ from: 'itx.address', to: 'stakeState', status: 'OK', table: 'stake' }));
|
|
64
65
|
|
|
65
66
|
// 5. verify sender & signer & receiver
|
|
66
|
-
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: '
|
|
67
|
-
runner.use(pipes.ExtractState({ from: 'senders', to: 'signerStates', status: 'INVALID_SIGNER_STATE' }));
|
|
68
|
-
runner.use(pipes.ExtractState({ from: 'itx.receiver', to: 'receiverState', status: 'INVALID_RECEIVER_STATE' }));
|
|
67
|
+
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'OK', table: 'account' }));
|
|
68
|
+
runner.use(pipes.ExtractState({ from: 'senders', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
|
|
69
|
+
runner.use(pipes.ExtractState({ from: 'itx.receiver', to: 'receiverState', status: 'INVALID_RECEIVER_STATE' })); // can by any type
|
|
69
70
|
runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
|
|
70
71
|
|
|
71
72
|
// 6. verify token state and balance
|
|
@@ -114,15 +115,15 @@ runner.use(
|
|
|
114
115
|
stakeUpdates.assets.push(...assetsList);
|
|
115
116
|
});
|
|
116
117
|
|
|
117
|
-
const isAlsoSigner = !!signerUpdates[
|
|
118
|
+
const isAlsoSigner = !!signerUpdates[tx.from];
|
|
118
119
|
|
|
119
120
|
const [newSenderState, newSignerStates, newStakeState, newAssetStates] = await Promise.all([
|
|
120
121
|
// Update sender state
|
|
121
|
-
statedb.account.
|
|
122
|
-
senderState
|
|
123
|
-
account.
|
|
122
|
+
statedb.account.updateOrCreate(
|
|
123
|
+
senderState,
|
|
124
|
+
account.updateOrCreate(
|
|
124
125
|
senderState,
|
|
125
|
-
Object.assign({ nonce: tx.nonce, pk: tx.pk }, signerUpdates[
|
|
126
|
+
Object.assign({ address: tx.from, nonce: tx.nonce, pk: tx.pk }, signerUpdates[tx.from] || {}),
|
|
126
127
|
context
|
|
127
128
|
),
|
|
128
129
|
context
|
|
@@ -131,7 +132,7 @@ runner.use(
|
|
|
131
132
|
// Update signer state
|
|
132
133
|
Promise.all(
|
|
133
134
|
signerStates
|
|
134
|
-
.filter((x) => x.address !==
|
|
135
|
+
.filter((x) => x.address !== tx.from)
|
|
135
136
|
.map((x) => statedb.account.update(x.address, account.update(x, signerUpdates[x.address], context), context))
|
|
136
137
|
),
|
|
137
138
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
const uniqBy = require('lodash/uniqBy');
|
|
2
2
|
const groupBy = require('lodash/groupBy');
|
|
3
3
|
const cloneDeep = require('lodash/cloneDeep');
|
|
4
|
+
const Joi = require('@ocap/validator');
|
|
4
5
|
const Error = require('@ocap/util/lib/error');
|
|
5
6
|
const { BN } = require('@ocap/util');
|
|
6
7
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
7
|
-
const { account, stake, evidence, rollupBlock
|
|
8
|
+
const { account, stake, evidence, rollupBlock } = require('@ocap/state');
|
|
8
9
|
|
|
9
10
|
// eslint-disable-next-line global-require
|
|
10
11
|
const debug = require('debug')(`${require('../../../package.json').name}:claim-block-reward`);
|
|
@@ -19,9 +20,9 @@ const runner = new Runner();
|
|
|
19
20
|
const schema = Joi.object({
|
|
20
21
|
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
21
22
|
blockHeight: Joi.number().integer().greater(0).required(),
|
|
22
|
-
blockHash: Joi.string().regex(Joi.
|
|
23
|
+
blockHash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
23
24
|
evidence: Joi.object({
|
|
24
|
-
hash: Joi.string().regex(Joi.
|
|
25
|
+
hash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
25
26
|
}).required(),
|
|
26
27
|
publisher: Joi.DID().wallet('ethereum').required(),
|
|
27
28
|
data: Joi.any().optional(),
|
|
@@ -263,7 +264,10 @@ runner.use(
|
|
|
263
264
|
),
|
|
264
265
|
]);
|
|
265
266
|
|
|
266
|
-
|
|
267
|
+
// to avoid this to be incorrectly indexed
|
|
268
|
+
delete context.stakeState;
|
|
269
|
+
|
|
270
|
+
context.stakeStates = newStakeStates.filter((x) => updates.stake[x.address]);
|
|
267
271
|
context.accountStates = newAccountStates;
|
|
268
272
|
context.blockState = newBlockState;
|
|
269
273
|
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
const pick = require('lodash/pick');
|
|
3
3
|
const Error = require('@ocap/util/lib/error');
|
|
4
4
|
const MerkleTree = require('@ocap/merkle-tree');
|
|
5
|
+
const Joi = require('@ocap/validator');
|
|
5
6
|
const { formatMessage } = require('@ocap/message');
|
|
6
7
|
const { toStakeAddress } = require('@arcblock/did-util');
|
|
7
8
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
8
|
-
const { account, stake, rollup, rollupBlock, tx: Tx
|
|
9
|
+
const { account, stake, rollup, rollupBlock, tx: Tx } = require('@ocap/state');
|
|
9
10
|
|
|
10
11
|
// eslint-disable-next-line global-require
|
|
11
12
|
const debug = require('debug')(`${require('../../../package.json').name}:create-rollup-block`);
|
|
@@ -19,18 +20,18 @@ const runner = new Runner();
|
|
|
19
20
|
|
|
20
21
|
// 1. verify itx
|
|
21
22
|
const schema = Joi.object({
|
|
22
|
-
hash: Joi.string().regex(Joi.
|
|
23
|
+
hash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
23
24
|
height: Joi.number().integer().greater(0).required(),
|
|
24
|
-
merkleRoot: Joi.string().regex(Joi.
|
|
25
|
+
merkleRoot: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
25
26
|
previousHash: Joi.string().when('height', {
|
|
26
27
|
is: 1,
|
|
27
28
|
then: Joi.string().optional().allow(''),
|
|
28
|
-
otherwise: Joi.string().regex(Joi.
|
|
29
|
+
otherwise: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
29
30
|
}),
|
|
30
|
-
txsHash: Joi.string().regex(Joi.
|
|
31
|
-
txsList: Joi.array().items(Joi.string().regex(Joi.
|
|
31
|
+
txsHash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
32
|
+
txsList: Joi.array().items(Joi.string().regex(Joi.patterns.txHash).required()).min(1).unique().required(),
|
|
32
33
|
proposer: Joi.DID().wallet('ethereum').required(),
|
|
33
|
-
signaturesList: Joi.
|
|
34
|
+
signaturesList: Joi.schemas.multiSig.min(1).required(),
|
|
34
35
|
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
35
36
|
minReward: Joi.BN().min(0).required(),
|
|
36
37
|
data: Joi.any().optional(),
|
|
@@ -311,7 +312,7 @@ runner.use(
|
|
|
311
312
|
]);
|
|
312
313
|
|
|
313
314
|
context.senderState = newSenderState;
|
|
314
|
-
context.stakeStates = newStakeStates;
|
|
315
|
+
context.stakeStates = newStakeStates.filter((x) => context.stakeUpdates[x.address]);
|
|
315
316
|
context.newSenderStates = newSenderStates;
|
|
316
317
|
context.rollupState = newRollupState;
|
|
317
318
|
context.rollupBlockState = rollupBlockState;
|
|
@@ -12,6 +12,7 @@ const { toRollupAddress } = require('@arcblock/did-util');
|
|
|
12
12
|
const debug = require('debug')(`${require('../../../package.json').name}:create-rollup`);
|
|
13
13
|
|
|
14
14
|
const { decodeAnySafe } = require('../../util');
|
|
15
|
+
const ensureTxFee = require('./pipes/ensure-tx-fee');
|
|
15
16
|
|
|
16
17
|
const runner = new Runner();
|
|
17
18
|
|
|
@@ -87,7 +88,7 @@ runner.use(async (context, next) => {
|
|
|
87
88
|
const { statedb, itx } = context;
|
|
88
89
|
const exist = await statedb.rollup.existByToken(itx.tokenAddress, context);
|
|
89
90
|
if (exist) {
|
|
90
|
-
return next(new Error('
|
|
91
|
+
return next(new Error('DUPLICATE_ROLLUP', 'Only 1 rollup can be created for the token'));
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
return next();
|
|
@@ -98,20 +99,27 @@ runner.use(pipes.ExtractState({ from: 'itx.address', to: 'rollupState', status:
|
|
|
98
99
|
runner.use(
|
|
99
100
|
pipes.VerifyInfo([
|
|
100
101
|
{
|
|
101
|
-
error: '
|
|
102
|
+
error: 'DUPLICATE_ROLLUP',
|
|
102
103
|
message: 'This rollup already exist on chain',
|
|
103
104
|
fn: (context) => isEmpty(context.rollupState),
|
|
104
105
|
},
|
|
105
106
|
])
|
|
106
107
|
);
|
|
107
108
|
|
|
109
|
+
runner.use(ensureTxFee);
|
|
110
|
+
|
|
108
111
|
// 5. create rollup state
|
|
109
112
|
runner.use(
|
|
110
113
|
async (context, next) => {
|
|
111
|
-
const { tx, formattedItx, rollupData, statedb, senderState } = context;
|
|
114
|
+
const { tx, formattedItx, rollupData, statedb, senderState, senderUpdates, vaultState, vaultUpdates } = context;
|
|
115
|
+
|
|
116
|
+
const [newSenderState, rollupState, newVaultState] = await Promise.all([
|
|
117
|
+
statedb.account.update(
|
|
118
|
+
senderState.address,
|
|
119
|
+
account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
|
|
120
|
+
context
|
|
121
|
+
),
|
|
112
122
|
|
|
113
|
-
const [newSenderState, rollupState] = await Promise.all([
|
|
114
|
-
statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
|
|
115
123
|
statedb.rollup.create(
|
|
116
124
|
formattedItx.address,
|
|
117
125
|
rollup.create(
|
|
@@ -128,6 +136,10 @@ runner.use(
|
|
|
128
136
|
),
|
|
129
137
|
context
|
|
130
138
|
),
|
|
139
|
+
|
|
140
|
+
isEmpty(vaultUpdates)
|
|
141
|
+
? vaultState
|
|
142
|
+
: statedb.account.update(vaultState.address, account.update(vaultState, vaultUpdates, context), context),
|
|
131
143
|
]);
|
|
132
144
|
|
|
133
145
|
// FIXME: create-rollup 的时候不能校验 stake,还是在这里创建 stake?如果在这里创建 stake,是否需要多签?
|
|
@@ -135,6 +147,7 @@ runner.use(
|
|
|
135
147
|
|
|
136
148
|
context.senderState = newSenderState;
|
|
137
149
|
context.rollupState = rollupState;
|
|
150
|
+
context.vaultState = newVaultState;
|
|
138
151
|
|
|
139
152
|
debug('create-rollup', rollupState);
|
|
140
153
|
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
const MerkleTree = require('@ocap/merkle-tree');
|
|
3
3
|
const joinUrl = require('url-join');
|
|
4
4
|
const Error = require('@ocap/util/lib/error');
|
|
5
|
+
const Joi = require('@ocap/validator');
|
|
5
6
|
const { BN, toHex } = require('@ocap/util');
|
|
6
7
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
7
|
-
const { account, rollup, stake, evidence
|
|
8
|
+
const { account, rollup, stake, evidence } = require('@ocap/state');
|
|
8
9
|
const { toStakeAddress } = require('@arcblock/did-util');
|
|
9
10
|
const { isEthereumDid } = require('@arcblock/did');
|
|
10
11
|
|
|
@@ -24,9 +25,9 @@ const schema = Joi.object({
|
|
|
24
25
|
.uri({ scheme: [/https?/] })
|
|
25
26
|
.required(),
|
|
26
27
|
evidence: Joi.object({
|
|
27
|
-
hash: Joi.string().regex(Joi.
|
|
28
|
+
hash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
28
29
|
}).required(),
|
|
29
|
-
signaturesList: Joi.
|
|
30
|
+
signaturesList: Joi.schemas.multiSig.min(1).required(),
|
|
30
31
|
data: Joi.any().optional(),
|
|
31
32
|
}).options({ stripUnknown: true, noDefaults: false });
|
|
32
33
|
runner.use(({ itx }, next) => {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* eslint-disable indent */
|
|
2
2
|
const MerkleTree = require('@ocap/merkle-tree');
|
|
3
3
|
const Error = require('@ocap/util/lib/error');
|
|
4
|
+
const Joi = require('@ocap/validator');
|
|
4
5
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
5
|
-
const { account, rollup, stake, evidence
|
|
6
|
+
const { account, rollup, stake, evidence } = require('@ocap/state');
|
|
6
7
|
const { toStakeAddress } = require('@arcblock/did-util');
|
|
7
8
|
|
|
8
9
|
// eslint-disable-next-line global-require
|
|
@@ -18,9 +19,9 @@ const runner = new Runner();
|
|
|
18
19
|
const schema = Joi.object({
|
|
19
20
|
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
20
21
|
evidence: Joi.object({
|
|
21
|
-
hash: Joi.string().regex(Joi.
|
|
22
|
+
hash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
22
23
|
}).required(),
|
|
23
|
-
signaturesList: Joi.
|
|
24
|
+
signaturesList: Joi.schemas.multiSig.min(1).required(),
|
|
24
25
|
data: Joi.any().optional(),
|
|
25
26
|
}).options({ stripUnknown: true, noDefaults: false });
|
|
26
27
|
runner.use(({ itx }, next) => {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const { fromTokenToUnit, BN } = require('@ocap/util');
|
|
3
|
+
|
|
4
|
+
const { applyTokenUpdates } = require('../../../util');
|
|
5
|
+
|
|
6
|
+
// FIXME: There maybe bug for tx that decrease senderState token balance
|
|
7
|
+
module.exports = async (context, next) => {
|
|
8
|
+
const { config, statedb, txType, senderState } = context;
|
|
9
|
+
const txFee = config.transaction.txFee[txType];
|
|
10
|
+
const vaultState = await statedb.account.get(config.vaults.txFee, context);
|
|
11
|
+
|
|
12
|
+
if (!txFee) {
|
|
13
|
+
context.senderUpdates = {};
|
|
14
|
+
context.vaultUpdates = {};
|
|
15
|
+
context.vaultState = vaultState;
|
|
16
|
+
context.updatedAccounts = [];
|
|
17
|
+
return next();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const expected = fromTokenToUnit(txFee, config.token.decimal);
|
|
21
|
+
const actual = new BN(senderState.tokens[config.token.address] || 0);
|
|
22
|
+
if (actual.lt(expected)) {
|
|
23
|
+
return next(new Error('INSUFFICIENT_FUND', `Insufficient fund to pay for tx fee, expected ${txFee}`));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const tokenChange = { address: config.token.address, value: expected.toString(10) };
|
|
27
|
+
|
|
28
|
+
context.senderUpdates = applyTokenUpdates([tokenChange], senderState, 'sub');
|
|
29
|
+
context.vaultUpdates = applyTokenUpdates([tokenChange], vaultState, 'add');
|
|
30
|
+
context.vaultState = vaultState;
|
|
31
|
+
|
|
32
|
+
context.updatedAccounts = [
|
|
33
|
+
{ address: senderState.address, token: config.token.address, delta: `-${tokenChange.value}`, action: 'fee' },
|
|
34
|
+
{ address: vaultState.address, token: config.token.address, delta: tokenChange.value, action: 'fee' },
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
return next();
|
|
38
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
2
3
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
3
|
-
const { account, rollup
|
|
4
|
+
const { account, rollup } = require('@ocap/state');
|
|
4
5
|
|
|
5
6
|
// eslint-disable-next-line global-require
|
|
6
7
|
const debug = require('debug')(`${require('../../../package.json').name}:update-rollup`);
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
const isEmpty = require('empty-value');
|
|
2
2
|
const cloneDeep = require('lodash/cloneDeep');
|
|
3
|
+
const Joi = require('@ocap/validator');
|
|
3
4
|
const Error = require('@ocap/util/lib/error');
|
|
4
5
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
5
|
-
const { account, token
|
|
6
|
+
const { account, token } = require('@ocap/state');
|
|
6
7
|
const { toTokenAddress } = require('@arcblock/did-util');
|
|
7
8
|
const { fromTokenToUnit } = require('@ocap/util');
|
|
8
9
|
|
|
9
10
|
// eslint-disable-next-line global-require
|
|
10
11
|
const debug = require('debug')(`${require('../../../package.json').name}:create-token`);
|
|
11
12
|
const { decodeAnySafe } = require('../../util');
|
|
13
|
+
const ensureTxFee = require('../rollup/pipes/ensure-tx-fee');
|
|
12
14
|
|
|
13
15
|
const MAX_TOTAL_SUPPLY = fromTokenToUnit(10000 * 100000000, 18); // 32
|
|
14
16
|
|
|
@@ -26,7 +28,7 @@ const schema = Joi.object({
|
|
|
26
28
|
icon: Joi.string().optional().valid(''),
|
|
27
29
|
totalSupply: Joi.BN().greater(0).max(MAX_TOTAL_SUPPLY).required(),
|
|
28
30
|
initialSupply: Joi.BN().greater(0).max(Joi.ref('totalSupply')).required(),
|
|
29
|
-
foreignToken: Joi.
|
|
31
|
+
foreignToken: Joi.schemas.foreignToken.optional().default(null),
|
|
30
32
|
data: Joi.any().optional(),
|
|
31
33
|
}).options({ stripUnknown: true, noDefaults: false });
|
|
32
34
|
|
|
@@ -64,7 +66,7 @@ runner.use(pipes.ExtractState({ from: 'itx.address', to: 'tokenState', table: 't
|
|
|
64
66
|
runner.use(
|
|
65
67
|
pipes.VerifyInfo([
|
|
66
68
|
{
|
|
67
|
-
error: '
|
|
69
|
+
error: 'DUPLICATE_TOKEN',
|
|
68
70
|
message: 'Token address already exists on chain',
|
|
69
71
|
fn: (context) => isEmpty(context.tokenState),
|
|
70
72
|
},
|
|
@@ -75,37 +77,46 @@ runner.use(
|
|
|
75
77
|
runner.use(async (context, next) => {
|
|
76
78
|
const { symbol } = context.config.token;
|
|
77
79
|
if (symbol.toLowerCase() === context.itx.symbol.toLowerCase()) {
|
|
78
|
-
return next(new Error('
|
|
80
|
+
return next(new Error('DUPLICATE_SYMBOL', `Token symbol can not be ${symbol}`));
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
const exist = await context.statedb.token.existBySymbol(context.itx.symbol, context);
|
|
82
84
|
if (exist) {
|
|
83
|
-
return next(new Error('
|
|
85
|
+
return next(new Error('DUPLICATE_SYMBOL', 'Token symbol already exists'));
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
return next();
|
|
87
89
|
});
|
|
88
90
|
|
|
91
|
+
runner.use(ensureTxFee);
|
|
92
|
+
|
|
89
93
|
// Update sender state, token state
|
|
90
94
|
runner.use(
|
|
91
95
|
async (context, next) => {
|
|
92
|
-
const { tx, itx, statedb, senderState } = context;
|
|
96
|
+
const { tx, itx, statedb, senderState, senderUpdates, vaultState, vaultUpdates } = context;
|
|
93
97
|
const data = decodeAnySafe(itx.data);
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
// We are definitely creating a different token, so it is safe to set tokens to initial supply
|
|
100
|
+
senderUpdates.tokens = senderUpdates.tokens || {};
|
|
101
|
+
senderUpdates.tokens[itx.address] = itx.initialSupply;
|
|
97
102
|
|
|
98
|
-
const [newSenderState, tokenState] = await Promise.all([
|
|
103
|
+
const [newSenderState, tokenState, newVaultState] = await Promise.all([
|
|
99
104
|
statedb.account.update(
|
|
100
105
|
senderState.address,
|
|
101
|
-
account.update(senderState, {
|
|
106
|
+
account.update(senderState, { nonce: tx.nonce, pk: tx.pk, ...senderUpdates }, context),
|
|
102
107
|
context
|
|
103
108
|
),
|
|
109
|
+
|
|
104
110
|
statedb.token.create(itx.address, token.create({ ...itx, data, issuer: senderState.address }, context), context),
|
|
111
|
+
|
|
112
|
+
isEmpty(vaultUpdates)
|
|
113
|
+
? vaultState
|
|
114
|
+
: statedb.account.update(vaultState.address, account.update(vaultState, vaultUpdates, context), context),
|
|
105
115
|
]);
|
|
106
116
|
|
|
107
117
|
context.senderState = newSenderState;
|
|
108
118
|
context.tokenState = tokenState;
|
|
119
|
+
context.vaultState = newVaultState;
|
|
109
120
|
|
|
110
121
|
debug('create token v2', tokenState);
|
|
111
122
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable indent */
|
|
2
2
|
const Error = require('@ocap/util/lib/error');
|
|
3
|
+
const Joi = require('@ocap/validator');
|
|
3
4
|
const getListField = require('@ocap/util/lib/get-list-field');
|
|
4
5
|
const { BN, fromUnitToToken } = require('@ocap/util');
|
|
5
6
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
6
|
-
const { account, stake, evidence
|
|
7
|
+
const { account, stake, evidence } = require('@ocap/state');
|
|
7
8
|
const { toStakeAddress } = require('@arcblock/did-util');
|
|
8
9
|
|
|
9
10
|
// eslint-disable-next-line global-require
|
|
@@ -14,11 +15,11 @@ const VerifyPaused = require('../rollup/pipes/verify-paused');
|
|
|
14
15
|
const { applyTokenUpdates, getTxFee, getBNSum, getRewardLocker } = require('../../util');
|
|
15
16
|
|
|
16
17
|
const schema = Joi.object({
|
|
17
|
-
token: Joi.
|
|
18
|
+
token: Joi.schemas.tokenInput.required(),
|
|
18
19
|
to: Joi.DID().wallet('ethereum').required(),
|
|
19
20
|
proposer: Joi.DID().wallet('ethereum').required(),
|
|
20
21
|
evidence: Joi.object({
|
|
21
|
-
hash: Joi.string().regex(Joi.
|
|
22
|
+
hash: Joi.string().regex(Joi.patterns.txHash).required(),
|
|
22
23
|
}).required(),
|
|
23
24
|
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
24
25
|
actualFee: Joi.BN().min(0).required(),
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable indent */
|
|
2
2
|
const Error = require('@ocap/util/lib/error');
|
|
3
|
+
const Joi = require('@ocap/validator');
|
|
3
4
|
const getListField = require('@ocap/util/lib/get-list-field');
|
|
4
5
|
const { BN, fromUnitToToken } = require('@ocap/util');
|
|
5
6
|
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
6
|
-
const { account, stake
|
|
7
|
+
const { account, stake } = require('@ocap/state');
|
|
7
8
|
const { toStakeAddress } = require('@arcblock/did-util');
|
|
8
9
|
|
|
9
10
|
// eslint-disable-next-line global-require
|
|
@@ -15,7 +16,7 @@ const { applyTokenUpdates, getTxFee, getBNSum, getRewardLocker } = require('../.
|
|
|
15
16
|
const verifyMultiSigV2 = pipes.VerifyMultiSigV2({ signersKey: 'signers' });
|
|
16
17
|
|
|
17
18
|
const schema = Joi.object({
|
|
18
|
-
token: Joi.
|
|
19
|
+
token: Joi.schemas.tokenInput.required(),
|
|
19
20
|
to: Joi.DID().wallet('ethereum').required(),
|
|
20
21
|
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
21
22
|
proposer: Joi.DID().wallet('ethereum').optional().allow('').default(''),
|
package/lib/util.js
CHANGED
|
@@ -54,7 +54,7 @@ const decodeAnySafe = (encoded) => {
|
|
|
54
54
|
|
|
55
55
|
const applyTokenUpdates = (tokens, state, operator) => {
|
|
56
56
|
if (['add', 'sub'].includes(operator) === false) {
|
|
57
|
-
throw new Error('
|
|
57
|
+
throw new Error('UNEXPECTED_OPERATOR', `Invalid operator when applyTokenUpdates: ${operator}`);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
if (!state) {
|
|
@@ -69,7 +69,7 @@ const applyTokenUpdates = (tokens, state, operator) => {
|
|
|
69
69
|
const balance = new BN(oldTokens[address] || 0);
|
|
70
70
|
const newBalance = balance[operator](requirement);
|
|
71
71
|
if (newBalance.lt(ZERO)) {
|
|
72
|
-
throw new Error('
|
|
72
|
+
throw new Error('NEGATIVE_TOKEN_BALANCE', `Negative token balance when applyTokenUpdates for ${address}`);
|
|
73
73
|
}
|
|
74
74
|
newTokens[address] = newBalance.toString(10);
|
|
75
75
|
}
|
|
@@ -102,16 +102,16 @@ const getTxFee = ({ amount, feeRate, maxFee, minFee, stringify = true }) => {
|
|
|
102
102
|
const minFeeAmount = new BN(minFee);
|
|
103
103
|
|
|
104
104
|
if (feeRate < 0) {
|
|
105
|
-
throw new Error('
|
|
105
|
+
throw new Error('NEGATIVE_FEE_RATE', 'Unexpected negative feeRate when getTxFee, abort!');
|
|
106
106
|
}
|
|
107
107
|
if (userAmount.lt(ZERO)) {
|
|
108
|
-
throw new Error('
|
|
108
|
+
throw new Error('NEGATIVE_AMOUNT', 'Unexpected negative amount when getTxFee, abort!');
|
|
109
109
|
}
|
|
110
110
|
if (maxFeeAmount.lt(ZERO)) {
|
|
111
|
-
throw new Error('
|
|
111
|
+
throw new Error('NEGATIVE_MAX_FEE', 'Unexpected negative maxFee when getTxFee, abort!');
|
|
112
112
|
}
|
|
113
113
|
if (minFeeAmount.lt(ZERO)) {
|
|
114
|
-
throw new Error('
|
|
114
|
+
throw new Error('NEGATIVE_MIN_FEE', 'Unexpected negative minFee when getTxFee, abort!');
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
// total fee
|
|
@@ -144,11 +144,11 @@ const getTxFee = ({ amount, feeRate, maxFee, minFee, stringify = true }) => {
|
|
|
144
144
|
const splitTxFee = ({ total, shares = {}, stringify = true }) => {
|
|
145
145
|
const totalAmount = new BN(total);
|
|
146
146
|
if (totalAmount.lt(ZERO)) {
|
|
147
|
-
throw new Error('
|
|
147
|
+
throw new Error('NEGATIVE_TOTAL_AMOUNT', 'Unexpected negative total when splitTxFee, abort!');
|
|
148
148
|
}
|
|
149
149
|
Object.keys(shares).forEach((key) => {
|
|
150
150
|
if (shares[key] < 0) {
|
|
151
|
-
throw new Error('
|
|
151
|
+
throw new Error('NEGATIVE_FEE_SHARE', `Unexpected negative shares[${key}] when splitTxFee, abort!`);
|
|
152
152
|
}
|
|
153
153
|
});
|
|
154
154
|
|
|
@@ -217,7 +217,7 @@ const ensureBlockReward = (rollupState, minReward, txStates) => {
|
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
if (actualFee.lt(ZERO)) {
|
|
220
|
-
throw new Error('
|
|
220
|
+
throw new Error('NEGATIVE_ACTUAL_FEE', 'Got negative actualFee for tx, abort!');
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
// If the actualFee is less than the maxFee, user will have a refund
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.13.
|
|
6
|
+
"version": "1.13.69",
|
|
7
7
|
"description": "Predefined tx pipeline sets to execute certain type of transactions",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,16 +19,17 @@
|
|
|
19
19
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@arcblock/did": "1.13.
|
|
23
|
-
"@arcblock/did-util": "1.13.
|
|
24
|
-
"@ocap/asset": "1.13.
|
|
25
|
-
"@ocap/mcrypto": "1.13.
|
|
26
|
-
"@ocap/merkle-tree": "1.13.
|
|
27
|
-
"@ocap/message": "1.13.
|
|
28
|
-
"@ocap/state": "1.13.
|
|
29
|
-
"@ocap/tx-pipeline": "1.13.
|
|
30
|
-
"@ocap/util": "1.13.
|
|
31
|
-
"@ocap/
|
|
22
|
+
"@arcblock/did": "1.13.69",
|
|
23
|
+
"@arcblock/did-util": "1.13.69",
|
|
24
|
+
"@ocap/asset": "1.13.69",
|
|
25
|
+
"@ocap/mcrypto": "1.13.69",
|
|
26
|
+
"@ocap/merkle-tree": "1.13.69",
|
|
27
|
+
"@ocap/message": "1.13.69",
|
|
28
|
+
"@ocap/state": "1.13.69",
|
|
29
|
+
"@ocap/tx-pipeline": "1.13.69",
|
|
30
|
+
"@ocap/util": "1.13.69",
|
|
31
|
+
"@ocap/validator": "1.13.69",
|
|
32
|
+
"@ocap/wallet": "1.13.69",
|
|
32
33
|
"debug": "^4.3.2",
|
|
33
34
|
"empty-value": "^1.0.1",
|
|
34
35
|
"lodash": "^4.17.21",
|
|
@@ -41,5 +42,5 @@
|
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"jest": "^27.3.1"
|
|
43
44
|
},
|
|
44
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "7520d994d592dc4fe50612a665c94d7fa4d5b143"
|
|
45
46
|
}
|