sui icon indicating copy to clipboard operation
sui copied to clipboard

[RFC][BCS/TS] Support multiple schemas

Open amnn opened this issue 2 years ago • 0 comments

Currently, bcs accumulates registered types in a singleton, updated by static functions so it's only possible to have one interface for each type name. This proposal suggests adding the ability to create new instances of the bcs, each with their own types registered.

Motivation

#4878 introduces a backwards incompatible change to Sui's BCS schema (the addition of a field, deep within the structure of a Move Call Transaction). For backwards compatibility, the TypeScript SDK needs to be able to talk to both the old and new schemas. This was achieved by:

https://github.com/MystenLabs/sui/blob/d379a70a37caf4e2acf7b9aa9cfcf6a1a278aa66/sdk/typescript/src/types/sui-bcs.ts#L316-L363

  • Supplying a different root type name during serialization, based on the version advertised by the RPC Provider:

https://github.com/MystenLabs/sui/blob/d379a70a37caf4e2acf7b9aa9cfcf6a1a278aa66/sdk/typescript/src/signers/txn-data-serializers/local-txn-data-serializer.ts#L345-L349

But this is quite error-prone and cumbersome, especially if we need to manage multiple unrelated schema changes. Ideally, instead of this approach, we could define multiple schemas (or a function that returns a schema, based on RPC version), so the example above becomes:

// sui-bcs.ts
function bcsSchema(version: string): BCS {
  const bcs = new BCS();

  /* ... */

  if (version === "0.11.0" || version === "0.12.0") {
    bcs.registerEnumType('ObjectArg', {
      ImmOrOwned: 'SuiObjectRef',
      Shared_Deprecated: 'ObjectID',
    });
  } else {
    bcs.registerStructType('SharedObjectRef', {
      objectId: 'ObjectID',
      initialSharedVersion: 'u64',
    });

    bcs.registerEnumType('ObjectArg', {
      ImmOrOwned: 'SuiObjectRef',
      Shared: 'SharedObjectRef',
    });
  }

 /* ... */

  return bcs;
}

export function bcsForAPI(version: string): BCS {
  /* wrapper to the above, with caching */
}

// local-txn-data-serializer.ts
const dataBytes = bcsForAPI(version).ser('TransactionData', tx, size).toBytes(); 

amnn avatar Oct 19 '22 14:10 amnn