@ocap/tx-protocols 1.17.23 → 1.18.0

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.
Files changed (34) hide show
  1. package/lib/pipes/ensure-cost.js +116 -0
  2. package/lib/pipes/ensure-gas.js +53 -0
  3. package/lib/protocols/account/delegate.js +30 -3
  4. package/lib/protocols/account/migrate.js +15 -1
  5. package/lib/protocols/account/revoke-delegate.js +14 -2
  6. package/lib/protocols/asset/acquire-v2.js +25 -2
  7. package/lib/protocols/asset/acquire-v3.js +34 -2
  8. package/lib/protocols/asset/create.js +9 -10
  9. package/lib/protocols/asset/mint.js +28 -2
  10. package/lib/protocols/asset/pipes/exec-mint-hook.js +1 -1
  11. package/lib/protocols/asset/update.js +11 -2
  12. package/lib/protocols/factory/create.js +8 -9
  13. package/lib/protocols/governance/claim-stake.js +41 -4
  14. package/lib/protocols/governance/revoke-stake.js +14 -3
  15. package/lib/protocols/governance/stake.js +53 -4
  16. package/lib/protocols/rollup/claim-reward.js +46 -16
  17. package/lib/protocols/rollup/create-block.js +35 -3
  18. package/lib/protocols/rollup/create.js +8 -18
  19. package/lib/protocols/rollup/join.js +25 -2
  20. package/lib/protocols/rollup/leave.js +15 -2
  21. package/lib/protocols/rollup/migrate-contract.js +13 -2
  22. package/lib/protocols/rollup/migrate-token.js +13 -2
  23. package/lib/protocols/rollup/pause.js +13 -2
  24. package/lib/protocols/rollup/resume.js +13 -2
  25. package/lib/protocols/rollup/update.js +13 -2
  26. package/lib/protocols/token/create.js +19 -9
  27. package/lib/protocols/token/deposit-v2.js +46 -6
  28. package/lib/protocols/token/withdraw-v2.js +43 -6
  29. package/lib/protocols/trade/exchange-v2.js +36 -3
  30. package/lib/protocols/trade/transfer-v2.js +27 -2
  31. package/lib/protocols/trade/transfer-v3.js +34 -1
  32. package/lib/util.js +7 -7
  33. package/package.json +13 -13
  34. package/lib/protocols/rollup/pipes/ensure-service-fee.js +0 -37
@@ -14,7 +14,8 @@ 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 ensureServiceFee = require('../rollup/pipes/ensure-service-fee');
17
+ const EnsureTxGas = require('../../pipes/ensure-gas');
18
+ const EnsureTxCost = require('../../pipes/ensure-cost');
18
19
 
19
20
  const runner = new Runner();
20
21
 
@@ -106,17 +107,18 @@ runner.use((context, next) => {
106
107
  return next(new Error('INVALID_FACTORY_INPUT', 'Not all input.assets exist on chain'));
107
108
  });
108
109
 
109
- runner.use(ensureServiceFee);
110
+ // Ensure tx fee and gas
111
+ runner.use(EnsureTxGas(() => ({ create: 1, update: 1, payment: 0 })));
112
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
110
113
 
111
114
  // Create factory state
112
115
  runner.use(
113
116
  async (context, next) => {
114
- const { tx, itx, statedb, senderState, delegatorState, senderUpdates, vaultState, vaultUpdates, factoryProps } =
115
- context;
117
+ const { tx, itx, statedb, senderState, delegatorState, senderUpdates, factoryProps, updateVaults } = context;
116
118
  const tokens = { [context.config.token.address]: '0' };
117
119
  const owner = delegatorState ? delegatorState.address : senderState.address;
118
120
 
119
- const [newSenderState, factoryState, newVaultState] = await Promise.all([
121
+ const [newSenderState, factoryState] = await Promise.all([
120
122
  // Update owner state
121
123
  statedb.account.update(
122
124
  senderState.address,
@@ -127,14 +129,11 @@ runner.use(
127
129
  // Create factory state
128
130
  statedb.factory.create(itx.address, factory.create({ ...factoryProps, tokens, owner }, context), context),
129
131
 
130
- isEmpty(vaultUpdates)
131
- ? vaultState
132
- : statedb.account.update(vaultState.address, account.update(vaultState, vaultUpdates, context), context),
132
+ updateVaults(),
133
133
  ]);
134
134
 
135
135
  context.senderState = newSenderState;
136
136
  context.factoryState = factoryState;
137
- context.vaultState = newVaultState;
138
137
 
139
138
  debug('createFactory', factoryState);
140
139
 
@@ -6,9 +6,11 @@ const { account, asset, stake, evidence } = require('@ocap/state');
6
6
  const { getRelatedAddresses } = require('@ocap/util/lib/get-related-addr');
7
7
 
8
8
  // eslint-disable-next-line global-require
9
- const debug = require('debug')(`${require('../../../package.json').name}:acquire-asset-v2`);
9
+ const debug = require('debug')(`${require('../../../package.json').name}:claim-stake`);
10
10
 
11
- const { applyTokenUpdates } = require('../../util');
11
+ const { applyTokenUpdates, applyTokenChange } = require('../../util');
12
+ const EnsureTxGas = require('../../pipes/ensure-gas');
13
+ const EnsureTxCost = require('../../pipes/ensure-cost');
12
14
 
13
15
  const runner = new Runner();
14
16
 
@@ -132,10 +134,37 @@ runner.use(pipes.ExtractState({ from: 'assets', to: 'assetStates', status: 'OK',
132
134
  runner.use(pipes.VerifyTransferrable({ assets: 'assetStates' }));
133
135
  runner.use(pipes.VerifyUpdater({ assetKey: 'assetStates', ownerKey: 'stakeState' }));
134
136
 
137
+ // Ensure tx fee and gas
138
+ runner.use(
139
+ EnsureTxGas((context) => {
140
+ const result = { create: 1, update: 2, payment: 0 };
141
+ if (context.receiverStates) {
142
+ result.update += context.receiverStates.length;
143
+ }
144
+ if (context.assetStates) {
145
+ result.update += context.assetStates.length;
146
+ }
147
+
148
+ return result;
149
+ })
150
+ );
151
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
152
+
135
153
  // 8. update statedb
136
154
  runner.use(
137
155
  async (context, next) => {
138
- const { tx, itx, outputs, statedb, senderState, stakeState, receiverStates, assetStates = [] } = context;
156
+ const {
157
+ tx,
158
+ itx,
159
+ outputs,
160
+ statedb,
161
+ senderState,
162
+ senderChange,
163
+ stakeState,
164
+ receiverStates,
165
+ updateVaults,
166
+ assetStates = [],
167
+ } = context;
139
168
 
140
169
  const receiverUpdates = {};
141
170
  const assetUpdates = {};
@@ -150,6 +179,9 @@ runner.use(
150
179
  // Update receiver balance
151
180
  const ownerState = receiverStates.find((s) => getRelatedAddresses(s).includes(owner));
152
181
  receiverUpdates[ownerState.address] = applyTokenUpdates(tokens, ownerState, 'add');
182
+ if (senderChange && ownerState.address === senderChange.address) {
183
+ receiverUpdates[ownerState.address] = applyTokenChange(receiverUpdates[ownerState.address], senderChange);
184
+ }
153
185
 
154
186
  // Update asset owner
155
187
  assets.forEach((a) => {
@@ -170,7 +202,10 @@ runner.use(
170
202
  senderState.address,
171
203
  account.update(
172
204
  senderState,
173
- Object.assign({ nonce: tx.nonce }, receiverUpdates[senderState.address] || {}),
205
+ Object.assign(
206
+ { nonce: tx.nonce },
207
+ receiverUpdates[senderState.address] || (senderChange ? applyTokenChange(senderState, senderChange) : {})
208
+ ),
174
209
  context
175
210
  ),
176
211
  context
@@ -201,6 +236,8 @@ runner.use(
201
236
  evidence.create({ hash: itx.evidence.hash, data: 'claim-stake' }, context),
202
237
  context
203
238
  ),
239
+
240
+ updateVaults(),
204
241
  ]);
205
242
 
206
243
  context.senderState = newSenderState;
@@ -5,9 +5,11 @@ const { account, stake } = require('@ocap/state');
5
5
  const { getRelatedAddresses } = require('@ocap/util/lib/get-related-addr');
6
6
 
7
7
  // eslint-disable-next-line global-require
8
- const debug = require('debug')(`${require('../../../package.json').name}:acquire-asset-v2`);
8
+ const debug = require('debug')(`${require('../../../package.json').name}:revoke-stake`);
9
9
 
10
10
  const { applyTokenUpdates } = require('../../util');
11
+ const EnsureTxGas = require('../../pipes/ensure-gas');
12
+ const EnsureTxCost = require('../../pipes/ensure-cost');
11
13
 
12
14
  const runner = new Runner();
13
15
 
@@ -93,10 +95,14 @@ runner.use(pipes.ExtractState({ from: 'assets', to: 'assetStates', status: 'OK',
93
95
  runner.use(pipes.VerifyTransferrable({ assets: 'assetStates' }));
94
96
  runner.use(pipes.VerifyUpdater({ assetKey: 'assetStates', ownerKey: 'stakeState' }));
95
97
 
98
+ // Ensure tx fee and gas
99
+ runner.use(EnsureTxGas(() => ({ create: 0, update: 2, payment: 0 })));
100
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
101
+
96
102
  // 8. update statedb
97
103
  runner.use(
98
104
  async (context, next) => {
99
- const { tx, itx, outputs, statedb, senderState, stakeState } = context;
105
+ const { tx, itx, outputs, statedb, senderState, senderUpdates, stakeState, updateVaults } = context;
100
106
 
101
107
  const stakeUpdates = {
102
108
  tokens: stakeState.tokens || {},
@@ -119,8 +125,13 @@ runner.use(
119
125
  });
120
126
 
121
127
  const [newSenderState, newStakeState] = await Promise.all([
122
- statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
128
+ statedb.account.update(
129
+ senderState.address,
130
+ account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
131
+ context
132
+ ),
123
133
  statedb.stake.update(stakeState.address, stake.update(stakeState, stakeUpdates, context), context),
134
+ updateVaults(),
124
135
  ]);
125
136
 
126
137
  context.senderState = newSenderState;
@@ -8,9 +8,12 @@ const { toStakeAddress } = require('@arcblock/did-util');
8
8
  const { account, asset, stake } = require('@ocap/state');
9
9
 
10
10
  // eslint-disable-next-line global-require
11
- const debug = require('debug')(`${require('../../../package.json').name}:acquire-asset-v2`);
11
+ const debug = require('debug')(`${require('../../../package.json').name}:stake`);
12
12
 
13
- const { applyTokenUpdates } = require('../../util');
13
+ const { applyTokenUpdates, applyTokenChange } = require('../../util');
14
+
15
+ const EnsureTxGas = require('../../pipes/ensure-gas');
16
+ const EnsureTxCost = require('../../pipes/ensure-cost');
14
17
 
15
18
  const verifyAssetOwner = promisify(pipes.VerifyUpdater({ assetKey: 'assets', ownerKey: 'owner' }));
16
19
 
@@ -94,10 +97,48 @@ runner.use(async (context, next) => {
94
97
  return next();
95
98
  });
96
99
 
100
+ // Ensure tx fee and gas
101
+ runner.use(
102
+ EnsureTxGas((context) => {
103
+ // FIXME: payment check
104
+ const result = { create: 0, update: 0, payment: 0 };
105
+ if (context.senderState) {
106
+ result.update += 1;
107
+ } else {
108
+ result.create += 1;
109
+ }
110
+ if (context.stakeState) {
111
+ result.update += 1;
112
+ } else {
113
+ result.create += 1;
114
+ }
115
+ if (context.signerStates) {
116
+ result.update += context.signerStates.length;
117
+ }
118
+ if (context.assetStates) {
119
+ result.update += context.assetStates.length;
120
+ }
121
+
122
+ return result;
123
+ })
124
+ );
125
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
126
+
97
127
  // update statedb
98
128
  runner.use(
99
129
  async (context, next) => {
100
- const { tx, itx, inputs, statedb, senderState, stakeState, signerStates, assetStates = [] } = context;
130
+ const {
131
+ tx,
132
+ itx,
133
+ inputs,
134
+ statedb,
135
+ senderState,
136
+ senderChange,
137
+ stakeState,
138
+ signerStates,
139
+ updateVaults,
140
+ assetStates = [],
141
+ } = context;
101
142
 
102
143
  const signerUpdates = {};
103
144
  const stakeUpdates = stakeState
@@ -111,6 +152,9 @@ runner.use(
111
152
  signerStates.find((s) => s.address === owner),
112
153
  'sub'
113
154
  );
155
+ if (senderChange && owner === senderChange.address) {
156
+ signerUpdates[owner] = applyTokenChange(signerUpdates[owner], senderChange);
157
+ }
114
158
  Object.assign(stakeUpdates, applyTokenUpdates(tokensList, stakeUpdates, 'add'));
115
159
  stakeUpdates.assets.push(...assetsList);
116
160
  });
@@ -123,7 +167,10 @@ runner.use(
123
167
  senderState,
124
168
  account.updateOrCreate(
125
169
  senderState,
126
- Object.assign({ address: tx.from, nonce: tx.nonce, pk: tx.pk }, signerUpdates[tx.from] || {}),
170
+ Object.assign(
171
+ { address: tx.from, nonce: tx.nonce, pk: tx.pk },
172
+ signerUpdates[tx.from] || (senderChange ? applyTokenChange(senderState, senderChange) : {})
173
+ ),
127
174
  context
128
175
  ),
129
176
  context
@@ -159,6 +206,8 @@ runner.use(
159
206
  statedb.asset.update(x.address, asset.update(x, { owner: itx.address }, context), context)
160
207
  )
161
208
  ),
209
+
210
+ updateVaults(),
162
211
  ]);
163
212
 
164
213
  context.senderState = newSenderState;
@@ -12,6 +12,8 @@ const debug = require('debug')(`${require('../../../package.json').name}:claim-b
12
12
 
13
13
  const { toStakeAddress } = require('@arcblock/did-util');
14
14
  const VerifySigners = require('./pipes/verify-signers');
15
+ const EnsureTxGas = require('../../pipes/ensure-gas');
16
+ const EnsureTxCost = require('../../pipes/ensure-cost');
15
17
  const { applyTokenChange, splitTxFee, getBNSum, getRewardLocker, RATE_BASE } = require('../../util');
16
18
 
17
19
  const runner = new Runner();
@@ -211,10 +213,40 @@ runner.use((context, next) => {
211
213
  return next();
212
214
  });
213
215
 
216
+ // Ensure tx fee and gas
217
+ runner.use(
218
+ EnsureTxGas((context) => {
219
+ const result = { create: 2, update: 1, payment: 0 };
220
+
221
+ result.update += context.accountStates.length;
222
+ if (context.updates[context.lockerState.address]) {
223
+ result.update += 1;
224
+ }
225
+ if (context.updates[context.stakeState.address]) {
226
+ result.update += 1;
227
+ }
228
+
229
+ return result;
230
+ })
231
+ );
232
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
233
+
214
234
  // 10. update state
215
235
  runner.use(
216
236
  async (context, next) => {
217
- const { tx, itx, updates, statedb, senderState, blockState, lockerState, stakeState, accountStates } = context;
237
+ const {
238
+ tx,
239
+ itx,
240
+ updates,
241
+ statedb,
242
+ senderState,
243
+ blockState,
244
+ lockerState,
245
+ stakeState,
246
+ accountStates,
247
+ senderChange,
248
+ updateVaults,
249
+ } = context;
218
250
 
219
251
  const [newStakeStates, newAccountStates, newBlockState] = await Promise.all([
220
252
  // update stake states
@@ -232,20 +264,15 @@ runner.use(
232
264
 
233
265
  // update accounts(proposer, publisher, validator)
234
266
  Promise.all(
235
- accountStates.map((x) =>
236
- statedb.account.update(
237
- x.address,
238
- account.update(
239
- x,
240
- Object.assign(
241
- x.address === senderState.address ? { nonce: tx.nonce } : {},
242
- applyTokenChange(x, updates.account[x.address])
243
- ),
244
- context
245
- ),
246
- context
247
- )
248
- )
267
+ accountStates.map((x) => {
268
+ let updateSet = applyTokenChange(x, updates.account[x.address]);
269
+ if (x.address === senderState.address) {
270
+ updateSet.nonce = tx.nonce;
271
+ updateSet = Object.assign(updateSet, applyTokenChange(updateSet, senderChange));
272
+ }
273
+
274
+ return statedb.account.update(x.address, account.update(x, updateSet, context), context);
275
+ })
249
276
  ),
250
277
 
251
278
  // Update block state, just update the context
@@ -262,6 +289,8 @@ runner.use(
262
289
  evidence.create({ hash: itx.blockHash, data: 'rollup-claim-block-reward' }, context),
263
290
  context
264
291
  ),
292
+
293
+ updateVaults(),
265
294
  ]);
266
295
 
267
296
  // to avoid this to be incorrectly indexed
@@ -271,7 +300,8 @@ runner.use(
271
300
  context.accountStates = newAccountStates;
272
301
  context.blockState = newBlockState;
273
302
 
274
- context.updatedAccounts = cloneDeep([...Object.values(updates.account), ...Object.values(updates.stake)]);
303
+ context.updatedAccounts.push(...cloneDeep(Object.values(updates.account)));
304
+ context.updatedAccounts.push(...cloneDeep(Object.values(updates.stake)));
275
305
 
276
306
  debug('claim-block-reward', itx);
277
307
 
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable indent */
2
2
  const pick = require('lodash/pick');
3
+ const cloneDeep = require('lodash/cloneDeep');
3
4
  const { CustomError: Error } = require('@ocap/util/lib/error');
4
5
  const MerkleTree = require('@ocap/merkle-tree');
5
6
  const { Joi, schemas, patterns } = require('@arcblock/validator');
@@ -14,6 +15,9 @@ const debug = require('debug')(`${require('../../../package.json').name}:create-
14
15
  const VerifySigners = require('./pipes/verify-signers');
15
16
  const VerifyEvidence = require('./pipes/verify-evidence');
16
17
  const VerifyPaused = require('./pipes/verify-paused');
18
+ const EnsureTxGas = require('../../pipes/ensure-gas');
19
+ const EnsureTxCost = require('../../pipes/ensure-cost');
20
+
17
21
  const { applyTokenChange, ensureBlockReward, getRewardLocker } = require('../../util');
18
22
 
19
23
  const runner = new Runner();
@@ -246,10 +250,35 @@ runner.use((context, next) => {
246
250
  });
247
251
  runner.use(pipes.ExtractState({ from: 'senders', to: 'senderStates', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
248
252
 
253
+ // Ensure tx fee and gas
254
+ runner.use(
255
+ EnsureTxGas((context) => {
256
+ const result = { create: 1, update: 2, payment: 0 };
257
+
258
+ result.update += context.stakeStates.filter((x) => context.stakeUpdates[x.address]).length;
259
+ result.update += context.txStates.length;
260
+ result.update += (context.senderStates || []).length;
261
+
262
+ return result;
263
+ })
264
+ );
265
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
266
+
249
267
  // 11. update state: mint tokens for deposits, burn tokens for withdraws
250
268
  runner.use(
251
269
  async (context, next) => {
252
- const { tx, itx, statedb, rollupState, senderState, stakeStates, txStates, formattedItx } = context;
270
+ const {
271
+ tx,
272
+ itx,
273
+ statedb,
274
+ rollupState,
275
+ senderState,
276
+ stakeStates,
277
+ txStates,
278
+ formattedItx,
279
+ senderUpdates,
280
+ updateVaults,
281
+ } = context;
253
282
  const senderStates = context.senderStates || [];
254
283
 
255
284
  const [newSenderState, newStakeStates, newSenderStates, newRollupState, rollupBlockState, newTxStates] =
@@ -257,7 +286,7 @@ runner.use(
257
286
  // update sender(proposer) account
258
287
  statedb.account.update(
259
288
  senderState.address,
260
- account.update(senderState, Object.assign({ nonce: tx.nonce }), context),
289
+ account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
261
290
  context
262
291
  ),
263
292
 
@@ -312,6 +341,8 @@ runner.use(
312
341
  Promise.all(
313
342
  txStates.map((x) => statedb.tx.update(x.hash, Tx.update(x, { finalized: true, tx: x.tx }), context))
314
343
  ),
344
+
345
+ updateVaults(),
315
346
  ]);
316
347
 
317
348
  context.senderState = newSenderState;
@@ -321,7 +352,8 @@ runner.use(
321
352
  context.rollupBlockState = rollupBlockState;
322
353
  context.txStates = newTxStates;
323
354
 
324
- context.updatedAccounts = [...Object.values(context.stakeUpdates), ...Object.values(context.accountUpdates)];
355
+ context.updatedAccounts.push(...cloneDeep(Object.values(context.stakeUpdates)));
356
+ context.updatedAccounts.push(...cloneDeep(Object.values(context.accountUpdates)));
325
357
 
326
358
  debug('create-rollup-block', { itx, updatedAccounts: context.updatedAccounts });
327
359
 
@@ -12,7 +12,8 @@ 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 ensureServiceFee = require('./pipes/ensure-service-fee');
15
+ const EnsureTxGas = require('../../pipes/ensure-gas');
16
+ const EnsureTxCost = require('../../pipes/ensure-cost');
16
17
 
17
18
  const runner = new Runner();
18
19
 
@@ -108,25 +109,17 @@ runner.use(
108
109
  ])
109
110
  );
110
111
 
111
- runner.use(ensureServiceFee);
112
+ // Ensure tx fee and gas
113
+ runner.use(EnsureTxGas(() => ({ create: 1, update: 1, payment: 0 })));
114
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
112
115
 
113
116
  // 5. create rollup state
114
117
  runner.use(
115
118
  async (context, next) => {
116
- const {
117
- tx,
118
- formattedItx,
119
- rollupData,
120
- statedb,
121
- senderState,
122
- delegatorState,
123
- senderUpdates,
124
- vaultState,
125
- vaultUpdates,
126
- } = context;
119
+ const { tx, formattedItx, rollupData, statedb, senderState, delegatorState, senderUpdates, updateVaults } = context;
127
120
 
128
121
  const issuer = delegatorState ? delegatorState.address : senderState.address;
129
- const [newSenderState, rollupState, newVaultState] = await Promise.all([
122
+ const [newSenderState, rollupState] = await Promise.all([
130
123
  statedb.account.update(
131
124
  senderState.address,
132
125
  account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
@@ -147,9 +140,7 @@ runner.use(
147
140
  context
148
141
  ),
149
142
 
150
- isEmpty(vaultUpdates)
151
- ? vaultState
152
- : statedb.account.update(vaultState.address, account.update(vaultState, vaultUpdates, context), context),
143
+ updateVaults(),
153
144
  ]);
154
145
 
155
146
  // FIXME: create-rollup 的时候不能校验 stake,还是在这里创建 stake?如果在这里创建 stake,是否需要多签?
@@ -157,7 +148,6 @@ runner.use(
157
148
 
158
149
  context.senderState = newSenderState;
159
150
  context.rollupState = rollupState;
160
- context.vaultState = newVaultState;
161
151
 
162
152
  debug('create-rollup', rollupState);
163
153
 
@@ -15,6 +15,8 @@ const debug = require('debug')(`${require('../../../package.json').name}:join-ro
15
15
  const VerifySigners = require('./pipes/verify-signers');
16
16
  const VerifyEvidence = require('./pipes/verify-evidence');
17
17
  const VerifyPaused = require('./pipes/verify-paused');
18
+ const EnsureTxGas = require('../../pipes/ensure-gas');
19
+ const EnsureTxCost = require('../../pipes/ensure-cost');
18
20
 
19
21
  const runner = new Runner();
20
22
 
@@ -110,14 +112,33 @@ runner.use(
110
112
  );
111
113
  runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
112
114
 
115
+ // Ensure tx fee and gas
116
+ runner.use(EnsureTxGas(() => ({ create: 1, update: 3, payment: 0 })));
117
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
118
+
113
119
  // 8. update state
114
120
  runner.use(
115
121
  async (context, next) => {
116
- const { tx, itx, rollupState, statedb, senderState, stakeState, newValidator, stakeAddress } = context;
122
+ const {
123
+ tx,
124
+ itx,
125
+ rollupState,
126
+ statedb,
127
+ senderState,
128
+ stakeState,
129
+ newValidator,
130
+ stakeAddress,
131
+ senderUpdates,
132
+ updateVaults,
133
+ } = context;
117
134
  const newValidators = rollupState.validators.concat([newValidator]);
118
135
 
119
136
  const [newSenderState, newRollupState, newStakeState, evidenceState] = await Promise.all([
120
- statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
137
+ statedb.account.update(
138
+ senderState.address,
139
+ account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
140
+ context
141
+ ),
121
142
 
122
143
  // persist new validators list
123
144
  statedb.rollup.update(
@@ -139,6 +160,8 @@ runner.use(
139
160
  evidence.create({ hash: itx.evidence.hash, data: 'rollup-join' }, context),
140
161
  context
141
162
  ),
163
+
164
+ updateVaults(),
142
165
  ]);
143
166
 
144
167
  context.senderState = newSenderState;
@@ -12,6 +12,8 @@ const debug = require('debug')(`${require('../../../package.json').name}:leave-r
12
12
  const VerifySigners = require('./pipes/verify-signers');
13
13
  const VerifyEvidence = require('./pipes/verify-evidence');
14
14
  const VerifyPaused = require('./pipes/verify-paused');
15
+ const EnsureTxGas = require('../../pipes/ensure-gas');
16
+ const EnsureTxCost = require('../../pipes/ensure-cost');
15
17
 
16
18
  const runner = new Runner();
17
19
 
@@ -85,14 +87,23 @@ runner.use(
85
87
  );
86
88
  runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
87
89
 
90
+ // Ensure tx fee and gas
91
+ runner.use(EnsureTxGas(() => ({ create: 1, update: 3, payment: 0 })));
92
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
93
+
88
94
  // 8. update state
89
95
  runner.use(
90
96
  async (context, next) => {
91
- const { tx, itx, rollupState, statedb, senderState, stakeState, stakeAddress } = context;
97
+ const { tx, itx, rollupState, statedb, senderState, stakeState, stakeAddress, senderUpdates, updateVaults } =
98
+ context;
92
99
  const newValidators = rollupState.validators.filter((x) => x.address !== tx.from);
93
100
 
94
101
  const [newSenderState, newRollupState, newStakeState, evidenceState] = await Promise.all([
95
- statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
102
+ statedb.account.update(
103
+ senderState.address,
104
+ account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
105
+ context
106
+ ),
96
107
 
97
108
  // persist new validators list
98
109
  statedb.rollup.update(
@@ -110,6 +121,8 @@ runner.use(
110
121
  evidence.create({ hash: itx.evidence.hash, data: 'rollup-leave' }, context),
111
122
  context
112
123
  ),
124
+
125
+ updateVaults(),
113
126
  ]);
114
127
 
115
128
  context.senderState = newSenderState;
@@ -5,6 +5,8 @@ const { account, rollup } = require('@ocap/state');
5
5
 
6
6
  const VerifySigners = require('./pipes/verify-signers');
7
7
  const EnsureValidator = require('./pipes/ensure-validator');
8
+ const EnsureTxGas = require('../../pipes/ensure-gas');
9
+ const EnsureTxCost = require('../../pipes/ensure-cost');
8
10
 
9
11
  const runner = new Runner();
10
12
 
@@ -32,14 +34,23 @@ runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INV
32
34
  runner.use(pipes.ExtractState({ from: 'signers', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
33
35
  runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
34
36
 
37
+ // Ensure tx fee and gas
38
+ runner.use(EnsureTxGas(() => ({ create: 0, update: 2, payment: 0 })));
39
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
40
+
35
41
  // 5. update rollup state
36
42
  runner.use(
37
43
  async (context, next) => {
38
- const { tx, itx, rollupState, statedb, senderState } = context;
44
+ const { tx, itx, rollupState, statedb, senderState, senderUpdates, updateVaults } = context;
39
45
 
40
46
  const [newSenderState, newRollupState] = await Promise.all([
41
- statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
47
+ statedb.account.update(
48
+ senderState.address,
49
+ account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
50
+ context
51
+ ),
42
52
  statedb.rollup.update(itx.rollup, rollup.migrate(rollupState, itx.to, context), context),
53
+ updateVaults(),
43
54
  ]);
44
55
 
45
56
  context.senderState = newSenderState;
@@ -5,6 +5,8 @@ const { account } = require('@ocap/state');
5
5
 
6
6
  const VerifySigners = require('./pipes/verify-signers');
7
7
  const EnsureValidator = require('./pipes/ensure-validator');
8
+ const EnsureTxGas = require('../../pipes/ensure-gas');
9
+ const EnsureTxCost = require('../../pipes/ensure-cost');
8
10
 
9
11
  const runner = new Runner();
10
12
 
@@ -47,13 +49,22 @@ runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INV
47
49
  runner.use(pipes.ExtractState({ from: 'signers', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
48
50
  runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
49
51
 
52
+ // Ensure tx fee and gas
53
+ runner.use(EnsureTxGas(() => ({ create: 0, update: 1, payment: 0 })));
54
+ runner.use(EnsureTxCost({ attachSenderChanges: true }));
55
+
50
56
  // 5. update state
51
57
  runner.use(
52
58
  async (context, next) => {
53
- const { tx, statedb, senderState } = context;
59
+ const { tx, statedb, senderState, senderUpdates, updateVaults } = context;
54
60
 
55
61
  const [newSenderState] = await Promise.all([
56
- statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
62
+ statedb.account.update(
63
+ senderState.address,
64
+ account.update(senderState, { nonce: tx.nonce, ...senderUpdates }, context),
65
+ context
66
+ ),
67
+ updateVaults(),
57
68
  ]);
58
69
 
59
70
  context.senderState = newSenderState;