@openzeppelin/upgrades-core 1.13.1 → 1.14.2
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/dist/proxy-kind.d.ts +4 -0
- package/dist/proxy-kind.d.ts.map +1 -1
- package/dist/proxy-kind.js +4 -0
- package/dist/proxy-kind.js.map +1 -1
- package/dist/standalone.test.js +9 -0
- package/dist/standalone.test.js.map +1 -1
- package/dist/storage/compare.d.ts +15 -4
- package/dist/storage/compare.d.ts.map +1 -1
- package/dist/storage/compare.js +49 -4
- package/dist/storage/compare.js.map +1 -1
- package/dist/storage/extract.d.ts.map +1 -1
- package/dist/storage/extract.js +27 -3
- package/dist/storage/extract.js.map +1 -1
- package/dist/storage/layout.d.ts +14 -0
- package/dist/storage/layout.d.ts.map +1 -1
- package/dist/storage/layout.js +6 -2
- package/dist/storage/layout.js.map +1 -1
- package/dist/storage/report-rename-retype.test.d.ts +2 -0
- package/dist/storage/report-rename-retype.test.d.ts.map +1 -0
- package/dist/storage/report-rename-retype.test.js +93 -0
- package/dist/storage/report-rename-retype.test.js.map +1 -0
- package/dist/storage/report.d.ts.map +1 -1
- package/dist/storage/report.js +32 -2
- package/dist/storage/report.js.map +1 -1
- package/dist/storage/report.test.js +6 -0
- package/dist/storage/report.test.js.map +1 -1
- package/dist/storage.test.js +1 -1
- package/dist/utils/execall.d.ts +2 -0
- package/dist/utils/execall.d.ts.map +1 -0
- package/dist/utils/execall.js +17 -0
- package/dist/utils/execall.js.map +1 -0
- package/package.json +2 -2
- package/src/proxy-kind.ts +4 -0
- package/src/standalone.test.ts +12 -0
- package/src/storage/compare.ts +61 -8
- package/src/storage/extract.ts +31 -5
- package/src/storage/layout.ts +17 -2
- package/src/storage/report-rename-retype.test.ts +106 -0
- package/src/storage/report-rename-retype.test.ts.md +44 -0
- package/src/storage/report-rename-retype.test.ts.snap +0 -0
- package/src/storage/report.test.ts +7 -0
- package/src/storage/report.test.ts.md +11 -0
- package/src/storage/report.test.ts.snap +0 -0
- package/src/storage/report.ts +39 -4
- package/src/storage.test.ts +1 -1
- package/src/storage.test.ts.md +146 -0
- package/src/storage.test.ts.snap +0 -0
- package/src/utils/execall.ts +11 -0
|
@@ -59,6 +59,13 @@ test('obvious mismatch', t => {
|
|
|
59
59
|
t.snapshot(report.explain());
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
+
test('function visibility change', t => {
|
|
63
|
+
const v1 = t.context.extractStorageLayout('StorageUpgrade_FunctionType_Visibility_V1');
|
|
64
|
+
const v2 = t.context.extractStorageLayout('StorageUpgrade_FunctionType_Visibility_V2_Bad');
|
|
65
|
+
const report = getReport(v1, v2);
|
|
66
|
+
t.snapshot(report.explain());
|
|
67
|
+
});
|
|
68
|
+
|
|
62
69
|
test('array', t => {
|
|
63
70
|
const v1 = t.context.extractStorageLayout('StorageUpgrade_Array_V1');
|
|
64
71
|
const v2 = t.context.extractStorageLayout('StorageUpgrade_Array_V2_Bad');
|
|
@@ -90,6 +90,17 @@ Generated by [AVA](https://avajs.dev).
|
|
|
90
90
|
file.sol:1: Upgraded \`a1\` to an incompatible type␊
|
|
91
91
|
- Bad upgrade from uint256[] to mapping(uint256 => uint256)`
|
|
92
92
|
|
|
93
|
+
## function visibility change
|
|
94
|
+
|
|
95
|
+
> Snapshot 1
|
|
96
|
+
|
|
97
|
+
`file.sol:1: Upgraded \`s1\` to an incompatible type␊
|
|
98
|
+
- Bad upgrade from struct StorageUpgrade_FunctionType_Visibility_V1.S to struct StorageUpgrade_FunctionType_Visibility_V2_Bad.S␊
|
|
99
|
+
- In struct StorageUpgrade_FunctionType_Visibility_V2_Bad.S␊
|
|
100
|
+
- Upgraded \`m\` to an incompatible type␊
|
|
101
|
+
- Bad upgrade from function () to function () external␊
|
|
102
|
+
Different visibility`
|
|
103
|
+
|
|
93
104
|
## array
|
|
94
105
|
|
|
95
106
|
> Snapshot 1
|
|
Binary file
|
package/src/storage/report.ts
CHANGED
|
@@ -2,7 +2,7 @@ import _chalk from 'chalk';
|
|
|
2
2
|
|
|
3
3
|
import type { BasicOperation } from '../levenshtein';
|
|
4
4
|
import type { ParsedTypeDetailed } from './layout';
|
|
5
|
-
import type { StorageOperation, StorageItem, StorageField, TypeChange, EnumOperation } from './compare';
|
|
5
|
+
import type { StorageOperation, StorageItem, StorageField, TypeChange, EnumOperation, LayoutChange } from './compare';
|
|
6
6
|
import { itemize, itemizeWith } from '../utils/itemize';
|
|
7
7
|
import { indent } from '../utils/indent';
|
|
8
8
|
import { assert } from '../utils/assert';
|
|
@@ -22,8 +22,12 @@ export class LayoutCompatibilityReport {
|
|
|
22
22
|
const chalk = new _chalk.Instance({ level: color && _chalk.supportsColor ? _chalk.supportsColor.level : 0 });
|
|
23
23
|
const res = [];
|
|
24
24
|
|
|
25
|
-
for (const op of this.ops) {
|
|
25
|
+
for (const [i, op] of this.ops.entries()) {
|
|
26
26
|
const src = 'updated' in op ? op.updated.src : op.original.contract;
|
|
27
|
+
// Only print layoutchange if it's the first op, otherwise we assume it will be explained by previous ops.
|
|
28
|
+
if (op.kind === 'layoutchange' && i !== 0) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
27
31
|
res.push(
|
|
28
32
|
chalk.bold(src) + ':' + indent(explainStorageOperation(op, { kind: 'layout', allowAppend: true }), 2, 1),
|
|
29
33
|
);
|
|
@@ -52,13 +56,20 @@ function explainStorageOperation(op: StorageOperation<StorageField>, ctx: Storag
|
|
|
52
56
|
: [];
|
|
53
57
|
return `Upgraded ${label(op.updated)} to an incompatible type\n` + itemize(basic, ...details);
|
|
54
58
|
}
|
|
55
|
-
|
|
56
59
|
case 'rename':
|
|
57
60
|
return `Renamed ${label(op.original)} to ${label(op.updated)}`;
|
|
58
61
|
|
|
59
62
|
case 'replace':
|
|
60
63
|
return `Replaced ${label(op.original)} with ${label(op.updated)} of incompatible type`;
|
|
61
64
|
|
|
65
|
+
case 'layoutchange': {
|
|
66
|
+
return (
|
|
67
|
+
`Layout ${op.change.uncertain ? 'could have changed' : 'changed'} for ${label(op.updated)} ` +
|
|
68
|
+
`(${op.original.type.item.label} -> ${op.updated.type.item.label})\n` +
|
|
69
|
+
describeLayoutTransition(op.change)
|
|
70
|
+
).trimEnd();
|
|
71
|
+
}
|
|
72
|
+
|
|
62
73
|
default: {
|
|
63
74
|
const title = explainBasicOperation(op, t => t.label);
|
|
64
75
|
const hints = [];
|
|
@@ -90,6 +101,9 @@ function explainStorageOperation(op: StorageOperation<StorageField>, ctx: Storag
|
|
|
90
101
|
|
|
91
102
|
function explainTypeChange(ch: TypeChange): string {
|
|
92
103
|
switch (ch.kind) {
|
|
104
|
+
case 'visibility change':
|
|
105
|
+
return `Bad upgrade ${describeTransition(ch.original, ch.updated)}\nDifferent visibility`;
|
|
106
|
+
|
|
93
107
|
case 'obvious mismatch':
|
|
94
108
|
case 'struct members':
|
|
95
109
|
case 'enum members':
|
|
@@ -172,7 +186,16 @@ function explainTypeChangeDetails(ch: TypeChange): string | undefined {
|
|
|
172
186
|
const { allowAppend } = ch;
|
|
173
187
|
return (
|
|
174
188
|
`In ${ch.updated.item.label}\n` +
|
|
175
|
-
itemize(
|
|
189
|
+
itemize(
|
|
190
|
+
...ch.ops.flatMap((op, i) => {
|
|
191
|
+
if (op.kind === 'layoutchange' && i !== 0) {
|
|
192
|
+
// Only print layoutchange if it's the first op, otherwise we assume it will be explained by previous ops.
|
|
193
|
+
return [];
|
|
194
|
+
} else {
|
|
195
|
+
return [explainStorageOperation(op, { kind: 'struct', allowAppend })];
|
|
196
|
+
}
|
|
197
|
+
}),
|
|
198
|
+
)
|
|
176
199
|
);
|
|
177
200
|
}
|
|
178
201
|
|
|
@@ -215,6 +238,18 @@ function describeTransition(original: ParsedTypeDetailed, updated: ParsedTypeDet
|
|
|
215
238
|
}
|
|
216
239
|
}
|
|
217
240
|
|
|
241
|
+
function describeLayoutTransition(change: LayoutChange): string {
|
|
242
|
+
const res = [];
|
|
243
|
+
for (const k of ['slot', 'offset', 'bytes'] as const) {
|
|
244
|
+
const ch = change[k];
|
|
245
|
+
if (ch) {
|
|
246
|
+
const label = (k === 'bytes' ? 'number of bytes' : k).replace(/^./, c => c.toUpperCase());
|
|
247
|
+
res.push(`${label} changed from ${ch.from} to ${ch.to}`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return itemize(...res);
|
|
251
|
+
}
|
|
252
|
+
|
|
218
253
|
function label(variable: { label: string }): string {
|
|
219
254
|
return '`' + variable.label + '`';
|
|
220
255
|
}
|