@ocap/tx-protocols 1.13.70 → 1.13.71
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/index.js +8 -0
- package/lib/protocols/rollup/create.js +5 -8
- package/lib/protocols/rollup/migrate-contract.js +53 -0
- package/lib/protocols/rollup/migrate-token.js +66 -0
- package/lib/protocols/rollup/pause.js +52 -0
- package/lib/protocols/rollup/pipes/ensure-validator.js +10 -0
- package/lib/protocols/rollup/resume.js +52 -0
- package/lib/protocols/rollup/update.js +0 -1
- package/package.json +13 -13
package/lib/index.js
CHANGED
|
@@ -23,8 +23,12 @@ const createRollup = require('./protocols/rollup/create');
|
|
|
23
23
|
const updateRollup = require('./protocols/rollup/update');
|
|
24
24
|
const joinRollup = require('./protocols/rollup/join');
|
|
25
25
|
const leaveRollup = require('./protocols/rollup/leave');
|
|
26
|
+
const pauseRollup = require('./protocols/rollup/pause');
|
|
27
|
+
const resumeRollup = require('./protocols/rollup/resume');
|
|
26
28
|
const createRollupBlock = require('./protocols/rollup/create-block');
|
|
27
29
|
const claimBlockReward = require('./protocols/rollup/claim-reward');
|
|
30
|
+
const migrateRollupContract = require('./protocols/rollup/migrate-contract');
|
|
31
|
+
const migrateRollupToken = require('./protocols/rollup/migrate-token');
|
|
28
32
|
|
|
29
33
|
const executor = require('./execute');
|
|
30
34
|
|
|
@@ -67,8 +71,12 @@ const createExecutor = ({ filter, runAsLambda }) => {
|
|
|
67
71
|
updateRollup,
|
|
68
72
|
joinRollup,
|
|
69
73
|
leaveRollup,
|
|
74
|
+
pauseRollup,
|
|
75
|
+
resumeRollup,
|
|
70
76
|
createRollupBlock,
|
|
71
77
|
claimBlockReward,
|
|
78
|
+
migrateRollupContract,
|
|
79
|
+
migrateRollupToken,
|
|
72
80
|
};
|
|
73
81
|
|
|
74
82
|
const execute = executor({ filter, runAsLambda });
|
|
@@ -58,6 +58,7 @@ runner.use(
|
|
|
58
58
|
|
|
59
59
|
// Save for later use
|
|
60
60
|
context.rollupData = itx.data;
|
|
61
|
+
context.seedValidators = itx.seedValidatorsList.map((x) => x.address);
|
|
61
62
|
|
|
62
63
|
return toRollupAddress(itx) === context.itx.address;
|
|
63
64
|
},
|
|
@@ -65,11 +66,10 @@ runner.use(
|
|
|
65
66
|
])
|
|
66
67
|
);
|
|
67
68
|
|
|
68
|
-
// 1. ensure sender exist
|
|
69
|
-
runner.use(
|
|
70
|
-
|
|
71
|
-
);
|
|
72
|
-
runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
|
|
69
|
+
// 1. ensure sender & validators exist
|
|
70
|
+
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
|
|
71
|
+
runner.use(pipes.ExtractState({ from: 'seedValidators', to: 'validatorStates', status: 'INVALID_VALIDATOR_STATE', table: 'account' })); // prettier-ignore
|
|
72
|
+
runner.use(pipes.VerifyAccountMigration({ signerKey: 'validatorStates', senderKey: 'senderState' }));
|
|
73
73
|
|
|
74
74
|
// 2. ensure token exist and match
|
|
75
75
|
runner.use(pipes.ExtractState({ from: 'itx.tokenAddress', to: 'tokenState', status: 'INVALID_TOKEN', table: 'token' }));
|
|
@@ -125,9 +125,6 @@ runner.use(
|
|
|
125
125
|
rollup.create(
|
|
126
126
|
{
|
|
127
127
|
...formattedItx,
|
|
128
|
-
paused: false,
|
|
129
|
-
blockHeight: 0,
|
|
130
|
-
blockHash: '',
|
|
131
128
|
issuer: senderState.address,
|
|
132
129
|
validators: formattedItx.seedValidators,
|
|
133
130
|
data: rollupData,
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
3
|
+
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
4
|
+
const { account, rollup } = require('@ocap/state');
|
|
5
|
+
|
|
6
|
+
const VerifySigners = require('./pipes/verify-signers');
|
|
7
|
+
const EnsureValidator = require('./pipes/ensure-validator');
|
|
8
|
+
|
|
9
|
+
const runner = new Runner();
|
|
10
|
+
|
|
11
|
+
// 1. verify itx
|
|
12
|
+
const schema = Joi.object({
|
|
13
|
+
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
14
|
+
to: Joi.DID().wallet('ethereum').required(),
|
|
15
|
+
data: Joi.any().optional(),
|
|
16
|
+
}).options({ stripUnknown: true, noDefaults: false });
|
|
17
|
+
runner.use(({ itx }, next) => {
|
|
18
|
+
const { error } = schema.validate(itx);
|
|
19
|
+
return next(error ? new Error('INVALID_TX', `Invalid itx: ${error.message}`) : null);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// 2. verify rollup
|
|
23
|
+
runner.use(pipes.ExtractState({ from: 'itx.rollup', to: 'rollupState', status: 'INVALID_ROLLUP', table: 'rollup' }));
|
|
24
|
+
runner.use(EnsureValidator(true));
|
|
25
|
+
|
|
26
|
+
// 3. verify tx signers and signatures
|
|
27
|
+
runner.use(VerifySigners({ signersKey: 'tx.signaturesList', allowSender: true }));
|
|
28
|
+
runner.use(pipes.VerifyMultiSigV2({ signersKey: 'signers' }));
|
|
29
|
+
|
|
30
|
+
// 4. verify sender and signer states
|
|
31
|
+
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
|
|
32
|
+
runner.use(pipes.ExtractState({ from: 'signers', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
|
|
33
|
+
runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
|
|
34
|
+
|
|
35
|
+
// 5. update rollup state
|
|
36
|
+
runner.use(
|
|
37
|
+
async (context, next) => {
|
|
38
|
+
const { tx, itx, rollupState, statedb, senderState } = context;
|
|
39
|
+
|
|
40
|
+
const [newSenderState, newRollupState] = await Promise.all([
|
|
41
|
+
statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
|
|
42
|
+
statedb.rollup.update(itx.rollup, rollup.migrate(rollupState, itx.to, context), context),
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
context.senderState = newSenderState;
|
|
46
|
+
context.rollupState = newRollupState;
|
|
47
|
+
|
|
48
|
+
next();
|
|
49
|
+
},
|
|
50
|
+
{ persistError: true }
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
module.exports = runner;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
3
|
+
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
4
|
+
const { account } = require('@ocap/state');
|
|
5
|
+
|
|
6
|
+
const VerifySigners = require('./pipes/verify-signers');
|
|
7
|
+
const EnsureValidator = require('./pipes/ensure-validator');
|
|
8
|
+
|
|
9
|
+
const runner = new Runner();
|
|
10
|
+
|
|
11
|
+
// 1. verify itx
|
|
12
|
+
const schema = Joi.object({
|
|
13
|
+
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
14
|
+
from: Joi.DID().wallet('ethereum').required(),
|
|
15
|
+
to: Joi.DID().wallet('ethereum').required(),
|
|
16
|
+
token: Joi.object({
|
|
17
|
+
address: Joi.DID().wallet('ethereum').required(),
|
|
18
|
+
value: Joi.BN().positive().required(),
|
|
19
|
+
}),
|
|
20
|
+
data: Joi.any().optional(),
|
|
21
|
+
}).options({ stripUnknown: true, noDefaults: false });
|
|
22
|
+
runner.use(({ itx }, next) => {
|
|
23
|
+
const { error } = schema.validate(itx);
|
|
24
|
+
return next(error ? new Error('INVALID_TX', `Invalid itx: ${error.message}`) : null);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// 2. verify rollup
|
|
28
|
+
runner.use(pipes.ExtractState({ from: 'itx.rollup', to: 'rollupState', status: 'INVALID_ROLLUP', table: 'rollup' }));
|
|
29
|
+
runner.use(EnsureValidator(true));
|
|
30
|
+
runner.use(({ itx, rollupState }, next) => {
|
|
31
|
+
if (rollupState.migrateHistory.includes(itx.from) === false) {
|
|
32
|
+
return next(new Error('INVALID_MIGRATE_ATTEMPT', 'itx.from must exist in rollup migrate history'));
|
|
33
|
+
}
|
|
34
|
+
if (itx.to !== rollupState.contractAddress) {
|
|
35
|
+
return next(new Error('INVALID_MIGRATE_ATTEMPT', 'itx.to must equal to latest rollup contract address'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return next();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// 3. verify tx signers and signatures
|
|
42
|
+
runner.use(VerifySigners({ signersKey: 'tx.signaturesList', allowSender: true }));
|
|
43
|
+
runner.use(pipes.VerifyMultiSigV2({ signersKey: 'signers' }));
|
|
44
|
+
|
|
45
|
+
// 4. verify sender and signer states
|
|
46
|
+
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
|
|
47
|
+
runner.use(pipes.ExtractState({ from: 'signers', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
|
|
48
|
+
runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
|
|
49
|
+
|
|
50
|
+
// 5. update state
|
|
51
|
+
runner.use(
|
|
52
|
+
async (context, next) => {
|
|
53
|
+
const { tx, statedb, senderState } = context;
|
|
54
|
+
|
|
55
|
+
const [newSenderState] = await Promise.all([
|
|
56
|
+
statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
context.senderState = newSenderState;
|
|
60
|
+
|
|
61
|
+
next();
|
|
62
|
+
},
|
|
63
|
+
{ persistError: true }
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
module.exports = runner;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
3
|
+
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
4
|
+
const { account, rollup } = require('@ocap/state');
|
|
5
|
+
|
|
6
|
+
const VerifySigners = require('./pipes/verify-signers');
|
|
7
|
+
const EnsureValidator = require('./pipes/ensure-validator');
|
|
8
|
+
|
|
9
|
+
const runner = new Runner();
|
|
10
|
+
|
|
11
|
+
// 1. verify itx
|
|
12
|
+
const schema = Joi.object({
|
|
13
|
+
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
14
|
+
data: Joi.any().optional(),
|
|
15
|
+
}).options({ stripUnknown: true, noDefaults: false });
|
|
16
|
+
runner.use(({ itx }, next) => {
|
|
17
|
+
const { error } = schema.validate(itx);
|
|
18
|
+
return next(error ? new Error('INVALID_TX', `Invalid itx: ${error.message}`) : null);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// 2. verify rollup
|
|
22
|
+
runner.use(pipes.ExtractState({ from: 'itx.rollup', to: 'rollupState', status: 'INVALID_ROLLUP', table: 'rollup' }));
|
|
23
|
+
runner.use(EnsureValidator(true));
|
|
24
|
+
|
|
25
|
+
// 3. verify tx signers and signatures
|
|
26
|
+
runner.use(VerifySigners({ signersKey: 'tx.signaturesList', allowSender: true }));
|
|
27
|
+
runner.use(pipes.VerifyMultiSigV2({ signersKey: 'signers' }));
|
|
28
|
+
|
|
29
|
+
// 4. verify sender and signer states
|
|
30
|
+
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
|
|
31
|
+
runner.use(pipes.ExtractState({ from: 'signers', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
|
|
32
|
+
runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
|
|
33
|
+
|
|
34
|
+
// 5. update rollup state
|
|
35
|
+
runner.use(
|
|
36
|
+
async (context, next) => {
|
|
37
|
+
const { tx, itx, rollupState, statedb, senderState } = context;
|
|
38
|
+
|
|
39
|
+
const [newSenderState, newRollupState] = await Promise.all([
|
|
40
|
+
statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
|
|
41
|
+
statedb.rollup.update(itx.rollup, rollup.pause(rollupState, context), context),
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
context.senderState = newSenderState;
|
|
45
|
+
context.rollupState = newRollupState;
|
|
46
|
+
|
|
47
|
+
next();
|
|
48
|
+
},
|
|
49
|
+
{ persistError: true }
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
module.exports = runner;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = (isSeed) => async (context, next) => {
|
|
2
|
+
const { rollupState, tx } = context;
|
|
3
|
+
|
|
4
|
+
const validators = isSeed ? rollupState.seedValidators : rollupState.validators;
|
|
5
|
+
if (validators.some((x) => x.address === tx.from) === false) {
|
|
6
|
+
return next(new Error('INVALID_TX', 'Tx sender is not an expected validator'));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
return next();
|
|
10
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const Error = require('@ocap/util/lib/error');
|
|
2
|
+
const Joi = require('@ocap/validator');
|
|
3
|
+
const { Runner, pipes } = require('@ocap/tx-pipeline');
|
|
4
|
+
const { account, rollup } = require('@ocap/state');
|
|
5
|
+
|
|
6
|
+
const VerifySigners = require('./pipes/verify-signers');
|
|
7
|
+
const EnsureValidator = require('./pipes/ensure-validator');
|
|
8
|
+
|
|
9
|
+
const runner = new Runner();
|
|
10
|
+
|
|
11
|
+
// 1. verify itx
|
|
12
|
+
const schema = Joi.object({
|
|
13
|
+
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
14
|
+
data: Joi.any().optional(),
|
|
15
|
+
}).options({ stripUnknown: true, noDefaults: false });
|
|
16
|
+
runner.use(({ itx }, next) => {
|
|
17
|
+
const { error } = schema.validate(itx);
|
|
18
|
+
return next(error ? new Error('INVALID_TX', `Invalid itx: ${error.message}`) : null);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// 2. verify rollup
|
|
22
|
+
runner.use(pipes.ExtractState({ from: 'itx.rollup', to: 'rollupState', status: 'INVALID_ROLLUP', table: 'rollup' }));
|
|
23
|
+
runner.use(EnsureValidator(true));
|
|
24
|
+
|
|
25
|
+
// 3. verify tx signers and signatures
|
|
26
|
+
runner.use(VerifySigners({ signersKey: 'tx.signaturesList', allowSender: true }));
|
|
27
|
+
runner.use(pipes.VerifyMultiSigV2({ signersKey: 'signers' }));
|
|
28
|
+
|
|
29
|
+
// 4. verify sender and signer states
|
|
30
|
+
runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
|
|
31
|
+
runner.use(pipes.ExtractState({ from: 'signers', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })); // prettier-ignore
|
|
32
|
+
runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', senderKey: 'senderState' }));
|
|
33
|
+
|
|
34
|
+
// 5. update rollup state
|
|
35
|
+
runner.use(
|
|
36
|
+
async (context, next) => {
|
|
37
|
+
const { tx, itx, rollupState, statedb, senderState } = context;
|
|
38
|
+
|
|
39
|
+
const [newSenderState, newRollupState] = await Promise.all([
|
|
40
|
+
statedb.account.update(senderState.address, account.update(senderState, { nonce: tx.nonce }, context), context),
|
|
41
|
+
statedb.rollup.update(itx.rollup, rollup.resume(rollupState, context), context),
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
context.senderState = newSenderState;
|
|
45
|
+
context.rollupState = newRollupState;
|
|
46
|
+
|
|
47
|
+
next();
|
|
48
|
+
},
|
|
49
|
+
{ persistError: true }
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
module.exports = runner;
|
|
@@ -15,7 +15,6 @@ const runner = new Runner();
|
|
|
15
15
|
// 1. verify itx: client must use previous rollup state to construct this itx
|
|
16
16
|
const schema = Joi.object({
|
|
17
17
|
rollup: Joi.DID().role('ROLE_ROLLUP').required(),
|
|
18
|
-
paused: Joi.boolean().required(),
|
|
19
18
|
|
|
20
19
|
minStakeAmount: Joi.BN().greater(0).required(),
|
|
21
20
|
maxStakeAmount: Joi.BN().greater(Joi.ref('minStakeAmount')).required(),
|
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.71",
|
|
7
7
|
"description": "Predefined tx pipeline sets to execute certain type of transactions",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -19,17 +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/validator": "1.13.
|
|
32
|
-
"@ocap/wallet": "1.13.
|
|
22
|
+
"@arcblock/did": "1.13.71",
|
|
23
|
+
"@arcblock/did-util": "1.13.71",
|
|
24
|
+
"@ocap/asset": "1.13.71",
|
|
25
|
+
"@ocap/mcrypto": "1.13.71",
|
|
26
|
+
"@ocap/merkle-tree": "1.13.71",
|
|
27
|
+
"@ocap/message": "1.13.71",
|
|
28
|
+
"@ocap/state": "1.13.71",
|
|
29
|
+
"@ocap/tx-pipeline": "1.13.71",
|
|
30
|
+
"@ocap/util": "1.13.71",
|
|
31
|
+
"@ocap/validator": "1.13.71",
|
|
32
|
+
"@ocap/wallet": "1.13.71",
|
|
33
33
|
"debug": "^4.3.2",
|
|
34
34
|
"empty-value": "^1.0.1",
|
|
35
35
|
"lodash": "^4.17.21",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"jest": "^27.3.1"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "82321f1dcd59ae272e87372bafaacc562e99c9ee"
|
|
46
46
|
}
|