@ocap/tx-protocols 1.13.79 → 1.13.83

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.
@@ -70,6 +70,10 @@ runner.use(
70
70
  runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
71
71
  runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
72
72
 
73
+ // Ensure delegation
74
+ runner.use(pipes.ExtractState({ from: 'tx.delegator', to: 'delegatorState', status: 'OK', table: 'account' }));
75
+ runner.use(pipes.VerifyDelegation({ type: 'signature', signerKey: 'senderState', delegatorKey: 'delegatorState' }));
76
+
73
77
  // Check if parent is a factory
74
78
  runner.use(pipes.ExtractState({ from: 'itx.parent', to: 'factoryState', status: 'OK', table: 'factory' }));
75
79
  runner.use(
@@ -93,7 +97,9 @@ runner.use(ensureTxFee);
93
97
  // Update asset state
94
98
  runner.use(
95
99
  async (context, next) => {
96
- const { tx, itx, assetData, statedb, senderState, senderUpdates, vaultState, vaultUpdates } = context;
100
+ const { tx, itx, assetData, statedb, senderState, delegatorState, senderUpdates, vaultState, vaultUpdates } =
101
+ context;
102
+ const owner = delegatorState ? delegatorState.address : senderState.address;
97
103
 
98
104
  const [newSenderState, assetState, newVaultState] = await Promise.all([
99
105
  statedb.account.update(
@@ -102,11 +108,7 @@ runner.use(
102
108
  context
103
109
  ),
104
110
 
105
- statedb.asset.create(
106
- itx.address,
107
- asset.create({ ...itx, data: assetData, owner: senderState.address }, context),
108
- context
109
- ),
111
+ statedb.asset.create(itx.address, asset.create({ ...itx, data: assetData, owner }, context), context),
110
112
 
111
113
  isEmpty(vaultUpdates)
112
114
  ? vaultState
@@ -83,6 +83,10 @@ runner.use(
83
83
  runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', table: 'account', status: 'INVALID_SENDER_STATE' })); // prettier-ignore
84
84
  runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
85
85
 
86
+ // Ensure delegation
87
+ runner.use(pipes.ExtractState({ from: 'tx.delegator', to: 'delegatorState', status: 'OK', table: 'account' }));
88
+ runner.use(pipes.VerifyDelegation({ type: 'signature', signerKey: 'senderState', delegatorKey: 'delegatorState' }));
89
+
86
90
  // Ensure tokens exist if we are creating an factory that consume tokens
87
91
  runner.use(pipes.ExtractState({ from: 'factoryTokens', to: 'tokenStates', table: 'token', status: 'INVALID_FACTORY_INPUT' })); // prettier-ignore
88
92
 
@@ -107,8 +111,10 @@ runner.use(ensureTxFee);
107
111
  // Create factory state
108
112
  runner.use(
109
113
  async (context, next) => {
110
- const { tx, itx, statedb, senderState, senderUpdates, vaultState, vaultUpdates, factoryProps } = context;
114
+ const { tx, itx, statedb, senderState, delegatorState, senderUpdates, vaultState, vaultUpdates, factoryProps } =
115
+ context;
111
116
  const tokens = { [context.config.token.address]: '0' };
117
+ const owner = delegatorState ? delegatorState.address : senderState.address;
112
118
 
113
119
  const [newSenderState, factoryState, newVaultState] = await Promise.all([
114
120
  // Update owner state
@@ -119,11 +125,7 @@ runner.use(
119
125
  ),
120
126
 
121
127
  // Create factory state
122
- statedb.factory.create(
123
- itx.address,
124
- factory.create({ ...factoryProps, tokens, owner: senderState.address }, context),
125
- context
126
- ),
128
+ statedb.factory.create(itx.address, factory.create({ ...factoryProps, tokens, owner }, context), context),
127
129
 
128
130
  isEmpty(vaultUpdates)
129
131
  ? vaultState
@@ -3,6 +3,7 @@ const Joi = require('@ocap/validator');
3
3
  const { BN } = require('@ocap/util');
4
4
  const { Runner, pipes } = require('@ocap/tx-pipeline');
5
5
  const { account, asset, stake, evidence } = require('@ocap/state');
6
+ const getRelatedAddresses = require('@ocap/util/lib/get-related-addr');
6
7
 
7
8
  // eslint-disable-next-line global-require
8
9
  const debug = require('debug')(`${require('../../../package.json').name}:acquire-asset-v2`);
@@ -26,14 +27,16 @@ runner.use(({ itx }, next) => {
26
27
  return next(error ? new Error('INVALID_TX', `Invalid itx: ${error.message}`) : null);
27
28
  });
28
29
 
29
- // 2. verify stake state
30
+ // 2. verify stake state & sender state
31
+ runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
30
32
  runner.use(pipes.ExtractState({ from: 'itx.address', to: 'stakeState', status: 'INVALID_STAKE_STATE', table: 'stake' })); // prettier-ignore
33
+ runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
31
34
  runner.use(
32
35
  pipes.VerifyInfo([
33
36
  {
34
37
  error: 'SENDER_NOT_MATCH',
35
38
  message: 'You are not allowed to claim stake from this address',
36
- fn: ({ tx, stakeState }) => tx.from === stakeState.sender,
39
+ fn: ({ senderState, stakeState }) => getRelatedAddresses(senderState).includes(stakeState.sender),
37
40
  },
38
41
  ])
39
42
  );
@@ -92,10 +95,8 @@ runner.use(
92
95
  })
93
96
  );
94
97
 
95
- // 6. verify sender & receiver
96
- runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
98
+ // 6. verify receiver states
97
99
  runner.use(pipes.ExtractState({ from: 'receivers', to: 'receiverStates', status: 'INVALID_RECEIVER_STATE', table: 'account' })); // prettier-ignore
98
- runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
99
100
 
100
101
  // 7. verify token state and balance
101
102
  runner.use(pipes.ExtractState({ from: 'tokens', to: 'tokenStates', status: 'INVALID_TOKEN', table: 'token' }));
@@ -147,15 +148,12 @@ runner.use(
147
148
  const { owner, tokens, assets } = x;
148
149
 
149
150
  // Update receiver balance
150
- receiverUpdates[owner] = applyTokenUpdates(
151
- tokens,
152
- receiverStates.find((s) => s.address === owner),
153
- 'add'
154
- );
151
+ const ownerState = receiverStates.find((s) => getRelatedAddresses(s).includes(owner));
152
+ receiverUpdates[ownerState.address] = applyTokenUpdates(tokens, ownerState, 'add');
155
153
 
156
154
  // Update asset owner
157
155
  assets.forEach((a) => {
158
- assetUpdates[a] = { owner };
156
+ assetUpdates[a] = { owner: ownerState.address };
159
157
  });
160
158
 
161
159
  // Update Stake Revoked fields
@@ -2,6 +2,7 @@ const isEmpty = require('empty-value');
2
2
  const { BN } = require('@ocap/util');
3
3
  const { Runner, pipes } = require('@ocap/tx-pipeline');
4
4
  const { account, stake } = require('@ocap/state');
5
+ const getRelatedAddresses = require('@ocap/util/lib/get-related-addr');
5
6
 
6
7
  // eslint-disable-next-line global-require
7
8
  const debug = require('debug')(`${require('../../../package.json').name}:acquire-asset-v2`);
@@ -42,16 +43,19 @@ runner.use(
42
43
  // 3. verify itx size: set hard limit here because more output leads to longer tx execute time
43
44
  runner.use(pipes.VerifyListSize({ listKey: ['outputs', 'receivers', 'tokens', 'assets'] }));
44
45
 
45
- // 4. verify stake state
46
- runner.use(
47
- pipes.ExtractState({ from: 'itx.address', to: 'stakeState', status: 'INVALID_STAKE_STATE', table: 'stake' })
48
- );
46
+ // 4. verify sender & receiver
47
+ runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
48
+ runner.use(pipes.ExtractState({ from: 'receivers', to: 'receiverStates', status: 'INVALID_RECEIVER_STATE', table: 'account' })); // prettier-ignore
49
+ runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
50
+
51
+ // 5. verify stake state
52
+ runner.use(pipes.ExtractState({ from: 'itx.address', to: 'stakeState', status: 'INVALID_STAKE_STATE', table: 'stake' })); // prettier-ignore
49
53
  runner.use(
50
54
  pipes.VerifyInfo([
51
55
  {
52
56
  error: 'SENDER_NOT_MATCH',
53
57
  message: 'You are not allowed to revoke stake from this address',
54
- fn: ({ tx, stakeState }) => tx.from === stakeState.sender,
58
+ fn: ({ senderState, stakeState }) => getRelatedAddresses(senderState).includes(stakeState.sender),
55
59
  },
56
60
  {
57
61
  error: 'STAKE_NOT_REVOCABLE',
@@ -61,15 +65,6 @@ runner.use(
61
65
  ])
62
66
  );
63
67
 
64
- // 5. verify sender & receiver
65
- runner.use(
66
- pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })
67
- );
68
- runner.use(
69
- pipes.ExtractState({ from: 'receivers', to: 'receiverStates', status: 'INVALID_RECEIVER_STATE', table: 'account' })
70
- );
71
- runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
72
-
73
68
  // 6. verify token state and balance
74
69
  runner.use(pipes.ExtractState({ from: 'tokens', to: 'tokenStates', status: 'INVALID_TOKEN', table: 'token' }));
75
70
  runner.use((context, next) => {
@@ -104,8 +99,8 @@ runner.use(
104
99
  const { tx, itx, outputs, statedb, senderState, stakeState } = context;
105
100
 
106
101
  const stakeUpdates = {
107
- tokens: stakeState.tokens,
108
- assets: stakeState.assets,
102
+ tokens: stakeState.tokens || {},
103
+ assets: stakeState.assets || [],
109
104
  revokedTokens: stakeState.revokedTokens || {},
110
105
  revokedAssets: stakeState.revokedAssets || [],
111
106
  };
@@ -66,10 +66,12 @@ runner.use(
66
66
  ])
67
67
  );
68
68
 
69
- // 1. ensure sender & validators exist
69
+ // 1. ensure sender, validators, delegation
70
70
  runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
71
71
  runner.use(pipes.ExtractState({ from: 'seedValidators', to: 'validatorStates', status: 'INVALID_VALIDATOR_STATE', table: 'account' })); // prettier-ignore
72
72
  runner.use(pipes.VerifyAccountMigration({ signerKey: 'validatorStates', senderKey: 'senderState' }));
73
+ runner.use(pipes.ExtractState({ from: 'tx.delegator', to: 'delegatorState', status: 'OK', table: 'account' }));
74
+ runner.use(pipes.VerifyDelegation({ type: 'signature', signerKey: 'senderState', delegatorKey: 'delegatorState' }));
73
75
 
74
76
  // 2. ensure token exist and match
75
77
  runner.use(pipes.ExtractState({ from: 'itx.tokenAddress', to: 'tokenState', status: 'INVALID_TOKEN', table: 'token' }));
@@ -111,7 +113,17 @@ runner.use(ensureTxFee);
111
113
  // 5. create rollup state
112
114
  runner.use(
113
115
  async (context, next) => {
114
- const { tx, formattedItx, rollupData, statedb, senderState, senderUpdates, vaultState, vaultUpdates } = context;
116
+ const {
117
+ tx,
118
+ formattedItx,
119
+ rollupData,
120
+ statedb,
121
+ senderState,
122
+ delegatorState,
123
+ senderUpdates,
124
+ vaultState,
125
+ vaultUpdates,
126
+ } = context;
115
127
 
116
128
  const [newSenderState, rollupState, newVaultState] = await Promise.all([
117
129
  statedb.account.update(
@@ -125,7 +137,7 @@ runner.use(
125
137
  rollup.create(
126
138
  {
127
139
  ...formattedItx,
128
- issuer: senderState.address,
140
+ issuer: delegatorState ? delegatorState.address : senderState.address,
129
141
  validators: formattedItx.seedValidators,
130
142
  data: rollupData,
131
143
  },
@@ -61,6 +61,10 @@ runner.use(
61
61
  runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })); // prettier-ignore
62
62
  runner.use(pipes.VerifyAccountMigration({ senderKey: 'senderState' }));
63
63
 
64
+ // Ensure delegation
65
+ runner.use(pipes.ExtractState({ from: 'tx.delegator', to: 'delegatorState', status: 'OK', table: 'account' }));
66
+ runner.use(pipes.VerifyDelegation({ type: 'signature', signerKey: 'senderState', delegatorKey: 'delegatorState' }));
67
+
64
68
  // Ensure token not exist
65
69
  runner.use(pipes.ExtractState({ from: 'itx.address', to: 'tokenState', table: 'token', status: 'OK' }));
66
70
  runner.use(
@@ -93,34 +97,47 @@ runner.use(ensureTxFee);
93
97
  // Update sender state, token state
94
98
  runner.use(
95
99
  async (context, next) => {
96
- const { tx, itx, statedb, senderState, senderUpdates, vaultState, vaultUpdates } = context;
100
+ const { tx, itx, statedb, senderState, delegatorState, senderUpdates, vaultState, vaultUpdates } = context;
97
101
  const data = decodeAnySafe(itx.data);
102
+ const owner = delegatorState ? delegatorState.address : senderState.address;
98
103
 
99
- // We are definitely creating a different token, so it is safe to set tokens to initial supply
104
+ const delegatorUpdates = {};
100
105
  senderUpdates.tokens = senderUpdates.tokens || {};
101
- senderUpdates.tokens[itx.address] = itx.initialSupply;
102
106
 
103
- const [newSenderState, tokenState, newVaultState] = await Promise.all([
107
+ // We are definitely creating a different token, so it is safe to set tokens to initial supply
108
+ if (delegatorState) {
109
+ delegatorUpdates.tokens = delegatorState.tokens || {};
110
+ delegatorUpdates.tokens[itx.address] = itx.initialSupply;
111
+ } else {
112
+ senderUpdates.tokens[itx.address] = itx.initialSupply;
113
+ }
114
+
115
+ const [newSenderState, tokenState, newVaultState, newDelegatorState] = await Promise.all([
104
116
  statedb.account.update(
105
117
  senderState.address,
106
118
  account.update(senderState, { nonce: tx.nonce, pk: tx.pk, ...senderUpdates }, context),
107
119
  context
108
120
  ),
109
121
 
110
- statedb.token.create(
111
- itx.address,
112
- token.create({ ...cloneDeep(itx), data, issuer: senderState.address }, context),
113
- context
114
- ),
122
+ statedb.token.create(itx.address, token.create({ ...cloneDeep(itx), data, issuer: owner }, context), context),
115
123
 
116
124
  isEmpty(vaultUpdates)
117
125
  ? vaultState
118
126
  : statedb.account.update(vaultState.address, account.update(vaultState, vaultUpdates, context), context),
127
+
128
+ delegatorState
129
+ ? statedb.account.update(
130
+ delegatorState.address,
131
+ account.update(delegatorState, delegatorUpdates, context),
132
+ context
133
+ )
134
+ : null,
119
135
  ]);
120
136
 
121
137
  context.senderState = newSenderState;
122
138
  context.tokenState = tokenState;
123
139
  context.vaultState = newVaultState;
140
+ context.delegatorState = newDelegatorState;
124
141
 
125
142
  debug('create token v2', tokenState);
126
143
 
@@ -6,6 +6,7 @@ const isEqual = require('lodash/isEqual');
6
6
  const { BN } = require('@ocap/util');
7
7
  const { Runner, pipes } = require('@ocap/tx-pipeline');
8
8
  const { account, asset } = require('@ocap/state');
9
+ const getRelatedAddresses = require('@ocap/util/lib/get-related-addr');
9
10
 
10
11
  // eslint-disable-next-line global-require
11
12
  const debug = require('debug')(`${require('../../../package.json').name}:transfer-v2`);
@@ -163,20 +164,13 @@ runner.use(
163
164
  });
164
165
 
165
166
  const receiverUpdates = {};
166
- outputs.forEach((x) => {
167
- const { owner, tokensList } = x;
168
- receiverUpdates[owner] = applyTokenUpdates(
169
- tokensList,
170
- receiverStates.find((s) => s.address === owner) || {},
171
- 'add'
172
- );
173
- });
174
-
175
167
  const assetUpdates = {};
176
168
  outputs.forEach((x) => {
177
- const { owner, assetsList } = x;
169
+ const { owner, tokensList, assetsList } = x;
170
+ const ownerState = receiverStates.find((s) => getRelatedAddresses(s).includes(owner)) || { address: owner };
171
+ receiverUpdates[ownerState.address] = applyTokenUpdates(tokensList, ownerState, 'add');
178
172
  assetsList.forEach((address) => {
179
- assetUpdates[address] = { owner };
173
+ assetUpdates[address] = { owner: ownerState.address };
180
174
  });
181
175
  });
182
176
 
@@ -213,10 +207,11 @@ runner.use(
213
207
  receivers
214
208
  .filter((x) => x !== senderState.address)
215
209
  .map((x) => {
216
- const receiverState = receiverStates.find((s) => s.address === x);
210
+ const receiverState = receiverStates.find((s) => getRelatedAddresses(s).includes(x));
211
+ const owner = receiverState ? receiverState.address : x;
217
212
  return statedb.account.updateOrCreate(
218
213
  receiverState,
219
- account.updateOrCreate(receiverState, { ...receiverUpdates[x], address: x }, context),
214
+ account.updateOrCreate(receiverState, { ...receiverUpdates[owner], address: owner }, context),
220
215
  context
221
216
  );
222
217
  })
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.13.79",
6
+ "version": "1.13.83",
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.79",
23
- "@arcblock/did-util": "1.13.79",
24
- "@ocap/asset": "1.13.79",
25
- "@ocap/mcrypto": "1.13.79",
26
- "@ocap/merkle-tree": "1.13.79",
27
- "@ocap/message": "1.13.79",
28
- "@ocap/state": "1.13.79",
29
- "@ocap/tx-pipeline": "1.13.79",
30
- "@ocap/util": "1.13.79",
31
- "@ocap/validator": "1.13.79",
32
- "@ocap/wallet": "1.13.79",
22
+ "@arcblock/did": "1.13.83",
23
+ "@arcblock/did-util": "1.13.83",
24
+ "@ocap/asset": "1.13.83",
25
+ "@ocap/mcrypto": "1.13.83",
26
+ "@ocap/merkle-tree": "1.13.83",
27
+ "@ocap/message": "1.13.83",
28
+ "@ocap/state": "1.13.83",
29
+ "@ocap/tx-pipeline": "1.13.83",
30
+ "@ocap/util": "1.13.83",
31
+ "@ocap/validator": "1.13.83",
32
+ "@ocap/wallet": "1.13.83",
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": "e349a68b05ae8c6975517c8b43c66f9120a9b99f"
45
+ "gitHead": "b92092e3f7347720e34f061844fdf6b49cbfca88"
46
46
  }