@ocap/tx-protocols 1.28.9 → 1.29.1

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 (284) hide show
  1. package/esm/execute.d.mts +53 -0
  2. package/esm/execute.mjs +225 -0
  3. package/esm/index.d.mts +95 -0
  4. package/esm/index.mjs +100 -0
  5. package/esm/pipes/ensure-cost.d.mts +18 -0
  6. package/esm/pipes/ensure-cost.mjs +136 -0
  7. package/esm/pipes/ensure-gas.d.mts +14 -0
  8. package/esm/pipes/ensure-gas.mjs +38 -0
  9. package/esm/protocols/account/delegate.d.mts +4 -0
  10. package/esm/protocols/account/delegate.mjs +195 -0
  11. package/esm/protocols/account/migrate.d.mts +4 -0
  12. package/esm/protocols/account/migrate.mjs +130 -0
  13. package/esm/protocols/account/revoke-delegate.d.mts +4 -0
  14. package/esm/protocols/account/revoke-delegate.mjs +102 -0
  15. package/esm/protocols/asset/acquire-v2.d.mts +9 -0
  16. package/esm/protocols/asset/acquire-v2.mjs +213 -0
  17. package/esm/protocols/asset/acquire-v3.d.mts +17 -0
  18. package/esm/protocols/asset/acquire-v3.mjs +265 -0
  19. package/esm/protocols/asset/calls/transfer-token.d.mts +4 -0
  20. package/esm/protocols/asset/calls/transfer-token.mjs +36 -0
  21. package/esm/protocols/asset/calls/transfer.d.mts +4 -0
  22. package/esm/protocols/asset/calls/transfer.mjs +32 -0
  23. package/esm/protocols/asset/consume.d.mts +4 -0
  24. package/esm/protocols/asset/consume.mjs +92 -0
  25. package/esm/protocols/asset/create.d.mts +4 -0
  26. package/esm/protocols/asset/create.mjs +136 -0
  27. package/esm/protocols/asset/mint.d.mts +4 -0
  28. package/esm/protocols/asset/mint.mjs +156 -0
  29. package/esm/protocols/asset/pipes/exec-mint-hook.d.mts +24 -0
  30. package/esm/protocols/asset/pipes/exec-mint-hook.mjs +54 -0
  31. package/esm/protocols/asset/pipes/extract-factory-tokens.d.mts +21 -0
  32. package/esm/protocols/asset/pipes/extract-factory-tokens.mjs +22 -0
  33. package/esm/protocols/asset/pipes/verify-itx-address.d.mts +32 -0
  34. package/esm/protocols/asset/pipes/verify-itx-address.mjs +56 -0
  35. package/esm/protocols/asset/pipes/verify-itx-assets.d.mts +18 -0
  36. package/esm/protocols/asset/pipes/verify-itx-assets.mjs +27 -0
  37. package/esm/protocols/asset/pipes/verify-itx-variables.d.mts +17 -0
  38. package/esm/protocols/asset/pipes/verify-itx-variables.mjs +20 -0
  39. package/esm/protocols/asset/pipes/verify-mint-limit.d.mts +15 -0
  40. package/esm/protocols/asset/pipes/verify-mint-limit.mjs +14 -0
  41. package/esm/protocols/asset/update.d.mts +4 -0
  42. package/esm/protocols/asset/update.mjs +111 -0
  43. package/esm/protocols/factory/create.d.mts +29 -0
  44. package/esm/protocols/factory/create.mjs +155 -0
  45. package/esm/protocols/governance/claim-stake.d.mts +27 -0
  46. package/esm/protocols/governance/claim-stake.mjs +220 -0
  47. package/esm/protocols/governance/return-stake.d.mts +27 -0
  48. package/esm/protocols/governance/return-stake.mjs +211 -0
  49. package/esm/protocols/governance/revoke-stake.d.mts +27 -0
  50. package/esm/protocols/governance/revoke-stake.mjs +178 -0
  51. package/esm/protocols/governance/slash-stake.d.mts +17 -0
  52. package/esm/protocols/governance/slash-stake.mjs +213 -0
  53. package/esm/protocols/governance/stake.d.mts +15 -0
  54. package/esm/protocols/governance/stake.mjs +270 -0
  55. package/esm/protocols/rollup/claim-reward.d.mts +11 -0
  56. package/esm/protocols/rollup/claim-reward.mjs +322 -0
  57. package/esm/protocols/rollup/close.d.mts +4 -0
  58. package/esm/protocols/rollup/close.mjs +105 -0
  59. package/esm/protocols/rollup/create-block.d.mts +11 -0
  60. package/esm/protocols/rollup/create-block.mjs +303 -0
  61. package/esm/protocols/rollup/create.d.mts +4 -0
  62. package/esm/protocols/rollup/create.mjs +164 -0
  63. package/esm/protocols/rollup/join.d.mts +4 -0
  64. package/esm/protocols/rollup/join.mjs +152 -0
  65. package/esm/protocols/rollup/leave.d.mts +4 -0
  66. package/esm/protocols/rollup/leave.mjs +137 -0
  67. package/esm/protocols/rollup/migrate.d.mts +4 -0
  68. package/esm/protocols/rollup/migrate.mjs +85 -0
  69. package/esm/protocols/rollup/pause.d.mts +4 -0
  70. package/esm/protocols/rollup/pause.mjs +76 -0
  71. package/esm/protocols/rollup/pipes/ensure-validator.d.mts +6 -0
  72. package/esm/protocols/rollup/pipes/ensure-validator.mjs +12 -0
  73. package/esm/protocols/rollup/pipes/verify-evidence.d.mts +15 -0
  74. package/esm/protocols/rollup/pipes/verify-evidence.mjs +29 -0
  75. package/esm/protocols/rollup/pipes/verify-signers.d.mts +15 -0
  76. package/esm/protocols/rollup/pipes/verify-signers.mjs +36 -0
  77. package/esm/protocols/rollup/pipes/verify-status.d.mts +13 -0
  78. package/esm/protocols/rollup/pipes/verify-status.mjs +26 -0
  79. package/esm/protocols/rollup/resume.d.mts +4 -0
  80. package/esm/protocols/rollup/resume.mjs +79 -0
  81. package/esm/protocols/rollup/update.d.mts +4 -0
  82. package/esm/protocols/rollup/update.mjs +111 -0
  83. package/esm/protocols/token/create.d.mts +4 -0
  84. package/esm/protocols/token/create.mjs +150 -0
  85. package/esm/protocols/token/deposit-v2.d.mts +11 -0
  86. package/esm/protocols/token/deposit-v2.mjs +216 -0
  87. package/esm/protocols/token/withdraw-v2.d.mts +9 -0
  88. package/esm/protocols/token/withdraw-v2.mjs +222 -0
  89. package/esm/protocols/token-factory/burn.d.mts +15 -0
  90. package/esm/protocols/token-factory/burn.mjs +233 -0
  91. package/esm/protocols/token-factory/create.d.mts +4 -0
  92. package/esm/protocols/token-factory/create.mjs +254 -0
  93. package/esm/protocols/token-factory/mint.d.mts +15 -0
  94. package/esm/protocols/token-factory/mint.mjs +234 -0
  95. package/esm/protocols/token-factory/pipes/calc-reserve.d.mts +21 -0
  96. package/esm/protocols/token-factory/pipes/calc-reserve.mjs +34 -0
  97. package/esm/protocols/token-factory/pipes/verify-icon.d.mts +14 -0
  98. package/esm/protocols/token-factory/pipes/verify-icon.mjs +18 -0
  99. package/esm/protocols/token-factory/pipes/verify-ownership.d.mts +12 -0
  100. package/esm/protocols/token-factory/pipes/verify-ownership.mjs +63 -0
  101. package/esm/protocols/token-factory/pipes/verify-url.d.mts +12 -0
  102. package/esm/protocols/token-factory/pipes/verify-url.mjs +26 -0
  103. package/esm/protocols/token-factory/update.d.mts +10 -0
  104. package/esm/protocols/token-factory/update.mjs +152 -0
  105. package/esm/protocols/trade/exchange-v2.d.mts +9 -0
  106. package/esm/protocols/trade/exchange-v2.mjs +239 -0
  107. package/esm/protocols/trade/transfer-v2.d.mts +9 -0
  108. package/esm/protocols/trade/transfer-v2.mjs +226 -0
  109. package/esm/protocols/trade/transfer-v3.d.mts +17 -0
  110. package/esm/protocols/trade/transfer-v3.mjs +270 -0
  111. package/esm/util.d.mts +141 -0
  112. package/esm/util.mjs +278 -0
  113. package/lib/_virtual/rolldown_runtime.cjs +29 -0
  114. package/lib/execute.cjs +231 -0
  115. package/lib/execute.d.cts +53 -0
  116. package/lib/index.cjs +105 -0
  117. package/lib/index.d.cts +95 -0
  118. package/lib/pipes/ensure-cost.cjs +141 -0
  119. package/lib/pipes/ensure-cost.d.cts +18 -0
  120. package/lib/pipes/ensure-gas.cjs +41 -0
  121. package/lib/pipes/ensure-gas.d.cts +14 -0
  122. package/lib/protocols/account/delegate.cjs +201 -0
  123. package/lib/protocols/account/delegate.d.cts +4 -0
  124. package/lib/protocols/account/migrate.cjs +135 -0
  125. package/lib/protocols/account/migrate.d.cts +4 -0
  126. package/lib/protocols/account/revoke-delegate.cjs +107 -0
  127. package/lib/protocols/account/revoke-delegate.d.cts +4 -0
  128. package/lib/protocols/asset/acquire-v2.cjs +216 -0
  129. package/lib/protocols/asset/acquire-v2.d.cts +9 -0
  130. package/lib/protocols/asset/acquire-v3.cjs +269 -0
  131. package/lib/protocols/asset/acquire-v3.d.cts +17 -0
  132. package/lib/protocols/asset/calls/transfer-token.cjs +40 -0
  133. package/lib/protocols/asset/calls/transfer-token.d.cts +4 -0
  134. package/lib/protocols/asset/calls/transfer.cjs +35 -0
  135. package/lib/protocols/asset/calls/transfer.d.cts +4 -0
  136. package/lib/protocols/asset/consume.cjs +95 -0
  137. package/lib/protocols/asset/consume.d.cts +4 -0
  138. package/lib/protocols/asset/create.cjs +140 -0
  139. package/lib/protocols/asset/create.d.cts +4 -0
  140. package/lib/protocols/asset/mint.cjs +159 -0
  141. package/lib/protocols/asset/mint.d.cts +4 -0
  142. package/lib/protocols/asset/pipes/exec-mint-hook.cjs +57 -0
  143. package/lib/protocols/asset/pipes/exec-mint-hook.d.cts +24 -0
  144. package/lib/protocols/asset/pipes/extract-factory-tokens.cjs +25 -0
  145. package/lib/protocols/asset/pipes/extract-factory-tokens.d.cts +21 -0
  146. package/lib/protocols/asset/pipes/verify-itx-address.cjs +59 -0
  147. package/lib/protocols/asset/pipes/verify-itx-address.d.cts +32 -0
  148. package/lib/protocols/asset/pipes/verify-itx-assets.cjs +29 -0
  149. package/lib/protocols/asset/pipes/verify-itx-assets.d.cts +18 -0
  150. package/lib/protocols/asset/pipes/verify-itx-variables.cjs +22 -0
  151. package/lib/protocols/asset/pipes/verify-itx-variables.d.cts +17 -0
  152. package/lib/protocols/asset/pipes/verify-mint-limit.cjs +16 -0
  153. package/lib/protocols/asset/pipes/verify-mint-limit.d.cts +15 -0
  154. package/lib/protocols/asset/update.cjs +114 -0
  155. package/lib/protocols/asset/update.d.cts +4 -0
  156. package/lib/protocols/factory/create.cjs +161 -0
  157. package/lib/protocols/factory/create.d.cts +29 -0
  158. package/lib/protocols/governance/claim-stake.cjs +223 -0
  159. package/lib/protocols/governance/claim-stake.d.cts +27 -0
  160. package/lib/protocols/governance/return-stake.cjs +215 -0
  161. package/lib/protocols/governance/return-stake.d.cts +27 -0
  162. package/lib/protocols/governance/revoke-stake.cjs +182 -0
  163. package/lib/protocols/governance/revoke-stake.d.cts +27 -0
  164. package/lib/protocols/governance/slash-stake.cjs +217 -0
  165. package/lib/protocols/governance/slash-stake.d.cts +17 -0
  166. package/lib/protocols/governance/stake.cjs +275 -0
  167. package/lib/protocols/governance/stake.d.cts +15 -0
  168. package/lib/protocols/rollup/claim-reward.cjs +328 -0
  169. package/lib/protocols/rollup/claim-reward.d.cts +11 -0
  170. package/lib/protocols/rollup/close.cjs +107 -0
  171. package/lib/protocols/rollup/close.d.cts +4 -0
  172. package/lib/protocols/rollup/create-block.cjs +309 -0
  173. package/lib/protocols/rollup/create-block.d.cts +11 -0
  174. package/lib/protocols/rollup/create.cjs +169 -0
  175. package/lib/protocols/rollup/create.d.cts +4 -0
  176. package/lib/protocols/rollup/join.cjs +157 -0
  177. package/lib/protocols/rollup/join.d.cts +4 -0
  178. package/lib/protocols/rollup/leave.cjs +141 -0
  179. package/lib/protocols/rollup/leave.d.cts +4 -0
  180. package/lib/protocols/rollup/migrate.cjs +87 -0
  181. package/lib/protocols/rollup/migrate.d.cts +4 -0
  182. package/lib/protocols/rollup/pause.cjs +78 -0
  183. package/lib/protocols/rollup/pause.d.cts +4 -0
  184. package/lib/protocols/rollup/pipes/ensure-validator.cjs +14 -0
  185. package/lib/protocols/rollup/pipes/ensure-validator.d.cts +6 -0
  186. package/lib/protocols/rollup/pipes/verify-evidence.cjs +32 -0
  187. package/lib/protocols/rollup/pipes/verify-evidence.d.cts +15 -0
  188. package/lib/protocols/rollup/pipes/verify-signers.cjs +39 -0
  189. package/lib/protocols/rollup/pipes/verify-signers.d.cts +15 -0
  190. package/lib/protocols/rollup/pipes/verify-status.cjs +28 -0
  191. package/lib/protocols/rollup/pipes/verify-status.d.cts +13 -0
  192. package/lib/protocols/rollup/resume.cjs +81 -0
  193. package/lib/protocols/rollup/resume.d.cts +4 -0
  194. package/lib/protocols/rollup/update.cjs +114 -0
  195. package/lib/protocols/rollup/update.d.cts +4 -0
  196. package/lib/protocols/token/create.cjs +156 -0
  197. package/lib/protocols/token/create.d.cts +4 -0
  198. package/lib/protocols/token/deposit-v2.cjs +219 -0
  199. package/lib/protocols/token/deposit-v2.d.cts +11 -0
  200. package/lib/protocols/token/withdraw-v2.cjs +225 -0
  201. package/lib/protocols/token/withdraw-v2.d.cts +9 -0
  202. package/lib/protocols/token-factory/burn.cjs +236 -0
  203. package/lib/protocols/token-factory/burn.d.cts +15 -0
  204. package/lib/protocols/token-factory/create.cjs +260 -0
  205. package/lib/protocols/token-factory/create.d.cts +4 -0
  206. package/lib/protocols/token-factory/mint.cjs +237 -0
  207. package/lib/protocols/token-factory/mint.d.cts +15 -0
  208. package/lib/protocols/token-factory/pipes/calc-reserve.cjs +38 -0
  209. package/lib/protocols/token-factory/pipes/calc-reserve.d.cts +21 -0
  210. package/lib/protocols/token-factory/pipes/verify-icon.cjs +22 -0
  211. package/lib/protocols/token-factory/pipes/verify-icon.d.cts +14 -0
  212. package/lib/protocols/token-factory/pipes/verify-ownership.cjs +66 -0
  213. package/lib/protocols/token-factory/pipes/verify-ownership.d.cts +12 -0
  214. package/lib/protocols/token-factory/pipes/verify-url.cjs +29 -0
  215. package/lib/protocols/token-factory/pipes/verify-url.d.cts +12 -0
  216. package/lib/protocols/token-factory/update.cjs +155 -0
  217. package/lib/protocols/token-factory/update.d.cts +10 -0
  218. package/lib/protocols/trade/exchange-v2.cjs +243 -0
  219. package/lib/protocols/trade/exchange-v2.d.cts +9 -0
  220. package/lib/protocols/trade/transfer-v2.cjs +229 -0
  221. package/lib/protocols/trade/transfer-v2.d.cts +9 -0
  222. package/lib/protocols/trade/transfer-v3.cjs +274 -0
  223. package/lib/protocols/trade/transfer-v3.d.cts +17 -0
  224. package/lib/util.cjs +296 -0
  225. package/lib/util.d.cts +141 -0
  226. package/package.json +49 -22
  227. package/tools/fixtures.ts +564 -0
  228. package/lib/execute.js +0 -254
  229. package/lib/index.js +0 -117
  230. package/lib/pipes/ensure-cost.js +0 -193
  231. package/lib/pipes/ensure-gas.js +0 -48
  232. package/lib/protocols/account/delegate.js +0 -223
  233. package/lib/protocols/account/migrate.js +0 -153
  234. package/lib/protocols/account/revoke-delegate.js +0 -110
  235. package/lib/protocols/asset/acquire-v2.js +0 -262
  236. package/lib/protocols/asset/acquire-v3.js +0 -330
  237. package/lib/protocols/asset/calls/README.md +0 -5
  238. package/lib/protocols/asset/calls/transfer-token.js +0 -36
  239. package/lib/protocols/asset/calls/transfer.js +0 -28
  240. package/lib/protocols/asset/consume.js +0 -105
  241. package/lib/protocols/asset/create.js +0 -151
  242. package/lib/protocols/asset/mint.js +0 -199
  243. package/lib/protocols/asset/pipes/exec-mint-hook.js +0 -62
  244. package/lib/protocols/asset/pipes/extract-factory-tokens.js +0 -18
  245. package/lib/protocols/asset/pipes/verify-itx-address.js +0 -54
  246. package/lib/protocols/asset/pipes/verify-itx-assets.js +0 -51
  247. package/lib/protocols/asset/pipes/verify-itx-variables.js +0 -26
  248. package/lib/protocols/asset/pipes/verify-mint-limit.js +0 -13
  249. package/lib/protocols/asset/update.js +0 -131
  250. package/lib/protocols/factory/create.js +0 -191
  251. package/lib/protocols/governance/claim-stake.js +0 -266
  252. package/lib/protocols/governance/return-stake.js +0 -248
  253. package/lib/protocols/governance/revoke-stake.js +0 -172
  254. package/lib/protocols/governance/slash-stake.js +0 -271
  255. package/lib/protocols/governance/stake.js +0 -303
  256. package/lib/protocols/rollup/claim-reward.js +0 -342
  257. package/lib/protocols/rollup/close.js +0 -104
  258. package/lib/protocols/rollup/create-block.js +0 -413
  259. package/lib/protocols/rollup/create.js +0 -197
  260. package/lib/protocols/rollup/join.js +0 -182
  261. package/lib/protocols/rollup/leave.js +0 -145
  262. package/lib/protocols/rollup/migrate.js +0 -85
  263. package/lib/protocols/rollup/pause.js +0 -75
  264. package/lib/protocols/rollup/pipes/ensure-validator.js +0 -12
  265. package/lib/protocols/rollup/pipes/verify-evidence.js +0 -37
  266. package/lib/protocols/rollup/pipes/verify-signers.js +0 -87
  267. package/lib/protocols/rollup/pipes/verify-status.js +0 -30
  268. package/lib/protocols/rollup/resume.js +0 -75
  269. package/lib/protocols/rollup/update.js +0 -122
  270. package/lib/protocols/token/create.js +0 -199
  271. package/lib/protocols/token/deposit-v2.js +0 -290
  272. package/lib/protocols/token/withdraw-v2.js +0 -305
  273. package/lib/protocols/token-factory/burn.js +0 -371
  274. package/lib/protocols/token-factory/create.js +0 -342
  275. package/lib/protocols/token-factory/mint.js +0 -385
  276. package/lib/protocols/token-factory/pipes/calc-reserve.js +0 -37
  277. package/lib/protocols/token-factory/pipes/verify-icon.js +0 -27
  278. package/lib/protocols/token-factory/pipes/verify-ownership.js +0 -93
  279. package/lib/protocols/token-factory/pipes/verify-url.js +0 -32
  280. package/lib/protocols/token-factory/update.js +0 -208
  281. package/lib/protocols/trade/exchange-v2.js +0 -239
  282. package/lib/protocols/trade/transfer-v2.js +0 -233
  283. package/lib/protocols/trade/transfer-v3.js +0 -333
  284. package/lib/util.js +0 -442
@@ -1,303 +0,0 @@
1
- const pick = require('lodash/pick');
2
- const { promisify } = require('node:util');
3
- const isEmpty = require('empty-value');
4
- const { Joi, schemas } = require('@arcblock/validator');
5
- const { CustomError: Error } = require('@ocap/util/lib/error');
6
- const { BN, fromTokenToUnit } = require('@ocap/util');
7
- const { Runner, pipes } = require('@ocap/tx-pipeline');
8
- const { toStakeAddress } = require('@arcblock/did-util');
9
- const { account, asset, stake } = require('@ocap/state');
10
-
11
- const debug = require('debug')(`${require('../../../package.json').name}:stake`);
12
-
13
- const { applyTokenUpdates, applyTokenChange, isGasStakeAddress, isGasStakeInput } = require('../../util');
14
-
15
- const EnsureTxGas = require('../../pipes/ensure-gas');
16
- const EnsureTxCost = require('../../pipes/ensure-cost');
17
-
18
- const verifyAssetOwner = promisify(pipes.VerifyUpdater({ assetKey: 'assets', ownerKey: 'owner' }));
19
-
20
- const runner = new Runner();
21
-
22
- // 0. verify itx
23
- const schema = Joi.object({
24
- address: Joi.DID().prefix().role('ROLE_STAKE').required(),
25
- receiver: Joi.DID().prefix().required(),
26
- slashersList: Joi.array().items(Joi.DID().prefix()).default([]),
27
- locked: Joi.boolean().default(false),
28
- inputsList: schemas.multiInput.min(1).required(),
29
- message: Joi.string().trim().min(1).max(256).required(),
30
- revokeWaitingPeriod: Joi.number().integer().min(0).default(0),
31
- data: Joi.any().optional().allow(null),
32
- nonce: Joi.string().trim().min(1).max(256).allow('').optional().allow(null),
33
- }).options({ stripUnknown: true, noDefaults: false });
34
- runner.use(({ itx }, next) => {
35
- const { error } = schema.validate(itx);
36
- return next(error ? new Error('INVALID_TX', `Invalid itx: ${error.message}`) : null);
37
- });
38
- runner.use(
39
- pipes.VerifyTxInput({
40
- fieldKey: 'itx.inputs',
41
- inputsKey: 'inputs',
42
- sendersKey: 'senders',
43
- tokensKey: 'tokens',
44
- assetsKey: 'assets',
45
- })
46
- );
47
-
48
- // 1. verify itx address
49
- runner.use(
50
- pipes.VerifyInfo([
51
- {
52
- error: 'INVALID_TX',
53
- message: 'Invalid staking address',
54
- fn: ({ tx, itx }) => toStakeAddress(tx.from, itx.receiver, itx.nonce) === itx.address,
55
- },
56
- {
57
- error: 'INVALID_TX',
58
- message: 'Tx sender can not be slasher',
59
- fn: ({ tx, itx }) => itx.slashersList.length === 0 || itx.slashersList.includes(tx.from) === false,
60
- },
61
- {
62
- error: 'INSUFFICIENT_DATA',
63
- message: 'Can not stake without any token or asset',
64
- fn: ({ assets, tokens }) => !(isEmpty(tokens) && isEmpty(assets)),
65
- },
66
- ])
67
- );
68
-
69
- // 2. verify itx size: set hard limit here because more inputs leads to longer tx execute time
70
- runner.use(pipes.VerifyListSize({ listKey: ['inputs', 'senders', 'tokens', 'assets'] }));
71
-
72
- // 3. verify multi sig
73
- runner.use(pipes.VerifyMultiSigV2({ signersKey: 'senders' }));
74
-
75
- // 4. verify against state
76
- runner.use(pipes.ExtractState({ from: 'itx.address', to: 'stakeState', status: 'OK', table: 'stake' }));
77
-
78
- // 5. verify sender & signer & receiver
79
- runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'OK', table: 'account' }));
80
- runner.use(
81
- pipes.ExtractState({ from: 'senders', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })
82
- );
83
- runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', stateKey: 'senderState', addressKey: 'tx.from' }));
84
- runner.use(pipes.ExtractState({ from: 'itx.receiver', to: 'receiverState', status: 'INVALID_RECEIVER_STATE' })); // can by any type
85
- runner.use(pipes.VerifyBlocked({ stateKeys: ['signerStates', 'receiverState'] }));
86
- runner.use(pipes.VerifyAccountMigration({ stateKey: 'receiverState', addressKey: 'itx.receiver' }));
87
-
88
- // 6. verify token state and balance
89
- runner.use(pipes.ExtractState({ from: 'tokens', to: 'tokenStates', status: 'INVALID_TOKEN', table: 'token' }));
90
- runner.use(pipes.VerifyTokenBalance({ ownerKey: 'signerStates', conditionKey: 'inputs' }));
91
-
92
- // verify token spenders
93
- runner.use(
94
- pipes.verifyTokenAccess({
95
- statesKey: 'tokenStates',
96
- listFieldKey: 'spenders',
97
- accountKeys: ['senderState'],
98
- errorMessage: 'Account {address} is not allowed to stake token {tokenAddress}',
99
- })
100
- );
101
- // 7. verify asset state and ownership
102
- runner.use(pipes.ExtractState({ from: 'assets', to: 'assetStates', status: 'OK', table: 'asset' }));
103
- runner.use(pipes.VerifyTransferrable({ assets: 'assetStates' }));
104
- runner.use(async (context, next) => {
105
- const { inputs, assetStates = [], signerStates } = context;
106
- for (const input of inputs) {
107
- const { owner, assetsList } = input;
108
- const states = assetStates.filter((x) => assetsList.includes(x.address));
109
- const signer = signerStates.find((x) => x.address === owner);
110
-
111
- try {
112
- await verifyAssetOwner({ assets: states, owner: signer });
113
- } catch (err) {
114
- return next(err);
115
- }
116
- }
117
-
118
- return next();
119
- });
120
-
121
- // ensure slashers exist and not migrated
122
- runner.use(
123
- pipes.ExtractState({
124
- from: 'itx.slashersList',
125
- to: 'slasherStates',
126
- status: 'INVALID_SLASHER_STATE',
127
- table: 'account',
128
- })
129
- );
130
- runner.use(pipes.VerifyAccountMigration({ stateKey: 'slasherStates', addressKey: 'itx.slashersList' }));
131
-
132
- // 8. handle tx gas stakes
133
- runner.use((context, next) => {
134
- const { tx, itx, inputs, config } = context;
135
- const { token, transaction } = config;
136
- const { minStake, maxStake } = transaction.txGas;
137
-
138
- context.isGasStake = isGasStakeAddress(tx.from, itx.address) && isGasStakeInput(inputs, token.address);
139
- if (context.isGasStake) {
140
- const [tokenInput] = inputs[0].tokensList;
141
- const actualStake = new BN(tokenInput.value);
142
- const expectedMinStake = fromTokenToUnit(minStake, token.decimal);
143
- const expectedMaxStake = fromTokenToUnit(maxStake, token.decimal);
144
- if (actualStake.lt(expectedMinStake)) {
145
- return next(new Error('INVALID_TX', `Stake for gas should be greater than: ${minStake}`));
146
- }
147
- if (actualStake.gt(expectedMaxStake)) {
148
- return next(new Error('INVALID_TX', `Stake for gas should be less than: ${maxStake}`));
149
- }
150
- }
151
-
152
- if (context.isGasStake) {
153
- context.revokeWaitingPeriod = transaction.txGas.stakeLockPeriod;
154
- context.slashers = [config.moderator.address];
155
- } else {
156
- context.revokeWaitingPeriod = itx.revokeWaitingPeriod;
157
- context.slashers = itx.slashersList;
158
- }
159
-
160
- return next();
161
- });
162
-
163
- // Ensure tx fee and gas
164
- runner.use(
165
- EnsureTxGas((context) => {
166
- const result = { create: 0, update: 0, payment: 0 };
167
-
168
- // Do not charge tx fee for self stake: https://github.com/ArcBlock/arc-wallet-ios/issues/4005
169
- const sender = context.senderState ? context.senderState.address : context.tx.from;
170
- const receiver = context.receiverState ? context.receiverState.address : context.itx.receiver;
171
- if (sender === receiver) {
172
- Object.defineProperty(context, 'txBaseGas', { value: false });
173
- return result;
174
- }
175
-
176
- if (context.senderState) {
177
- result.update += 1;
178
- } else {
179
- result.create += 1;
180
- }
181
- if (context.stakeState) {
182
- result.update += 1;
183
- } else {
184
- result.create += 1;
185
- }
186
- if (context.signerStates) {
187
- result.update += context.signerStates.length;
188
- }
189
- if (context.assetStates) {
190
- result.update += context.assetStates.length;
191
- }
192
-
193
- return result;
194
- })
195
- );
196
- runner.use(EnsureTxCost({ attachSenderChanges: true }));
197
-
198
- // Save context snapshot before updating states
199
- runner.use(pipes.TakeStateSnapshot());
200
-
201
- // update statedb
202
- runner.use(
203
- async (context, next) => {
204
- const {
205
- tx,
206
- itx,
207
- inputs,
208
- statedb,
209
- senderState,
210
- senderChange,
211
- stakeState,
212
- signerStates,
213
- updateVaults,
214
- assetStates = [],
215
- } = context;
216
-
217
- const signerUpdates = {};
218
- const stakeUpdates = stakeState
219
- ? { tokens: stakeState.tokens, assets: stakeState.assets, data: itx.data }
220
- : { tokens: {}, assets: [], data: itx.data };
221
-
222
- inputs.forEach((x) => {
223
- const { owner, tokensList, assetsList } = x;
224
- signerUpdates[owner] = applyTokenUpdates(
225
- tokensList,
226
- signerStates.find((s) => s.address === owner),
227
- 'sub'
228
- );
229
- if (senderChange && owner === senderChange.address) {
230
- signerUpdates[owner] = applyTokenChange(signerUpdates[owner], senderChange);
231
- }
232
- Object.assign(stakeUpdates, applyTokenUpdates(tokensList, stakeUpdates, 'add'));
233
- stakeUpdates.assets.push(...assetsList);
234
- });
235
-
236
- const isAlsoSigner = !!signerUpdates[tx.from];
237
-
238
- const [newSenderState, newSignerStates, newStakeState, newAssetStates] = await Promise.all([
239
- // Update sender state
240
- statedb.account.updateOrCreate(
241
- senderState,
242
- account.updateOrCreate(
243
- senderState,
244
- Object.assign(
245
- { address: tx.from, nonce: tx.nonce, pk: tx.pk },
246
- signerUpdates[tx.from] || (senderChange ? applyTokenChange(senderState, senderChange) : {})
247
- ),
248
- context
249
- ),
250
- context
251
- ),
252
-
253
- // Update signer state
254
- Promise.all(
255
- signerStates
256
- .filter((x) => x.address !== tx.from)
257
- .map((x) => statedb.account.update(x.address, account.update(x, signerUpdates[x.address], context), context))
258
- ),
259
-
260
- // Update/create stake state
261
- stakeState
262
- ? statedb.stake.update(stakeState.address, stake.update(stakeState, stakeUpdates, context), context)
263
- : statedb.stake.create(
264
- itx.address,
265
- stake.create(
266
- {
267
- sender: tx.from,
268
- revocable: !itx.locked,
269
- slashers: context.slashers,
270
- revokeWaitingPeriod: context.revokeWaitingPeriod,
271
- ...pick(itx, ['address', 'receiver', 'message', 'data', 'nonce']),
272
- ...stakeUpdates,
273
- },
274
- context
275
- ),
276
- context
277
- ),
278
-
279
- // Transfer assets to staking account
280
- Promise.all(
281
- assetStates.map((x) =>
282
- statedb.asset.update(x.address, asset.update(x, { owner: itx.address }, context), context)
283
- )
284
- ),
285
- ]);
286
-
287
- await updateVaults();
288
-
289
- context.senderState = newSenderState;
290
- context.signerStates = isAlsoSigner ? newSignerStates.concat(newSenderState) : newSignerStates;
291
- context.stakeState = newStakeState;
292
- context.assetStates = newAssetStates;
293
-
294
- debug('stake', { address: itx.address, stakeUpdates, signerUpdates });
295
-
296
- next();
297
- },
298
- { persistError: true }
299
- );
300
-
301
- runner.use(pipes.VerifyStateDiff());
302
-
303
- module.exports = runner;
@@ -1,342 +0,0 @@
1
- const uniqBy = require('lodash/uniqBy');
2
- const groupBy = require('lodash/groupBy');
3
- const cloneDeep = require('lodash/cloneDeep');
4
- const { Joi, patterns } = require('@arcblock/validator');
5
- const { CustomError: Error } = require('@ocap/util/lib/error');
6
- const { BN } = require('@ocap/util');
7
- const { Runner, pipes } = require('@ocap/tx-pipeline');
8
- const { account, stake, evidence, rollupBlock } = require('@ocap/state');
9
-
10
- const debug = require('debug')(`${require('../../../package.json').name}:claim-block-reward`);
11
-
12
- const { toStakeAddress } = require('@arcblock/did-util');
13
- const VerifySigners = require('./pipes/verify-signers');
14
- const VerifyStatus = require('./pipes/verify-status');
15
- const EnsureValidator = require('./pipes/ensure-validator');
16
- const EnsureTxGas = require('../../pipes/ensure-gas');
17
- const EnsureTxCost = require('../../pipes/ensure-cost');
18
- const { applyTokenChange, splitTxFee, getBNSum, getRewardLocker, RATE_BASE } = require('../../util');
19
-
20
- const runner = new Runner();
21
-
22
- // 1. verify itx
23
- const schema = Joi.object({
24
- rollup: Joi.DID().prefix().role('ROLE_ROLLUP').required(),
25
- blockHeight: Joi.number().integer().greater(0).required(),
26
- blockHash: Joi.string().regex(patterns.txHash).required(),
27
- evidence: Joi.object({
28
- hash: Joi.string().regex(patterns.txHash).required(),
29
- }).required(),
30
- publisher: Joi.DID().prefix().wallet('ethereum').required(),
31
- data: Joi.any().optional().allow(null),
32
- }).options({ stripUnknown: true, noDefaults: false });
33
- runner.use((context, next) => {
34
- const { tx, itx } = context;
35
-
36
- const { error } = schema.validate(itx);
37
- if (error) {
38
- return next(new Error('INVALID_TX', error.message));
39
- }
40
-
41
- // ensure publisher same with tx.from
42
- if (tx.from !== itx.publisher) {
43
- return next(new Error('INVALID_TX', 'itx.publisher must be same with tx.from'));
44
- }
45
-
46
- context.lockerAddress = getRewardLocker(itx.rollup);
47
-
48
- return next();
49
- });
50
-
51
- // 2. ensure evidence not exist
52
- runner.use(pipes.ExtractState({ from: 'itx.evidence.hash', to: 'evidenceSeen', status: 'OK', table: 'evidence' }));
53
- runner.use(pipes.ExtractState({ from: 'itx.blockHash', to: 'blockClaimed', status: 'OK', table: 'evidence' }));
54
- runner.use(({ evidenceSeen, blockClaimed }, next) => {
55
- if (evidenceSeen) return next(new Error('INVALID_TX', 'Claim evidence already seen on this chain'));
56
- if (blockClaimed) return next(new Error('INVALID_TX', 'Block reward already claimed before this tx'));
57
- return next();
58
- });
59
-
60
- // 3. verify rollup and block state
61
- runner.use(pipes.ExtractState({ from: 'itx.rollup', to: 'rollupState', status: 'INVALID_ROLLUP', table: 'rollup' }));
62
- runner.use(EnsureValidator());
63
- runner.use(VerifyStatus({ closed: false }));
64
- runner.use(
65
- pipes.ExtractState({ from: 'itx.blockHash', to: 'blockState', status: 'INVALID_ROLLUP_BLOCK', table: 'rollupBlock' })
66
- );
67
- runner.use((context, next) => {
68
- const { blockState, rollupState, itx } = context;
69
- if (blockState.rollup !== rollupState.address) {
70
- return next(new Error('INVALID_TX', 'Rollup block belonging does not match'));
71
- }
72
- if (blockState.height !== itx.blockHeight) {
73
- return next(new Error('INVALID_TX', 'Rollup block height does not match'));
74
- }
75
-
76
- // If the publisher is not the producer, he should wait at least rollupState.publishWaitingPeriod
77
- if (blockState.proposer !== itx.publisher) {
78
- const proposedAt = +new Date(blockState.context.genesisTime);
79
- const publishedAt = +new Date(context.txTime);
80
- if (proposedAt + rollupState.publishWaitingPeriod * 1000 > publishedAt) {
81
- return next(new Error('INVALID_TX', 'Rollup block can only be published by producer during waiting period'));
82
- }
83
- }
84
-
85
- context.producerStake = toStakeAddress(blockState.proposer, itx.rollup);
86
-
87
- return next();
88
- });
89
-
90
- // 4. verify tx signers & signatures
91
- runner.use(VerifySigners({ signersKey: 'tx.signaturesList', allowSender: true }));
92
- runner.use(pipes.VerifyMultiSigV2({ signersKey: 'signers' }));
93
-
94
- // 5. verify block reward locker
95
- runner.use(
96
- pipes.ExtractState({ from: 'lockerAddress', to: 'lockerState', status: 'INVALID_LOCKER_STATE', table: 'stake' })
97
- );
98
- runner.use(
99
- pipes.ExtractState({ from: 'producerStake', to: 'stakeState', status: 'INVALID_STAKE_STATE', table: 'stake' })
100
- );
101
-
102
- // 6. verify sender and signer states
103
- runner.use(
104
- pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })
105
- );
106
- runner.use(
107
- pipes.ExtractState({ from: 'signers', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })
108
- );
109
- runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', stateKey: 'senderState', addressKey: 'tx.from' }));
110
-
111
- // 7. verify token state
112
- runner.use(
113
- pipes.ExtractState({ from: 'rollupState.tokenAddress', to: 'tokenState', status: 'INVALID_TOKEN', table: 'token' })
114
- );
115
-
116
- // 8. split and aggregate block reward for each tx and the block
117
- runner.use(pipes.ExtractState({ from: 'blockState.txs', to: 'txs', status: 'INVALID_TX', table: 'tx' }));
118
- runner.use((context, next) => {
119
- const { itx, txs, rollupState, blockState, lockerState, tokenState, stakeState } = context;
120
- const { proposerFeeShare, publisherFeeShare } = rollupState;
121
-
122
- const shares = {
123
- publisher: publisherFeeShare,
124
- proposer: proposerFeeShare,
125
- validator: 10000 - publisherFeeShare - proposerFeeShare,
126
- };
127
-
128
- const changes = { account: [], stake: [] };
129
-
130
- // 0. handle slash case
131
- // TODO: the producer stake balance should be enough for slashing
132
- const shouldSlash = blockState.proposer !== itx.publisher;
133
- if (shouldSlash) {
134
- const slashAmount = new BN(rollupState.minStakeAmount).mul(new BN(rollupState.publishSlashRate)).div(RATE_BASE);
135
- const slashShare = slashAmount.div(new BN(2));
136
- changes.stake.push({ address: stakeState.address, delta: `-${slashAmount.toString(10)}`, action: 'slash' });
137
- changes.stake.push({ address: lockerState.address, delta: slashShare.toString(10), action: 'slash' });
138
- changes.account.push({ address: itx.publisher, delta: slashShare.toString(10), action: 'reward' });
139
- }
140
-
141
- // 1. loop through the tx and split reward
142
- txs.forEach((x) => {
143
- const { actualFee } = x.tx.itxJson;
144
- const { publisher, proposer, validator } = splitTxFee({ total: actualFee, shares, stringify: false });
145
-
146
- changes.stake.push({ address: lockerState.address, delta: `-${actualFee}`, action: 'claim' });
147
- changes.account.push({ address: itx.publisher, delta: publisher.toString(10), action: 'fee' });
148
-
149
- if (x.type === 'deposit_token_v2') {
150
- changes.account.push({ address: x.tx.itxJson.proposer, delta: proposer.toString(10), action: 'fee' });
151
-
152
- // block and tx signers share the validator part
153
- // FIXME: delegation is not supported here yet
154
- const validators = x.tx.signatures.map((s) => s.signer).concat(blockState.signatures.map((s) => s.signer));
155
- const validatorShare = validator.div(new BN(validators.length));
156
- validators.forEach((v) =>
157
- changes.account.push({ address: v, delta: validatorShare.toString(10), action: 'fee' })
158
- );
159
- } else if (x.type === 'withdraw_token_v2') {
160
- changes.account.push({ address: blockState.proposer, delta: proposer.toString(10), action: 'fee' });
161
-
162
- // block signers share the validator part
163
- const validators = blockState.signatures.map((s) => s.signer);
164
- const validatorShares = splitTxFee({
165
- total: validator,
166
- shares: validators.reduce((acc, signer) => {
167
- acc[signer] = 1;
168
- return acc;
169
- }, {}),
170
- rateBase: new BN(validators.length),
171
- });
172
- Object.keys(validatorShares).forEach((v) =>
173
- changes.account.push({ address: v, delta: validatorShares[v], action: 'fee' })
174
- );
175
- }
176
- });
177
-
178
- // 2. aggregate changes to updates
179
- const grouped = {
180
- account: groupBy(changes.account, 'address'),
181
- stake: groupBy(changes.stake, 'address'),
182
- };
183
-
184
- const updates = {
185
- stake: Object.keys(grouped.stake).reduce((acc, x) => {
186
- acc[x] = {
187
- address: x,
188
- token: tokenState.address,
189
- delta: getBNSum(...grouped.stake[x].map((c) => c.delta)),
190
- action: grouped.stake[x][grouped.stake[x].length - 1].action,
191
- };
192
- return acc;
193
- }, {}),
194
- account: Object.keys(grouped.account).reduce((acc, x) => {
195
- acc[x] = {
196
- address: x,
197
- token: tokenState.address,
198
- delta: getBNSum(...grouped.account[x].map((c) => c.delta)),
199
- action: grouped.account[x][grouped.account[x].length - 1].action,
200
- };
201
- return acc;
202
- }, {}),
203
- };
204
-
205
- context.changes = changes;
206
- context.updates = updates;
207
-
208
- return next();
209
- });
210
-
211
- // 9. extract all accounts that will be updated exist
212
- runner.use((context, next) => {
213
- const { updates, senderState, signerStates } = context;
214
- const requiredAccounts = Object.keys(updates.account);
215
- const knownAccounts = { [senderState.address]: senderState };
216
-
217
- signerStates.forEach((x) => (knownAccounts[x.address] = x));
218
-
219
- context.missingAccounts = requiredAccounts.filter((x) => !knownAccounts[x]);
220
- return next();
221
- });
222
- runner.use(
223
- pipes.ExtractState({
224
- from: 'missingAccounts',
225
- to: 'missingAccountStates',
226
- status: 'INVALID_SIGNER_STATE',
227
- table: 'account',
228
- })
229
- );
230
- runner.use((context, next) => {
231
- const { senderState, signerStates, missingAccountStates } = context;
232
- context.accountStates = uniqBy([senderState, ...signerStates, ...(missingAccountStates || [])], 'address');
233
- return next();
234
- });
235
-
236
- // Ensure tx fee and gas
237
- runner.use(
238
- EnsureTxGas((context) => {
239
- const result = { create: 2, update: 1, payment: 0 };
240
-
241
- result.update += context.accountStates.length;
242
- if (context.updates[context.lockerState.address]) {
243
- result.update += 1;
244
- }
245
- if (context.updates[context.stakeState.address]) {
246
- result.update += 1;
247
- }
248
-
249
- return result;
250
- })
251
- );
252
- runner.use(EnsureTxCost({ attachSenderChanges: true }));
253
-
254
- // Save context snapshot before updating states
255
- runner.use(pipes.TakeStateSnapshot());
256
-
257
- // 10. update state
258
- runner.use(
259
- async (context, next) => {
260
- const {
261
- tx,
262
- itx,
263
- updates,
264
- statedb,
265
- senderState,
266
- blockState,
267
- lockerState,
268
- stakeState,
269
- accountStates,
270
- senderChange,
271
- updateVaults,
272
- } = context;
273
-
274
- const [newStakeStates, newAccountStates, newBlockState] = await Promise.all([
275
- // update stake states
276
- Promise.all(
277
- [lockerState, stakeState].map((x) =>
278
- updates.stake[x.address]
279
- ? statedb.stake.update(
280
- x.address,
281
- stake.update(x, applyTokenChange(x, updates.stake[x.address]), context),
282
- context
283
- )
284
- : x
285
- )
286
- ),
287
-
288
- // update accounts(proposer, publisher, validator)
289
- Promise.all(
290
- accountStates.map((x) => {
291
- if (updates.account[x.address]) {
292
- let updateSet = applyTokenChange(x, updates.account[x.address]);
293
- if (x.address === senderState.address) {
294
- updateSet.nonce = tx.nonce;
295
- updateSet = Object.assign(updateSet, senderChange ? applyTokenChange(updateSet, senderChange) : {});
296
- }
297
-
298
- return statedb.account.update(x.address, account.update(x, updateSet, context), context);
299
- }
300
-
301
- return x;
302
- })
303
- ),
304
-
305
- // Update block state, just update the context
306
- statedb.rollupBlock.update(blockState.hash, rollupBlock.update(blockState, context), context),
307
-
308
- // Create evidence
309
- statedb.evidence.create(
310
- itx.evidence.hash,
311
- evidence.create({ hash: itx.evidence.hash, data: 'rollup-claim-block-reward' }, context),
312
- context
313
- ),
314
- statedb.evidence.create(
315
- itx.blockHash,
316
- evidence.create({ hash: itx.blockHash, data: 'rollup-claim-block-reward' }, context),
317
- context
318
- ),
319
- ]);
320
-
321
- await updateVaults();
322
-
323
- // to avoid this to be incorrectly indexed
324
- delete context.stakeState;
325
-
326
- context.stakeStates = newStakeStates.filter((x) => updates.stake[x.address]);
327
- context.accountStates = newAccountStates;
328
- context.blockState = newBlockState;
329
-
330
- context.updatedAccounts.push(...cloneDeep(Object.values(updates.account)));
331
- context.updatedAccounts.push(...cloneDeep(Object.values(updates.stake)));
332
-
333
- debug('claim-block-reward', itx);
334
-
335
- next();
336
- },
337
- { persistError: true }
338
- );
339
-
340
- runner.use(pipes.VerifyStateDiff());
341
-
342
- module.exports = runner;