@openzeppelin/upgrades-core 1.25.0 → 1.26.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/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol/ERC1967Proxy.json +2 -2
- package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json +2 -2
- package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.dbg.json +1 -1
- package/artifacts/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json +2 -2
- package/artifacts/@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol/ProxyAdmin.json +7 -7
- package/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json +2 -72
- package/artifacts/AdminUpgradeabilityProxy.json +2 -72
- package/artifacts/ProxyAdmin.json +7 -7
- package/artifacts/build-info.json +21225 -12
- package/artifacts/contracts/proxy/AdminUpgradeabilityProxy.sol/AdminUpgradeabilityProxy.json +2 -72
- package/artifacts/contracts/proxy/ProxyAdmin.sol/ProxyAdmin.json +7 -7
- package/dist/deployment.d.ts +28 -4
- package/dist/deployment.d.ts.map +1 -1
- package/dist/deployment.js +106 -25
- package/dist/deployment.js.map +1 -1
- package/dist/deployment.test.js +116 -0
- package/dist/deployment.test.js.map +1 -1
- package/dist/impl-store.d.ts +27 -2
- package/dist/impl-store.d.ts.map +1 -1
- package/dist/impl-store.js +39 -8
- package/dist/impl-store.js.map +1 -1
- package/dist/impl-store.test.js +30 -0
- package/dist/impl-store.test.js.map +1 -1
- package/dist/manifest.d.ts +3 -3
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +1 -1
- package/dist/manifest.js.map +1 -1
- package/dist/manifest.test.js +1 -0
- package/dist/manifest.test.js.map +1 -1
- package/dist/validate/error.d.ts +3 -0
- package/dist/validate/error.d.ts.map +1 -1
- package/dist/validate/error.js +7 -1
- package/dist/validate/error.js.map +1 -1
- package/dist/validate/index.d.ts +1 -1
- package/dist/validate/index.d.ts.map +1 -1
- package/dist/validate/index.js +2 -1
- package/dist/validate/index.js.map +1 -1
- package/dist/validate/query.js +1 -1
- package/dist/validate/query.js.map +1 -1
- package/package.json +5 -4
- package/src/deployment.test.ts +182 -1
- package/src/deployment.ts +134 -26
- package/src/impl-store.test.ts +52 -1
- package/src/impl-store.ts +69 -11
- package/src/manifest.test.ts +1 -0
- package/src/manifest.ts +11 -8
- package/src/validate/error.ts +6 -0
- package/src/validate/index.ts +1 -1
- package/src/validate/query.ts +2 -2
package/src/impl-store.ts
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import debug from './utils/debug';
|
|
2
2
|
import { Manifest, ManifestData, ImplDeployment } from './manifest';
|
|
3
3
|
import { EthereumProvider, isDevelopmentNetwork } from './provider';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Deployment,
|
|
6
|
+
RemoteDeploymentId,
|
|
7
|
+
RemoteDeployment,
|
|
8
|
+
InvalidDeployment,
|
|
9
|
+
resumeOrDeploy,
|
|
10
|
+
waitAndValidateDeployment,
|
|
11
|
+
} from './deployment';
|
|
5
12
|
import { Version } from './version';
|
|
6
13
|
import assert from 'assert';
|
|
7
14
|
import { DeployOpts } from '.';
|
|
@@ -26,6 +33,7 @@ export interface ManifestField<T> {
|
|
|
26
33
|
* @param deploy the deploy function
|
|
27
34
|
* @param opts options containing the timeout and pollingInterval parameters. If undefined, assumes the timeout is not configurable and will not mention those parameters in the error message for TransactionMinedTimeout.
|
|
28
35
|
* @param merge if true, adds a deployment to existing deployment by merging their addresses. Defaults to false.
|
|
36
|
+
* @param getRemoteDeployment a function to get the remote deployment status by id. If the deployment id is not found, returns undefined.
|
|
29
37
|
* @returns the deployment
|
|
30
38
|
* @throws {InvalidDeployment} if the deployment is invalid
|
|
31
39
|
* @throws {TransactionMinedTimeout} if the transaction was not confirmed within the timeout period
|
|
@@ -36,6 +44,7 @@ async function fetchOrDeployGeneric<T extends Deployment, U extends T = T>(
|
|
|
36
44
|
deploy: () => Promise<U>,
|
|
37
45
|
opts?: DeployOpts,
|
|
38
46
|
merge?: boolean,
|
|
47
|
+
getRemoteDeployment?: (remoteDeploymentId: string) => Promise<RemoteDeployment | undefined>,
|
|
39
48
|
): Promise<U | Deployment> {
|
|
40
49
|
const manifest = await Manifest.forNetwork(provider);
|
|
41
50
|
|
|
@@ -51,7 +60,16 @@ async function fetchOrDeployGeneric<T extends Deployment, U extends T = T>(
|
|
|
51
60
|
}
|
|
52
61
|
|
|
53
62
|
const stored = deployment.get();
|
|
54
|
-
const updated = await resumeOrDeploy(
|
|
63
|
+
const updated = await resumeOrDeploy(
|
|
64
|
+
provider,
|
|
65
|
+
stored,
|
|
66
|
+
deploy,
|
|
67
|
+
lens.type,
|
|
68
|
+
opts,
|
|
69
|
+
deployment,
|
|
70
|
+
merge,
|
|
71
|
+
getRemoteDeployment,
|
|
72
|
+
);
|
|
55
73
|
if (updated !== stored) {
|
|
56
74
|
if (merge && deployment.merge) {
|
|
57
75
|
// only check primary addresses for clashes, since the address could already exist in an allAddresses field
|
|
@@ -67,7 +85,7 @@ async function fetchOrDeployGeneric<T extends Deployment, U extends T = T>(
|
|
|
67
85
|
return updated;
|
|
68
86
|
});
|
|
69
87
|
|
|
70
|
-
await waitAndValidateDeployment(provider, deployment, lens.type, opts);
|
|
88
|
+
await waitAndValidateDeployment(provider, deployment, lens.type, opts, getRemoteDeployment);
|
|
71
89
|
|
|
72
90
|
return deployment;
|
|
73
91
|
} catch (e) {
|
|
@@ -98,6 +116,18 @@ export function deleteDeployment(deployment: ManifestField<Deployment>) {
|
|
|
98
116
|
deployment.set(undefined);
|
|
99
117
|
}
|
|
100
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Fetches the deployment address from the manifest, or deploys it if not found and returns the address.
|
|
121
|
+
*
|
|
122
|
+
* @param version the contract version
|
|
123
|
+
* @param provider the Ethereum provider
|
|
124
|
+
* @param deploy the deploy function
|
|
125
|
+
* @param opts options containing the timeout and pollingInterval parameters. If undefined, assumes the timeout is not configurable and will not mention those parameters in the error message for TransactionMinedTimeout.
|
|
126
|
+
* @param merge if true, adds a deployment to existing deployment by merging their addresses. Defaults to false.
|
|
127
|
+
* @returns the deployment address
|
|
128
|
+
* @throws {InvalidDeployment} if the deployment is invalid
|
|
129
|
+
* @throws {TransactionMinedTimeout} if the transaction was not confirmed within the timeout period
|
|
130
|
+
*/
|
|
101
131
|
export async function fetchOrDeploy(
|
|
102
132
|
version: Version,
|
|
103
133
|
provider: EthereumProvider,
|
|
@@ -108,14 +138,35 @@ export async function fetchOrDeploy(
|
|
|
108
138
|
return (await fetchOrDeployGeneric(implLens(version.linkedWithoutMetadata), provider, deploy, opts, merge)).address;
|
|
109
139
|
}
|
|
110
140
|
|
|
141
|
+
/**
|
|
142
|
+
* Fetches the deployment from the manifest, or deploys it if not found and returns the deployment.
|
|
143
|
+
*
|
|
144
|
+
* @param version the contract version
|
|
145
|
+
* @param provider the Ethereum provider
|
|
146
|
+
* @param deploy the deploy function
|
|
147
|
+
* @param opts options containing the timeout and pollingInterval parameters. If undefined, assumes the timeout is not configurable and will not mention those parameters in the error message for TransactionMinedTimeout.
|
|
148
|
+
* @param merge if true, adds a deployment to existing deployment by merging their addresses. Defaults to false.
|
|
149
|
+
* @param getRemoteDeployment a function to get the remote deployment status by id. If the deployment id is not found, returns undefined.
|
|
150
|
+
* @returns the deployment
|
|
151
|
+
* @throws {InvalidDeployment} if the deployment is invalid
|
|
152
|
+
* @throws {TransactionMinedTimeout} if the transaction was not confirmed within the timeout period
|
|
153
|
+
*/
|
|
111
154
|
export async function fetchOrDeployGetDeployment<T extends ImplDeployment>(
|
|
112
155
|
version: Version,
|
|
113
156
|
provider: EthereumProvider,
|
|
114
157
|
deploy: () => Promise<T>,
|
|
115
158
|
opts?: DeployOpts,
|
|
116
159
|
merge?: boolean,
|
|
160
|
+
getRemoteDeployment?: (remoteDeploymentId: string) => Promise<RemoteDeployment | undefined>,
|
|
117
161
|
): Promise<T | Deployment> {
|
|
118
|
-
return fetchOrDeployGeneric(
|
|
162
|
+
return fetchOrDeployGeneric(
|
|
163
|
+
implLens(version.linkedWithoutMetadata),
|
|
164
|
+
provider,
|
|
165
|
+
deploy,
|
|
166
|
+
opts,
|
|
167
|
+
merge,
|
|
168
|
+
getRemoteDeployment,
|
|
169
|
+
);
|
|
119
170
|
}
|
|
120
171
|
|
|
121
172
|
const implLens = (versionWithoutMetadata: string) =>
|
|
@@ -171,7 +222,7 @@ function lens<T>(description: string, type: string, fn: (data: ManifestData) =>
|
|
|
171
222
|
async function checkForAddressClash(
|
|
172
223
|
provider: EthereumProvider,
|
|
173
224
|
data: ManifestData,
|
|
174
|
-
updated: Deployment,
|
|
225
|
+
updated: Deployment & RemoteDeploymentId,
|
|
175
226
|
checkAllAddresses: boolean,
|
|
176
227
|
): Promise<void> {
|
|
177
228
|
const clash = lookupDeployment(data, updated.address, checkAllAddresses);
|
|
@@ -180,11 +231,18 @@ async function checkForAddressClash(
|
|
|
180
231
|
debug('deleting a previous deployment at address', updated.address);
|
|
181
232
|
clash.set(undefined);
|
|
182
233
|
} else {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
234
|
+
const existing = clash.get();
|
|
235
|
+
// it's a clash if there is no deployment id or if deployment ids don't match
|
|
236
|
+
if (
|
|
237
|
+
existing !== undefined &&
|
|
238
|
+
(existing.remoteDeploymentId === undefined || existing.remoteDeploymentId !== updated.remoteDeploymentId)
|
|
239
|
+
) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`The following deployment clashes with an existing one at ${updated.address}\n\n` +
|
|
242
|
+
JSON.stringify(updated, null, 2) +
|
|
243
|
+
`\n\n`,
|
|
244
|
+
);
|
|
245
|
+
}
|
|
188
246
|
}
|
|
189
247
|
}
|
|
190
248
|
}
|
|
@@ -193,7 +251,7 @@ function lookupDeployment(
|
|
|
193
251
|
data: ManifestData,
|
|
194
252
|
address: string,
|
|
195
253
|
checkAllAddresses: boolean,
|
|
196
|
-
): ManifestField<Deployment> | undefined {
|
|
254
|
+
): ManifestField<Deployment & RemoteDeploymentId> | undefined {
|
|
197
255
|
if (data.admin?.address === address) {
|
|
198
256
|
return adminLens(data);
|
|
199
257
|
}
|
package/src/manifest.test.ts
CHANGED
package/src/manifest.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { EthereumProvider, getChainId, getHardhatMetadata, networkNames } from '
|
|
|
5
5
|
import lockfile from 'proper-lockfile';
|
|
6
6
|
import { compare as compareVersions } from 'compare-versions';
|
|
7
7
|
|
|
8
|
-
import type { Deployment } from './deployment';
|
|
8
|
+
import type { Deployment, RemoteDeploymentId } from './deployment';
|
|
9
9
|
import type { StorageLayout } from './storage';
|
|
10
10
|
import { pick } from './utils/pick';
|
|
11
11
|
import { mapValues } from './utils/map-values';
|
|
@@ -18,9 +18,9 @@ const currentManifestVersion = '3.2';
|
|
|
18
18
|
export interface ManifestData {
|
|
19
19
|
manifestVersion: string;
|
|
20
20
|
impls: {
|
|
21
|
-
[version in string]?: ImplDeployment;
|
|
21
|
+
[version in string]?: ImplDeployment & RemoteDeploymentId;
|
|
22
22
|
};
|
|
23
|
-
proxies: ProxyDeployment[];
|
|
23
|
+
proxies: (ProxyDeployment & RemoteDeploymentId)[];
|
|
24
24
|
admin?: Deployment;
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -318,11 +318,14 @@ export function normalizeManifestData(input: ManifestData): ManifestData {
|
|
|
318
318
|
};
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
-
function normalizeDeployment<D extends Deployment>(input: D): Deployment;
|
|
322
|
-
function normalizeDeployment<D extends Deployment, K extends keyof D>(
|
|
323
|
-
|
|
321
|
+
function normalizeDeployment<D extends Deployment & RemoteDeploymentId>(input: D): Deployment & RemoteDeploymentId;
|
|
322
|
+
function normalizeDeployment<D extends Deployment & RemoteDeploymentId, K extends keyof D>(
|
|
323
|
+
input: D,
|
|
324
|
+
include: K[],
|
|
325
|
+
): Deployment & RemoteDeploymentId & Pick<D, K>;
|
|
326
|
+
function normalizeDeployment<D extends Deployment & RemoteDeploymentId, K extends keyof D>(
|
|
324
327
|
input: D,
|
|
325
328
|
include: K[] = [],
|
|
326
|
-
): Deployment & Pick<D, K> {
|
|
327
|
-
return pick(input, ['address', 'txHash', ...include]);
|
|
329
|
+
): Deployment & RemoteDeploymentId & Pick<D, K> {
|
|
330
|
+
return pick(input, ['address', 'txHash', 'remoteDeploymentId', ...include]);
|
|
328
331
|
}
|
package/src/validate/error.ts
CHANGED
|
@@ -9,3 +9,9 @@ export class ValidationErrors extends UpgradesError {
|
|
|
9
9
|
);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
export class ContractSourceNotFoundError extends UpgradesError {
|
|
14
|
+
constructor() {
|
|
15
|
+
super('The requested contract was not found. Make sure the source code is available for compilation');
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/validate/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { validate, ValidationRunData, ContractValidation } from './run';
|
|
2
2
|
export { ProxyKindOption, StandaloneValidationOptions, ValidationOptions, withValidationDefaults } from './overrides';
|
|
3
|
-
export { ValidationErrors } from './error';
|
|
3
|
+
export { ValidationErrors, ContractSourceNotFoundError } from './error';
|
|
4
4
|
export { RunValidation, ValidationLog, Validation, ValidationResult } from './compat';
|
|
5
5
|
export { ValidationData, ValidationDataCurrent, isCurrentValidationData, concatRunData } from './data';
|
|
6
6
|
export {
|
package/src/validate/query.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ValidationRunData, ValidationError, isOpcodeError } from './run';
|
|
|
3
3
|
import { StorageLayout } from '../storage/layout';
|
|
4
4
|
import { unlinkBytecode } from '../link-refs';
|
|
5
5
|
import { ValidationOptions, processExceptions } from './overrides';
|
|
6
|
-
import { ValidationErrors } from './error';
|
|
6
|
+
import { ContractSourceNotFoundError, ValidationErrors } from './error';
|
|
7
7
|
import { ValidationData, normalizeValidationData } from './data';
|
|
8
8
|
import { ProxyDeployment } from '../manifest';
|
|
9
9
|
|
|
@@ -72,7 +72,7 @@ export function getContractNameAndRunValidation(data: ValidationData, version: V
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
if (fullContractName === undefined || runValidation === undefined) {
|
|
75
|
-
throw new
|
|
75
|
+
throw new ContractSourceNotFoundError();
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
return [fullContractName, runValidation];
|