Skip to content

Commit

Permalink
Added a section to Michelson Encoder doc about the breaking change, f…
Browse files Browse the repository at this point in the history
…ixed TypeCheck method example (#3002)

* docs: added a section to michelson encoder docs about breaking change, fixed typecheck doc

* docs: use a smaller example, enable live code blocks for the example

* docs: fix typo, add example to a hard-to-understand sentence
  • Loading branch information
ac10n committed Jul 8, 2024
1 parent 97832fc commit 22d8aea
Show file tree
Hide file tree
Showing 3 changed files with 239 additions and 13 deletions.
124 changes: 118 additions & 6 deletions docs/michelson_encoder.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ The purpose of the `Michelson-Encoder` package is to create an abstraction over

Its integration into the main `Taquito` package makes it easier to write the storage when deploying a contract and the parameter when calling a contract entry-point.

:::info
With the release of Taquito vevsion 20.0.0, we have made a breaking change in the Michelson Encoder package.
Please check the [Breaking Change to Field Numbering](#breaking-change-to-field-numbering) section of this document for more information and how to enable the old behavior.
:::

## How it works?

There are three main classes in the Michelson Encoder:
Expand Down Expand Up @@ -264,12 +269,16 @@ const storageType = {
]
};
const storageSchema = new Schema(storageType);
const typecheck = storageSchema.Typecheck({
stored_counter: 10,
threshold: 5,
keys: ['edpkuLxx9PQD8fZ45eUzrK3yhfDZJHhBuK4Zi49DcEGANwd2rpX82t']
})
console.log(typecheck);
try {
storageSchema.Typecheck({
stored_counter: 10,
threshold: 5,
keys: ['edpkuLxx9PQD8fZ45eUzrK3yhfDZJHhBuK4Zi49DcEGANwd2rpX82t']
})
console.log('Storage object is valid');
} catch (e) {
console.log(`Storage is not valid: ${e}`);
}
```

### The Encode method
Expand Down Expand Up @@ -533,3 +542,106 @@ const storageSchema = new Schema({
const mixedSchema = storageSchema.ExtractSchema();
console.log(JSON.stringify(mixedSchema, null, 2));
```

## Breaking Change to Field Numbering {#breaking-change-to-field-numbering}
When having nested `pair`s or unions (`or`), Taquito assigns numbers to fields when an annotation is not present.
In previous versions of Taquito, the nested object's fields were numbered were a continuation of the parent object's fields.
For example, the following schema:

```js live noInline
const param = {
prim: 'or',
args: [
{
prim: 'pair',
args: [{ prim: 'address' }, { prim: 'nat' }],
annots: ['%transfer']
},
{
prim: 'or',
args: [
{
prim: 'pair',
args: [{ prim: 'address' }, { prim: 'nat' }],
annots: ['%approve']
},
{
prim: 'pair',
args: [{ prim: 'address' }, { prim: 'nat' }],
annots: ['%mint']
}
]
}
],
annots: [':_entries']
};
const parameterSchema = new ParameterSchema(param);
Token.fieldNumberingStrategy = "Legacy"; //To bring back the old behavior
const value = parameterSchema.generateSchema();
console.log(JSON.stringify(value, null, 2));
Token.fieldNumberingStrategy = 'Latest'; //To restore the default (new) behavior
```

Please run the code above and check the output.

Please note how nested field numbers are not predictable. The field numbers are assigned in the order their parent were encountered during the traversal of the tree. For instance, in the above example, `approve` would get a field number of `1`. Because it has annotations, the field number is not used. But its nested fields would be numbered starting from `1` and not `2`.

While this behavior is not an error, it is prone to unexpected changes when the schema is modified. Also, predicting the field number of a specific field is not straightforward.

With the release of Taquito version 20.0.0, we have made a breaking change in the Michelson Encoder package. The field numbering is now predictable and consistent.
The field numbers for each nested object (`Or`/`Pair`) are now reset from zero. You can see that by commenting out the line: `Token.fieldNumberingStrategy = "Legacy";` and running the code again.

Below you can see a diff of the new versus old behavior:

```diff
{
"__michelsonType": "or",
"schema": {
"transfer": {
"__michelsonType": "pair",
"schema": {
"0": {
"__michelsonType": "address",
"schema": "address"
},
"1": {
"__michelsonType": "nat",
"schema": "nat"
}
}
},
"approve": {
"__michelsonType": "pair",
"schema": {
- "1": {
+ "0": {
"__michelsonType": "address",
"schema": "address"
},
- "2": {
+ "1": {
"__michelsonType": "nat",
"schema": "nat"
}
}
},
"mint": {
"__michelsonType": "pair",
"schema": {
- "2": {
+ "0": {
"__michelsonType": "address",
"schema": "address"
},
- "3": {
+ "1": {
"__michelsonType": "nat",
"schema": "nat"
}
}
}
}
}
```
You can enable the old behavior by setting the `Token.fieldNumberingStrategy = 'Legacy'`. Please note that this value should stay the same for the whole application.
The possible values are: `type FieldNumberingStrategy = 'Legacy' | 'ResetFieldNumbersInNestedObjects' | 'Latest';` For new applications, we recommend using the default value `Latest`.
4 changes: 3 additions & 1 deletion website/src/theme/CodeBlock/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ export default ({
const { LedgerSigner, DerivationType } = await import('@taquito/ledger-signer');
const { Tzip16Module, tzip16, MichelsonStorageView } = await import('@taquito/tzip16')
const { Tzip12Module, tzip12 } = await import("@taquito/tzip12");
const { Schema, ParameterSchema } = await import("@taquito/michelson-encoder");
const { Schema, ParameterSchema, Token } = await import("@taquito/michelson-encoder");
const { Parser, packDataBytes, emitMicheline } = await import('@taquito/michel-codec');
const { RpcClient } = await import('@taquito/rpc');
const TransportWebHID = (await import("@ledgerhq/hw-transport-webhid")).default;
Expand Down Expand Up @@ -128,6 +128,7 @@ export default ({
compose,
Schema,
ParameterSchema,
Token,
getRevealFee,
verifySignature,
Parser,
Expand Down Expand Up @@ -185,6 +186,7 @@ export default ({
compose: dependencies?.compose,
Schema: dependencies?.Schema,
ParameterSchema: dependencies?.ParameterSchema,
Token: dependencies?.Token,
getRevealFee: dependencies?.getRevealFee,
verifySignature: dependencies?.verifySignature,
Parser: dependencies?.Parser,
Expand Down
124 changes: 118 additions & 6 deletions website/versioned_docs/version-20.0.0/michelson_encoder.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ The purpose of the `Michelson-Encoder` package is to create an abstraction over

Its integration into the main `Taquito` package makes it easier to write the storage when deploying a contract and the parameter when calling a contract entry-point.

:::info
With the release of Taquito vevsion 20.0.0, we have made a breaking change in the Michelson Encoder package.
Please check the [Breaking Change to Field Numbering](#breaking-change-to-field-numbering) section of this document for more information and how to enable the old behavior.
:::

## How it works?

There are three main classes in the Michelson Encoder:
Expand Down Expand Up @@ -264,12 +269,16 @@ const storageType = {
]
};
const storageSchema = new Schema(storageType);
const typecheck = storageSchema.Typecheck({
stored_counter: 10,
threshold: 5,
keys: ['edpkuLxx9PQD8fZ45eUzrK3yhfDZJHhBuK4Zi49DcEGANwd2rpX82t']
})
console.log(typecheck);
try {
storageSchema.Typecheck({
stored_counter: 10,
threshold: 5,
keys: ['edpkuLxx9PQD8fZ45eUzrK3yhfDZJHhBuK4Zi49DcEGANwd2rpX82t']
})
console.log('Storage object is valid');
} catch (e) {
console.log(`Storage is not valid: ${e}`);
}
```

### The Encode method
Expand Down Expand Up @@ -533,3 +542,106 @@ const storageSchema = new Schema({
const mixedSchema = storageSchema.ExtractSchema();
console.log(JSON.stringify(mixedSchema, null, 2));
```

## Breaking Change to Field Numbering {#breaking-change-to-field-numbering}
When having nested `pair`s or unions (`or`), Taquito assigns numbers to fields when an annotation is not present.
In previous versions of Taquito, the nested object's fields were numbered were a continuation of the parent object's fields.
For example, the following schema:

```js live noInline
const param = {
prim: 'or',
args: [
{
prim: 'pair',
args: [{ prim: 'address' }, { prim: 'nat' }],
annots: ['%transfer']
},
{
prim: 'or',
args: [
{
prim: 'pair',
args: [{ prim: 'address' }, { prim: 'nat' }],
annots: ['%approve']
},
{
prim: 'pair',
args: [{ prim: 'address' }, { prim: 'nat' }],
annots: ['%mint']
}
]
}
],
annots: [':_entries']
};
const parameterSchema = new ParameterSchema(param);
Token.fieldNumberingStrategy = "Legacy"; //To bring back the old behavior
const value = parameterSchema.generateSchema();
console.log(JSON.stringify(value, null, 2));
Token.fieldNumberingStrategy = 'Latest'; //To restore the default (new) behavior
```

Please run the code above and check the output.

Please note how nested field numbers are not predictable. The field numbers are assigned in the order their parent were encountered during the traversal of the tree. For instance, in the above example, `approve` would get a field number of `1`. Because it has annotations, the field number is not used. But its nested fields would be numbered starting from `1` and not `2`.

While this behavior is not an error, it is prone to unexpected changes when the schema is modified. Also, predicting the field number of a specific field is not straightforward.

With the release of Taquito version 20.0.0, we have made a breaking change in the Michelson Encoder package. The field numbering is now predictable and consistent.
The field numbers for each nested object (`Or`/`Pair`) are now reset from zero. You can see that by commenting out the line: `Token.fieldNumberingStrategy = "Legacy";` and running the code again.

Below you can see a diff of the new versus old behavior:

```diff
{
"__michelsonType": "or",
"schema": {
"transfer": {
"__michelsonType": "pair",
"schema": {
"0": {
"__michelsonType": "address",
"schema": "address"
},
"1": {
"__michelsonType": "nat",
"schema": "nat"
}
}
},
"approve": {
"__michelsonType": "pair",
"schema": {
- "1": {
+ "0": {
"__michelsonType": "address",
"schema": "address"
},
- "2": {
+ "1": {
"__michelsonType": "nat",
"schema": "nat"
}
}
},
"mint": {
"__michelsonType": "pair",
"schema": {
- "2": {
+ "0": {
"__michelsonType": "address",
"schema": "address"
},
- "3": {
+ "1": {
"__michelsonType": "nat",
"schema": "nat"
}
}
}
}
}
```
You can enable the old behavior by setting the `Token.fieldNumberingStrategy = 'Legacy'`. Please note that this value should stay the same for the whole application.
The possible values are: `type FieldNumberingStrategy = 'Legacy' | 'ResetFieldNumbersInNestedObjects' | 'Latest';` For new applications, we recommend using the default value `Latest`.

0 comments on commit 22d8aea

Please sign in to comment.