@openzeppelin/upgrades-core 1.9.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.
- package/CHANGELOG.md +110 -0
- package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.dbg.json +4 -0
- package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.json +80 -0
- package/artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/ProxyAdmin.json +160 -0
- package/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json +155 -0
- package/artifacts/AdminUpgradeabilityProxy.json +155 -0
- package/artifacts/ProxyAdmin.json +160 -0
- package/artifacts/contracts/proxy/AdminUpgradeabilityProxy.sol/AdminUpgradeabilityProxy.json +155 -0
- package/artifacts/contracts/proxy/ProxyAdmin.sol/ProxyAdmin.json +160 -0
- package/contracts/Initializable.sol +64 -0
- package/dist/ast-dereferencer.d.ts +8 -0
- package/dist/ast-dereferencer.d.ts.map +1 -0
- package/dist/ast-dereferencer.js +29 -0
- package/dist/ast-dereferencer.js.map +1 -0
- package/dist/deployment.d.ts +18 -0
- package/dist/deployment.d.ts.map +1 -0
- package/dist/deployment.js +110 -0
- package/dist/deployment.js.map +1 -0
- package/dist/deployment.test.d.ts +2 -0
- package/dist/deployment.test.d.ts.map +1 -0
- package/dist/deployment.test.js +92 -0
- package/dist/deployment.test.js.map +1 -0
- package/dist/eip-1967.d.ts +7 -0
- package/dist/eip-1967.d.ts.map +1 -0
- package/dist/eip-1967.js +63 -0
- package/dist/eip-1967.js.map +1 -0
- package/dist/error.d.ts +21 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +21 -0
- package/dist/error.js.map +1 -0
- package/dist/impl-store.d.ts +7 -0
- package/dist/impl-store.d.ts.map +1 -0
- package/dist/impl-store.js +94 -0
- package/dist/impl-store.js.map +1 -0
- package/dist/impl-store.test.d.ts +2 -0
- package/dist/impl-store.test.d.ts.map +1 -0
- package/dist/impl-store.test.js +55 -0
- package/dist/impl-store.test.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/levenshtein.d.ts +12 -0
- package/dist/levenshtein.d.ts.map +1 -0
- package/dist/levenshtein.js +89 -0
- package/dist/levenshtein.js.map +1 -0
- package/dist/levenshtein.test.d.ts +2 -0
- package/dist/levenshtein.test.d.ts.map +1 -0
- package/dist/levenshtein.test.js +88 -0
- package/dist/levenshtein.test.js.map +1 -0
- package/dist/link-refs.d.ts +11 -0
- package/dist/link-refs.d.ts.map +1 -0
- package/dist/link-refs.js +36 -0
- package/dist/link-refs.js.map +1 -0
- package/dist/link-refs.test.d.ts +2 -0
- package/dist/link-refs.test.d.ts.map +1 -0
- package/dist/link-refs.test.js +76 -0
- package/dist/link-refs.test.js.map +1 -0
- package/dist/manifest-storage-layout.d.ts +6 -0
- package/dist/manifest-storage-layout.d.ts.map +1 -0
- package/dist/manifest-storage-layout.js +95 -0
- package/dist/manifest-storage-layout.js.map +1 -0
- package/dist/manifest-storage-layout.test.d.ts +2 -0
- package/dist/manifest-storage-layout.test.d.ts.map +1 -0
- package/dist/manifest-storage-layout.test.js +105 -0
- package/dist/manifest-storage-layout.test.js.map +1 -0
- package/dist/manifest.d.ts +36 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +154 -0
- package/dist/manifest.js.map +1 -0
- package/dist/manifest.test.d.ts +2 -0
- package/dist/manifest.test.d.ts.map +1 -0
- package/dist/manifest.test.js +17 -0
- package/dist/manifest.test.js.map +1 -0
- package/dist/provider.d.ts +37 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +74 -0
- package/dist/provider.js.map +1 -0
- package/dist/provider.test.d.ts +2 -0
- package/dist/provider.test.d.ts.map +1 -0
- package/dist/provider.test.js +41 -0
- package/dist/provider.test.js.map +1 -0
- package/dist/scripts/migrate-oz-cli-project.d.ts +108 -0
- package/dist/scripts/migrate-oz-cli-project.d.ts.map +1 -0
- package/dist/scripts/migrate-oz-cli-project.js +321 -0
- package/dist/scripts/migrate-oz-cli-project.js.map +1 -0
- package/dist/scripts/migrate-oz-cli-project.test.d.ts +2 -0
- package/dist/scripts/migrate-oz-cli-project.test.d.ts.map +1 -0
- package/dist/scripts/migrate-oz-cli-project.test.js +60 -0
- package/dist/scripts/migrate-oz-cli-project.test.js.map +1 -0
- package/dist/set-proxy-kind.d.ts +5 -0
- package/dist/set-proxy-kind.d.ts.map +1 -0
- package/dist/set-proxy-kind.js +25 -0
- package/dist/set-proxy-kind.js.map +1 -0
- package/dist/solc-api.d.ts +39 -0
- package/dist/solc-api.d.ts.map +1 -0
- package/dist/solc-api.js +3 -0
- package/dist/solc-api.js.map +1 -0
- package/dist/src-decoder.d.ts +6 -0
- package/dist/src-decoder.d.ts.map +1 -0
- package/dist/src-decoder.js +36 -0
- package/dist/src-decoder.js.map +1 -0
- package/dist/src-decoder.test.d.ts +2 -0
- package/dist/src-decoder.test.d.ts.map +1 -0
- package/dist/src-decoder.test.js +29 -0
- package/dist/src-decoder.test.js.map +1 -0
- package/dist/storage/compare.d.ts +55 -0
- package/dist/storage/compare.d.ts.map +1 -0
- package/dist/storage/compare.js +181 -0
- package/dist/storage/compare.js.map +1 -0
- package/dist/storage/compat.d.ts +4 -0
- package/dist/storage/compat.d.ts.map +1 -0
- package/dist/storage/compat.js +9 -0
- package/dist/storage/compat.js.map +1 -0
- package/dist/storage/extract.d.ts +7 -0
- package/dist/storage/extract.d.ts.map +1 -0
- package/dist/storage/extract.js +86 -0
- package/dist/storage/extract.js.map +1 -0
- package/dist/storage/index.d.ts +8 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +65 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/layout.d.ts +31 -0
- package/dist/storage/layout.d.ts.map +1 -0
- package/dist/storage/layout.js +46 -0
- package/dist/storage/layout.js.map +1 -0
- package/dist/storage/report.d.ts +8 -0
- package/dist/storage/report.d.ts.map +1 -0
- package/dist/storage/report.js +175 -0
- package/dist/storage/report.js.map +1 -0
- package/dist/storage/report.test.d.ts +2 -0
- package/dist/storage/report.test.d.ts.map +1 -0
- package/dist/storage/report.test.js +82 -0
- package/dist/storage/report.test.js.map +1 -0
- package/dist/storage.test.d.ts +2 -0
- package/dist/storage.test.d.ts.map +1 -0
- package/dist/storage.test.js +436 -0
- package/dist/storage.test.js.map +1 -0
- package/dist/stub-provider.d.ts +14 -0
- package/dist/stub-provider.d.ts.map +1 -0
- package/dist/stub-provider.js +128 -0
- package/dist/stub-provider.js.map +1 -0
- package/dist/utils/assert.d.ts +3 -0
- package/dist/utils/assert.d.ts.map +1 -0
- package/dist/utils/assert.js +14 -0
- package/dist/utils/assert.js.map +1 -0
- package/dist/utils/curry.d.ts +6 -0
- package/dist/utils/curry.d.ts.map +1 -0
- package/dist/utils/curry.js +16 -0
- package/dist/utils/curry.js.map +1 -0
- package/dist/utils/debug.d.ts +4 -0
- package/dist/utils/debug.d.ts.map +1 -0
- package/dist/utils/debug.js +8 -0
- package/dist/utils/debug.js.map +1 -0
- package/dist/utils/deep-array.d.ts +3 -0
- package/dist/utils/deep-array.d.ts.map +1 -0
- package/dist/utils/deep-array.js +13 -0
- package/dist/utils/deep-array.js.map +1 -0
- package/dist/utils/deep-array.test.d.ts +2 -0
- package/dist/utils/deep-array.test.d.ts.map +1 -0
- package/dist/utils/deep-array.test.js +23 -0
- package/dist/utils/deep-array.test.js.map +1 -0
- package/dist/utils/function.d.ts +4 -0
- package/dist/utils/function.d.ts.map +1 -0
- package/dist/utils/function.js +43 -0
- package/dist/utils/function.js.map +1 -0
- package/dist/utils/function.test.d.ts +2 -0
- package/dist/utils/function.test.d.ts.map +1 -0
- package/dist/utils/function.test.js +34 -0
- package/dist/utils/function.test.js.map +1 -0
- package/dist/utils/indent.d.ts +2 -0
- package/dist/utils/indent.d.ts.map +1 -0
- package/dist/utils/indent.js +8 -0
- package/dist/utils/indent.js.map +1 -0
- package/dist/utils/is-nullish.d.ts +2 -0
- package/dist/utils/is-nullish.d.ts.map +1 -0
- package/dist/utils/is-nullish.js +8 -0
- package/dist/utils/is-nullish.js.map +1 -0
- package/dist/utils/is-nullish.test.d.ts +2 -0
- package/dist/utils/is-nullish.test.d.ts.map +1 -0
- package/dist/utils/is-nullish.test.js +17 -0
- package/dist/utils/is-nullish.test.js.map +1 -0
- package/dist/utils/is-value-type.d.ts +3 -0
- package/dist/utils/is-value-type.d.ts.map +1 -0
- package/dist/utils/is-value-type.js +8 -0
- package/dist/utils/is-value-type.js.map +1 -0
- package/dist/utils/itemize.d.ts +3 -0
- package/dist/utils/itemize.d.ts.map +1 -0
- package/dist/utils/itemize.js +18 -0
- package/dist/utils/itemize.js.map +1 -0
- package/dist/utils/log.d.ts +4 -0
- package/dist/utils/log.d.ts.map +1 -0
- package/dist/utils/log.js +35 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/make-non-enumerable.d.ts +2 -0
- package/dist/utils/make-non-enumerable.d.ts.map +1 -0
- package/dist/utils/make-non-enumerable.js +9 -0
- package/dist/utils/make-non-enumerable.js.map +1 -0
- package/dist/utils/map-values.d.ts +2 -0
- package/dist/utils/map-values.d.ts.map +1 -0
- package/dist/utils/map-values.js +12 -0
- package/dist/utils/map-values.js.map +1 -0
- package/dist/utils/parse-type-id.d.ts +9 -0
- package/dist/utils/parse-type-id.d.ts.map +1 -0
- package/dist/utils/parse-type-id.js +92 -0
- package/dist/utils/parse-type-id.js.map +1 -0
- package/dist/utils/parse-type-id.test.d.ts +2 -0
- package/dist/utils/parse-type-id.test.d.ts.map +1 -0
- package/dist/utils/parse-type-id.test.js +25 -0
- package/dist/utils/parse-type-id.test.js.map +1 -0
- package/dist/utils/pick.d.ts +2 -0
- package/dist/utils/pick.d.ts.map +1 -0
- package/dist/utils/pick.js +12 -0
- package/dist/utils/pick.js.map +1 -0
- package/dist/utils/type-id.d.ts +4 -0
- package/dist/utils/type-id.d.ts.map +1 -0
- package/dist/utils/type-id.js +65 -0
- package/dist/utils/type-id.js.map +1 -0
- package/dist/validate/compat.d.ts +6 -0
- package/dist/validate/compat.d.ts.map +1 -0
- package/dist/validate/compat.js +4 -0
- package/dist/validate/compat.js.map +1 -0
- package/dist/validate/data.d.ts +14 -0
- package/dist/validate/data.d.ts.map +1 -0
- package/dist/validate/data.js +50 -0
- package/dist/validate/data.js.map +1 -0
- package/dist/validate/error.d.ts +7 -0
- package/dist/validate/error.d.ts.map +1 -0
- package/dist/validate/error.js +78 -0
- package/dist/validate/error.js.map +1 -0
- package/dist/validate/index.d.ts +8 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +24 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/overrides.d.ts +14 -0
- package/dist/validate/overrides.d.ts.map +1 -0
- package/dist/validate/overrides.js +72 -0
- package/dist/validate/overrides.js.map +1 -0
- package/dist/validate/query.d.ts +15 -0
- package/dist/validate/query.d.ts.map +1 -0
- package/dist/validate/query.js +111 -0
- package/dist/validate/query.js.map +1 -0
- package/dist/validate/query.test.d.ts +2 -0
- package/dist/validate/query.test.d.ts.map +1 -0
- package/dist/validate/query.test.js +48 -0
- package/dist/validate/query.test.js.map +1 -0
- package/dist/validate/run.d.ts +39 -0
- package/dist/validate/run.d.ts.map +1 -0
- package/dist/validate/run.js +199 -0
- package/dist/validate/run.js.map +1 -0
- package/dist/validate.test.d.ts +2 -0
- package/dist/validate.test.d.ts.map +1 -0
- package/dist/validate.test.js +116 -0
- package/dist/validate.test.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +66 -0
- package/dist/version.js.map +1 -0
- package/dist/version.test.d.ts +2 -0
- package/dist/version.test.d.ts.map +1 -0
- package/dist/version.test.js +53 -0
- package/dist/version.test.js.map +1 -0
- package/package.json +58 -0
- package/src/ast-dereferencer.ts +42 -0
- package/src/deployment.test.ts +98 -0
- package/src/deployment.ts +122 -0
- package/src/eip-1967.ts +77 -0
- package/src/error.ts +26 -0
- package/src/impl-store.test.ts +59 -0
- package/src/impl-store.ts +124 -0
- package/src/index.ts +18 -0
- package/src/levenshtein.test.ts +91 -0
- package/src/levenshtein.ts +116 -0
- package/src/link-refs.test.ts +77 -0
- package/src/link-refs.ts +41 -0
- package/src/manifest-storage-layout.test.ts +118 -0
- package/src/manifest-storage-layout.ts +107 -0
- package/src/manifest.test.ts +13 -0
- package/src/manifest.ts +178 -0
- package/src/provider.test.ts +43 -0
- package/src/provider.ts +103 -0
- package/src/scripts/migratable-manifest.test.json +175 -0
- package/src/scripts/migrate-oz-cli-project.test.ts +70 -0
- package/src/scripts/migrate-oz-cli-project.test.ts.md +146 -0
- package/src/scripts/migrate-oz-cli-project.test.ts.snap +0 -0
- package/src/scripts/migrate-oz-cli-project.ts +484 -0
- package/src/scripts/project-file.test.json +25 -0
- package/src/set-proxy-kind.ts +27 -0
- package/src/solc-api.ts +42 -0
- package/src/src-decoder.test.ts +30 -0
- package/src/src-decoder.ts +37 -0
- package/src/storage/compare.ts +249 -0
- package/src/storage/compat.ts +3 -0
- package/src/storage/extract.ts +110 -0
- package/src/storage/index.ts +73 -0
- package/src/storage/layout.ts +88 -0
- package/src/storage/report.test.ts +95 -0
- package/src/storage/report.test.ts.md +154 -0
- package/src/storage/report.test.ts.snap +0 -0
- package/src/storage/report.ts +215 -0
- package/src/storage.test.ts +479 -0
- package/src/storage.test.ts.md +643 -0
- package/src/storage.test.ts.snap +0 -0
- package/src/stub-provider.ts +120 -0
- package/src/utils/assert.ts +9 -0
- package/src/utils/curry.ts +17 -0
- package/src/utils/debug.ts +3 -0
- package/src/utils/deep-array.test.ts +21 -0
- package/src/utils/deep-array.ts +9 -0
- package/src/utils/function.test.ts +37 -0
- package/src/utils/function.ts +53 -0
- package/src/utils/indent.ts +3 -0
- package/src/utils/is-nullish.test.ts +15 -0
- package/src/utils/is-nullish.ts +3 -0
- package/src/utils/is-value-type.ts +5 -0
- package/src/utils/itemize.ts +16 -0
- package/src/utils/log.ts +34 -0
- package/src/utils/make-non-enumerable.ts +4 -0
- package/src/utils/map-values.ts +7 -0
- package/src/utils/parse-type-id.test.ts +22 -0
- package/src/utils/parse-type-id.test.ts.md +264 -0
- package/src/utils/parse-type-id.test.ts.snap +0 -0
- package/src/utils/parse-type-id.ts +104 -0
- package/src/utils/pick.ts +7 -0
- package/src/utils/type-id.ts +57 -0
- package/src/validate/compat.ts +9 -0
- package/src/validate/data.ts +55 -0
- package/src/validate/error.ts +75 -0
- package/src/validate/index.ts +17 -0
- package/src/validate/overrides.ts +93 -0
- package/src/validate/query.test.ts +48 -0
- package/src/validate/query.ts +127 -0
- package/src/validate/run.ts +278 -0
- package/src/validate.test.ts +133 -0
- package/src/version.test.ts +59 -0
- package/src/version.ts +71 -0
package/src/error.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import util from 'util';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
|
|
4
|
+
interface ErrorDescriptor<E> {
|
|
5
|
+
msg: (e: E) => string;
|
|
6
|
+
hint?: (e: E) => string | undefined;
|
|
7
|
+
link?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type ErrorDescriptions<E extends { kind: string }> = {
|
|
11
|
+
[K in E['kind']]: ErrorDescriptor<E & { kind: K }>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
function noDetails() {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class UpgradesError extends Error {
|
|
19
|
+
constructor(message: string, details = noDetails) {
|
|
20
|
+
super(message + '\n\n' + details());
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[util.inspect.custom](): string {
|
|
24
|
+
return chalk.red.bold('Error:') + ' ' + this.message;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
|
|
3
|
+
import { promises as fs } from 'fs';
|
|
4
|
+
import rimrafAsync from 'rimraf';
|
|
5
|
+
import util from 'util';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
|
|
9
|
+
import { fetchOrDeploy } from './impl-store';
|
|
10
|
+
import { getVersion } from './version';
|
|
11
|
+
import { stubProvider } from './stub-provider';
|
|
12
|
+
|
|
13
|
+
const rimraf = util.promisify(rimrafAsync);
|
|
14
|
+
|
|
15
|
+
test.before(async () => {
|
|
16
|
+
process.chdir(await fs.mkdtemp(path.join(os.tmpdir(), 'upgrades-core-test-')));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test.after(async () => {
|
|
20
|
+
await rimraf(process.cwd());
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const version1 = getVersion('01');
|
|
24
|
+
const version2 = getVersion('02', '02');
|
|
25
|
+
|
|
26
|
+
test('deploys on cache miss', async t => {
|
|
27
|
+
const provider = stubProvider();
|
|
28
|
+
await fetchOrDeploy(version1, provider, provider.deploy);
|
|
29
|
+
t.is(provider.deployCount, 1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('reuses on cache hit', async t => {
|
|
33
|
+
const provider = stubProvider();
|
|
34
|
+
const cachedDeploy = () => fetchOrDeploy(version1, provider, provider.deploy);
|
|
35
|
+
const address1 = await cachedDeploy();
|
|
36
|
+
const address2 = await cachedDeploy();
|
|
37
|
+
t.is(provider.deployCount, 1);
|
|
38
|
+
t.is(address2, address1);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('does not reuse unrelated version', async t => {
|
|
42
|
+
const provider = stubProvider();
|
|
43
|
+
const address1 = await fetchOrDeploy(version1, provider, provider.deploy);
|
|
44
|
+
const address2 = await fetchOrDeploy(version2, provider, provider.deploy);
|
|
45
|
+
t.is(provider.deployCount, 2);
|
|
46
|
+
t.not(address2, address1);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('cleans up invalid deployment', async t => {
|
|
50
|
+
const chainId = 1234;
|
|
51
|
+
const provider1 = stubProvider(chainId);
|
|
52
|
+
// create a deployment on a network
|
|
53
|
+
await fetchOrDeploy(version1, provider1, provider1.deploy);
|
|
54
|
+
// try to fetch it on a different network with same chainId
|
|
55
|
+
const provider2 = stubProvider(chainId);
|
|
56
|
+
await t.throwsAsync(fetchOrDeploy(version1, provider2, provider2.deploy));
|
|
57
|
+
// the failed deployment has been cleaned up
|
|
58
|
+
await fetchOrDeploy(version1, provider2, provider2.deploy);
|
|
59
|
+
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import debug from './utils/debug';
|
|
2
|
+
import { Manifest, ManifestData, ImplDeployment } from './manifest';
|
|
3
|
+
import { EthereumProvider, isDevelopmentNetwork } from './provider';
|
|
4
|
+
import { Deployment, InvalidDeployment, resumeOrDeploy, waitAndValidateDeployment } from './deployment';
|
|
5
|
+
import type { Version } from './version';
|
|
6
|
+
|
|
7
|
+
interface ManifestLens<T> {
|
|
8
|
+
description: string;
|
|
9
|
+
(data: ManifestData): ManifestField<T>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface ManifestField<T> {
|
|
13
|
+
get(): T | undefined;
|
|
14
|
+
set(value: T | undefined): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function fetchOrDeployGeneric<T extends Deployment>(
|
|
18
|
+
lens: ManifestLens<T>,
|
|
19
|
+
provider: EthereumProvider,
|
|
20
|
+
deploy: () => Promise<T>,
|
|
21
|
+
): Promise<string> {
|
|
22
|
+
const manifest = await Manifest.forNetwork(provider);
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const deployment = await manifest.lockedRun(async () => {
|
|
26
|
+
debug('fetching deployment of', lens.description);
|
|
27
|
+
const data = await manifest.read();
|
|
28
|
+
const deployment = lens(data);
|
|
29
|
+
const stored = deployment.get();
|
|
30
|
+
if (stored === undefined) {
|
|
31
|
+
debug('deployment of', lens.description, 'not found');
|
|
32
|
+
}
|
|
33
|
+
const updated = await resumeOrDeploy(provider, stored, deploy);
|
|
34
|
+
if (updated !== stored) {
|
|
35
|
+
await checkForAddressClash(provider, data, updated);
|
|
36
|
+
deployment.set(updated);
|
|
37
|
+
await manifest.write(data);
|
|
38
|
+
}
|
|
39
|
+
return updated;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await waitAndValidateDeployment(provider, deployment);
|
|
43
|
+
|
|
44
|
+
return deployment.address;
|
|
45
|
+
} catch (e) {
|
|
46
|
+
// If we run into a deployment error, we remove it from the manifest.
|
|
47
|
+
if (e instanceof InvalidDeployment) {
|
|
48
|
+
await manifest.lockedRun(async () => {
|
|
49
|
+
const data = await manifest.read();
|
|
50
|
+
const deployment = lens(data);
|
|
51
|
+
const stored = deployment.get();
|
|
52
|
+
if (stored?.txHash === e.deployment.txHash) {
|
|
53
|
+
deployment.set(undefined);
|
|
54
|
+
await manifest.write(data);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
e.removed = true;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
throw e;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function fetchOrDeploy(
|
|
65
|
+
version: Version,
|
|
66
|
+
provider: EthereumProvider,
|
|
67
|
+
deploy: () => Promise<ImplDeployment>,
|
|
68
|
+
): Promise<string> {
|
|
69
|
+
return fetchOrDeployGeneric(implLens(version.linkedWithoutMetadata), provider, deploy);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const implLens = (versionWithoutMetadata: string) =>
|
|
73
|
+
lens(`implementation ${versionWithoutMetadata}`, data => ({
|
|
74
|
+
get: () => data.impls[versionWithoutMetadata],
|
|
75
|
+
set: (value?: ImplDeployment) => (data.impls[versionWithoutMetadata] = value),
|
|
76
|
+
}));
|
|
77
|
+
|
|
78
|
+
export async function fetchOrDeployAdmin(
|
|
79
|
+
provider: EthereumProvider,
|
|
80
|
+
deploy: () => Promise<Deployment>,
|
|
81
|
+
): Promise<string> {
|
|
82
|
+
return fetchOrDeployGeneric(adminLens, provider, deploy);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const adminLens = lens('proxy admin', data => ({
|
|
86
|
+
get: () => data.admin,
|
|
87
|
+
set: (value?: Deployment) => (data.admin = value),
|
|
88
|
+
}));
|
|
89
|
+
|
|
90
|
+
function lens<T>(description: string, fn: (data: ManifestData) => ManifestField<T>): ManifestLens<T> {
|
|
91
|
+
return Object.assign(fn, { description });
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function checkForAddressClash(
|
|
95
|
+
provider: EthereumProvider,
|
|
96
|
+
data: ManifestData,
|
|
97
|
+
updated: Deployment,
|
|
98
|
+
): Promise<void> {
|
|
99
|
+
const clash = lookupDeployment(data, updated.address);
|
|
100
|
+
if (clash !== undefined) {
|
|
101
|
+
if (await isDevelopmentNetwork(provider)) {
|
|
102
|
+
debug('deleting a previous deployment at address', updated.address);
|
|
103
|
+
clash.set(undefined);
|
|
104
|
+
} else {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`The following deployment clashes with an existing one at ${updated.address}\n\n` +
|
|
107
|
+
JSON.stringify(updated, null, 2) +
|
|
108
|
+
`\n\n`,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function lookupDeployment(data: ManifestData, address: string): ManifestField<Deployment> | undefined {
|
|
115
|
+
if (data.admin?.address === address) {
|
|
116
|
+
return adminLens(data);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
for (const versionWithoutMetadata in data.impls) {
|
|
120
|
+
if (data.impls[versionWithoutMetadata]?.address === address) {
|
|
121
|
+
return implLens(versionWithoutMetadata)(data);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from './validate';
|
|
2
|
+
export * from './impl-store';
|
|
3
|
+
export * from './version';
|
|
4
|
+
export * from './manifest';
|
|
5
|
+
export * from './storage';
|
|
6
|
+
export * from './eip-1967';
|
|
7
|
+
export * from './provider';
|
|
8
|
+
export * from './src-decoder';
|
|
9
|
+
export * from './solc-api';
|
|
10
|
+
export * from './deployment';
|
|
11
|
+
export * from './link-refs';
|
|
12
|
+
|
|
13
|
+
export { getStorageLayoutForAddress } from './manifest-storage-layout';
|
|
14
|
+
|
|
15
|
+
export * from './scripts/migrate-oz-cli-project';
|
|
16
|
+
|
|
17
|
+
export { logWarning } from './utils/log';
|
|
18
|
+
export { setProxyKind } from './set-proxy-kind';
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
|
|
3
|
+
import { levenshtein } from './levenshtein';
|
|
4
|
+
|
|
5
|
+
const match = <T>(a: T, b: T) => (a === b ? undefined : { kind: 'replace', original: a, updated: b });
|
|
6
|
+
|
|
7
|
+
test('equal', t => {
|
|
8
|
+
const a = [...'abc'];
|
|
9
|
+
const b = [...'abc'];
|
|
10
|
+
const ops = levenshtein(a, b, match);
|
|
11
|
+
t.deepEqual(ops, []);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('append', t => {
|
|
15
|
+
const a = [...'abc'];
|
|
16
|
+
const b = [...'abcd'];
|
|
17
|
+
const ops = levenshtein(a, b, match);
|
|
18
|
+
t.like(ops, {
|
|
19
|
+
length: 1,
|
|
20
|
+
0: {
|
|
21
|
+
kind: 'append',
|
|
22
|
+
updated: 'd',
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('delete from end', t => {
|
|
28
|
+
const a = [...'abcd'];
|
|
29
|
+
const b = [...'abc'];
|
|
30
|
+
const ops = levenshtein(a, b, match);
|
|
31
|
+
t.like(ops, {
|
|
32
|
+
length: 1,
|
|
33
|
+
0: {
|
|
34
|
+
kind: 'delete',
|
|
35
|
+
original: 'd',
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('delete from middle', t => {
|
|
41
|
+
const a = [...'abc'];
|
|
42
|
+
const b = [...'ac'];
|
|
43
|
+
const ops = levenshtein(a, b, match);
|
|
44
|
+
t.like(ops, {
|
|
45
|
+
length: 1,
|
|
46
|
+
0: {
|
|
47
|
+
kind: 'delete',
|
|
48
|
+
original: 'b',
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('delete from beginning', t => {
|
|
54
|
+
const a = [...'abc'];
|
|
55
|
+
const b = [...'bc'];
|
|
56
|
+
const ops = levenshtein(a, b, match);
|
|
57
|
+
t.like(ops, {
|
|
58
|
+
length: 1,
|
|
59
|
+
0: {
|
|
60
|
+
kind: 'delete',
|
|
61
|
+
original: 'a',
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('insert', t => {
|
|
67
|
+
const a = [...'abc'];
|
|
68
|
+
const b = [...'azbc'];
|
|
69
|
+
const ops = levenshtein(a, b, match);
|
|
70
|
+
t.like(ops, {
|
|
71
|
+
length: 1,
|
|
72
|
+
0: {
|
|
73
|
+
kind: 'insert',
|
|
74
|
+
updated: 'z',
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('replace', t => {
|
|
80
|
+
const a = [...'abc'];
|
|
81
|
+
const b = [...'axc'];
|
|
82
|
+
const ops = levenshtein(a, b, match);
|
|
83
|
+
t.like(ops, {
|
|
84
|
+
length: 1,
|
|
85
|
+
0: {
|
|
86
|
+
kind: 'replace',
|
|
87
|
+
original: 'b',
|
|
88
|
+
updated: 'x',
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export type BasicOperation<T> =
|
|
2
|
+
| {
|
|
3
|
+
kind: 'append' | 'insert';
|
|
4
|
+
updated: T;
|
|
5
|
+
}
|
|
6
|
+
| {
|
|
7
|
+
kind: 'delete';
|
|
8
|
+
original: T;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type Operation<T, C> = C | BasicOperation<T>;
|
|
12
|
+
|
|
13
|
+
type GetChangeOp<T, C> = (a: T, b: T) => C | undefined;
|
|
14
|
+
|
|
15
|
+
export function levenshtein<T, C>(a: T[], b: T[], getChangeOp: GetChangeOp<T, C>): Operation<T, C>[] {
|
|
16
|
+
const matrix = buildMatrix(a, b, getChangeOp);
|
|
17
|
+
return buildOps(matrix, a, b);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const CHANGE_COST = 3;
|
|
21
|
+
const INSERTION_COST = 2;
|
|
22
|
+
const DELETION_COST = 2;
|
|
23
|
+
|
|
24
|
+
type MatrixOp<T, C> = BasicOperation<T> | { kind: 'change'; change: C } | { kind: 'nop' };
|
|
25
|
+
type MatrixEntry<T, C> = MatrixOp<T, C> & { totalCost: number; predecessor?: MatrixEntry<T, C> };
|
|
26
|
+
|
|
27
|
+
function buildMatrix<T, C>(a: T[], b: T[], getChangeOp: GetChangeOp<T, C>): MatrixEntry<T, C>[][] {
|
|
28
|
+
// matrix[i][j] will contain the last operation that takes a.slice(0, i) to b.slice(0, j)
|
|
29
|
+
// The list of operations can be recovered following the predecessors as in buildOps
|
|
30
|
+
|
|
31
|
+
const matrix: MatrixEntry<T, C>[][] = new Array(a.length + 1);
|
|
32
|
+
|
|
33
|
+
matrix[0] = new Array(b.length + 1);
|
|
34
|
+
matrix[0][0] = { kind: 'nop', totalCost: 0 };
|
|
35
|
+
|
|
36
|
+
// Populate first row
|
|
37
|
+
for (let j = 1; j <= b.length; j++) {
|
|
38
|
+
matrix[0][j] = insertion(0, j);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Fill in the rest of the matrix
|
|
42
|
+
for (let i = 1; i <= a.length; i++) {
|
|
43
|
+
matrix[i] = new Array(b.length + 1);
|
|
44
|
+
matrix[i][0] = deletion(i, 0);
|
|
45
|
+
for (let j = 1; j <= b.length; j++) {
|
|
46
|
+
matrix[i][j] = minBy([change(i, j), insertion(i, j), deletion(i, j)], e => e.totalCost);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return matrix;
|
|
51
|
+
|
|
52
|
+
// The different kinds of matrix entries are built by these helpers
|
|
53
|
+
|
|
54
|
+
function insertion(i: number, j: number): MatrixEntry<T, C> {
|
|
55
|
+
const updated = b[j - 1];
|
|
56
|
+
const predecessor = matrix[i][j - 1];
|
|
57
|
+
const predCost = predecessor.totalCost;
|
|
58
|
+
if (j > a.length) {
|
|
59
|
+
return { kind: 'append', totalCost: predCost, predecessor, updated };
|
|
60
|
+
} else {
|
|
61
|
+
return { kind: 'insert', totalCost: predCost + INSERTION_COST, predecessor, updated };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function deletion(i: number, j: number): MatrixEntry<T, C> {
|
|
66
|
+
const original = a[i - 1];
|
|
67
|
+
const predecessor = matrix[i - 1][j];
|
|
68
|
+
const predCost = predecessor.totalCost;
|
|
69
|
+
return { kind: 'delete', totalCost: predCost + DELETION_COST, predecessor, original };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function change(i: number, j: number): MatrixEntry<T, C> {
|
|
73
|
+
const original = a[i - 1];
|
|
74
|
+
const updated = b[j - 1];
|
|
75
|
+
const predecessor = matrix[i - 1][j - 1];
|
|
76
|
+
const predCost = predecessor.totalCost;
|
|
77
|
+
const change = getChangeOp(original, updated);
|
|
78
|
+
if (change !== undefined) {
|
|
79
|
+
return { kind: 'change', totalCost: predCost + CHANGE_COST, predecessor, change };
|
|
80
|
+
} else {
|
|
81
|
+
return { kind: 'nop', totalCost: predCost, predecessor };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function minBy<T>(arr: [T, ...T[]], value: (item: T) => number): T {
|
|
87
|
+
let min = arr[0];
|
|
88
|
+
let minValue = value(min);
|
|
89
|
+
|
|
90
|
+
for (const item of arr) {
|
|
91
|
+
const itemValue = value(item);
|
|
92
|
+
if (itemValue < minValue) {
|
|
93
|
+
min = item;
|
|
94
|
+
minValue = itemValue;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return min;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function buildOps<T, C>(matrix: MatrixEntry<T, C>[][], a: T[], b: T[]): Operation<T, C>[] {
|
|
102
|
+
const ops: Operation<T, C>[] = [];
|
|
103
|
+
|
|
104
|
+
let entry: MatrixEntry<T, C> | undefined = matrix[a.length][b.length];
|
|
105
|
+
|
|
106
|
+
while (entry !== undefined) {
|
|
107
|
+
if (entry.kind === 'change') {
|
|
108
|
+
ops.unshift(entry.change);
|
|
109
|
+
} else if (entry.kind !== 'nop') {
|
|
110
|
+
ops.unshift(entry);
|
|
111
|
+
}
|
|
112
|
+
entry = entry.predecessor;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return ops;
|
|
116
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { SolcBytecode } from './solc-api';
|
|
3
|
+
import { extractLinkReferences, unlinkBytecode, LinkReference } from './link-refs';
|
|
4
|
+
|
|
5
|
+
const bytecodeSolc =
|
|
6
|
+
'0123456789__lib1____abcdef0123__lib2____4567890abcdef0123456__lib3______________789abcdef0123456789';
|
|
7
|
+
const bytecodeArtifact = '0x' + bytecodeSolc;
|
|
8
|
+
const bytecodeLink =
|
|
9
|
+
'0x01234567891ADDRLIB01abcdef01232ADDRLIB024567890abcdef01234563ADDRESSLIB030000000789abcdef0123456789';
|
|
10
|
+
|
|
11
|
+
test('extractLinkReferences', t => {
|
|
12
|
+
const bytecode: SolcBytecode = {
|
|
13
|
+
linkReferences: {
|
|
14
|
+
'a.sol': {
|
|
15
|
+
lib1: [{ length: 5, start: 5 }],
|
|
16
|
+
lib2: [{ length: 5, start: 15 }],
|
|
17
|
+
},
|
|
18
|
+
'b.sol': {
|
|
19
|
+
lib3: [{ length: 10, start: 30 }],
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
object: bytecodeSolc,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const linkReferences: LinkReference[] = extractLinkReferences(bytecode);
|
|
26
|
+
t.is(linkReferences.length, 3);
|
|
27
|
+
t.deepEqual(linkReferences[0], {
|
|
28
|
+
src: 'a.sol',
|
|
29
|
+
name: 'lib1',
|
|
30
|
+
length: 5,
|
|
31
|
+
start: 5,
|
|
32
|
+
placeholder: '__lib1____',
|
|
33
|
+
});
|
|
34
|
+
t.deepEqual(linkReferences[1], {
|
|
35
|
+
src: 'a.sol',
|
|
36
|
+
name: 'lib2',
|
|
37
|
+
length: 5,
|
|
38
|
+
start: 15,
|
|
39
|
+
placeholder: '__lib2____',
|
|
40
|
+
});
|
|
41
|
+
t.deepEqual(linkReferences[2], {
|
|
42
|
+
src: 'b.sol',
|
|
43
|
+
name: 'lib3',
|
|
44
|
+
length: 10,
|
|
45
|
+
start: 30,
|
|
46
|
+
placeholder: '__lib3______________',
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('unlinkBytecode', t => {
|
|
51
|
+
const linkReferences: LinkReference[] = [
|
|
52
|
+
{
|
|
53
|
+
src: 'a.sol',
|
|
54
|
+
name: 'lib1',
|
|
55
|
+
length: 5,
|
|
56
|
+
start: 5,
|
|
57
|
+
placeholder: '__lib1____',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
src: 'a.sol',
|
|
61
|
+
name: 'lib2',
|
|
62
|
+
length: 5,
|
|
63
|
+
start: 15,
|
|
64
|
+
placeholder: '__lib2____',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
src: 'b.sol',
|
|
68
|
+
name: 'lib3',
|
|
69
|
+
length: 10,
|
|
70
|
+
start: 30,
|
|
71
|
+
placeholder: '__lib3______________',
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
const unlinkedBytecode: string = unlinkBytecode(bytecodeLink, linkReferences);
|
|
75
|
+
t.is(unlinkedBytecode.length, bytecodeArtifact.length);
|
|
76
|
+
t.is(unlinkedBytecode, bytecodeArtifact);
|
|
77
|
+
});
|