From 8f8f2297f73b379d2928c0789a2a2efed341c5ac Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Mon, 8 May 2023 12:25:27 +0200 Subject: [PATCH 01/12] Fixed bug where `getBlockInfo` throws error on genesis blocks. --- packages/common/CHANGELOG.md | 5 +++++ packages/common/src/GRPCTypeTranslation.ts | 2 +- packages/common/src/types.ts | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index d9e062072..7c56b8e03 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + +### Changed +- Updated `blockInfo` so that the `bakerId` field is optional, since it will be undefined for genesis blocks. + ## 6.5.0 2023-5-03 ### Added diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 47c597783..71cc45988 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2078,7 +2078,7 @@ export function blockInfo(blockInfo: v2.BlockInfo): v1.BlockInfo { blockStateHash: unwrapValToHex(blockInfo.stateHash), blockLastFinalized: unwrapValToHex(blockInfo.lastFinalizedBlock), blockHeight: unwrap(blockInfo.height?.value), - blockBaker: unwrap(blockInfo.baker?.value), + blockBaker: blockInfo.baker?.value, blockSlot: unwrap(blockInfo.slotNumber?.value), blockArriveTime: trTimestamp(blockInfo.arriveTime), blockReceiveTime: trTimestamp(blockInfo.receiveTime), diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index c0727ad43..807f9d0a8 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -583,7 +583,7 @@ export interface BlockInfo { blockLastFinalized: HexString; blockHeight: bigint; - blockBaker: BakerId; + blockBaker?: BakerId; blockSlot: bigint; blockArriveTime: Date; From 1a780a2647881fe5d411c713721198363423ff63 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Wed, 10 May 2023 15:18:10 +0200 Subject: [PATCH 02/12] Fixed bug where the versioning info of schemas was lost Also changed syntax highlighting from `js` to `ts` --- docs/CIS2Contract.md | 22 +++++----- docs/gRPC.md | 8 ++-- docs/grpc-v1.md | 62 +++++++++++++-------------- examples/client/getModuleSource.ts | 4 +- packages/common/CHANGELOG.md | 5 +++ packages/common/src/GRPCClient.ts | 19 +++++--- packages/common/src/types.ts | 5 +++ packages/nodejs/test/clientV2.test.ts | 7 ++- 8 files changed, 77 insertions(+), 55 deletions(-) diff --git a/docs/CIS2Contract.md b/docs/CIS2Contract.md index 65250f13b..b15d1f1ee 100644 --- a/docs/CIS2Contract.md +++ b/docs/CIS2Contract.md @@ -20,14 +20,14 @@ The CIS2Contract class wraps the [ConcordiumNodeClient]('./gRPC.md'), defining a ## Creating a CIS2Contract The contract relies on a `ConcordiumNodeClient` instance to communicate with the node along with a contract address of the CIS-2 contract to invoke functions on. -```js +```ts const contractAddress = {index: 1234n, subindex: 0n}; const contract = await CIS2Contract.create(nodeClient, contractAddress); // Implied that you already have a `ConcordiumNodeClient` instance of some form. ``` This gets the relevant contract information from the node and checks that the contract is in fact a CIS-2 contract (through the [CIS-0 supports function](../packages/common/README.md#check-smart-contract-for-support-for-standards)), hence why it is async. You can also instantiate using the `new` keyword, circumventing standard checks: -```js +```ts const contract = new CIS2Contract(nodeClient, contractAddress, 'my_contract_name'); ``` @@ -37,7 +37,7 @@ This relies on using private keys for the sender account to sign the transaction See the signing a transaction section for the [common package](../packages/common/README.md#sign-an-account-transaction) for create an `AccountSigner`. -```js +```ts const tokenId = ''; // HEX string representing a token ID defined in the contract. const from = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; const to = '3ybJ66spZ2xdWF3avgxQb2meouYa7mpvMWNPmUnczU8FoF8cGB'; // An account receiver. @@ -61,7 +61,7 @@ const txHash = await contract.transfer( ### Create transfer transaction This creates a CIS-2 "transfer" transaction, that can then be submitted the transaction through a Concordium compatible wallet, which handles signing and submitting. -```js +```ts const tokenId = ''; // HEX string representing a token ID defined in the contract. const from = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; const to = '3ybJ66spZ2xdWF3avgxQb2meouYa7mpvMWNPmUnczU8FoF8cGB'; // An account receiver. @@ -94,7 +94,7 @@ This relies on using private keys for the sender account to sign the transaction See the signing a transaction section for the [common package](../packages/common/README.md#sign-an-account-transaction) for create an `AccountSigner`. -```js +```ts const owner = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; const type = 'add'; // or 'remove'; const address = '3ybJ66spZ2xdWF3avgxQb2meouYa7mpvMWNPmUnczU8FoF8cGB'; // Address to add as operator of owner @@ -117,7 +117,7 @@ const txHash = await contract.updateOperator( ### Create update operator transaction This creates a CIS-2 "updateOperator" transaction, that can then be submitted the transaction through a Concordium compatible wallet, which handles signing and submitting. -```js +```ts const owner = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; const type = 'add'; // or 'remove'; const address = '3ybJ66spZ2xdWF3avgxQb2meouYa7mpvMWNPmUnczU8FoF8cGB'; // Address to add as operator of owner @@ -146,7 +146,7 @@ const { ## Querying for balance of token(s) The following example demonstrates how to send either a single/list of CIS-2 "balanceOf" queries using a `CIS2Contract` instance. The response for the query will be either a single/list of bigint balances corresponding to the queries. -```js +```ts const tokenId = ''; // HEX string representing a token ID defined in the contract. const address = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; @@ -164,7 +164,7 @@ const [balance1, balance2, balance3] = await contract.balanceOf([query1, query2, ## Querying for operator of The following example demonstrates how to send either a single/list of CIS-2 "operatorOf" queries using a `CIS2Contract` instance. The response for the query will be either a single/list of boolean values corresponding to the queries, each signaling whether the specified `address` is an operator of the specified `owner`. -```js +```ts const owner = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; const address = '3ybJ66spZ2xdWF3avgxQb2meouYa7mpvMWNPmUnczU8FoF8cGB'; // Address to check if operator of owner // const address = {index: 1234n, 0n}; // Example of contract address operator. @@ -186,7 +186,7 @@ The following example demonstrates how to send either a single/list of CIS-2 "to To get the actual metadata JSON for the contract, a subsequent request to the URL returned would have to be made. -```js +```ts const tokenId = ''; // HEX string representing a token ID defined in the contract. const metadataUrl = await contract.tokenMetadata(tokenId); @@ -205,7 +205,7 @@ One common use case is to check the energy needed to execute the update which ca ### Token transfer(s) dry-run The following example demonstrates how to perform a dry-run of CIS-2 "transfer" with either a single/list of transfers using a `CIS2Contract` instance. The response will be an object containing information about the function invocation. -```js +```ts const tokenId = ''; // HEX string representing a token ID defined in the contract. const from = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; const to = '3ybJ66spZ2xdWF3avgxQb2meouYa7mpvMWNPmUnczU8FoF8cGB'; // An account receiver. @@ -222,7 +222,7 @@ const result = await contract.dryRun.transfer(from, update); ### Operator updates(s) dry-run The following example demonstrates how to perform a dry-run of CIS-2 "updateOperator" with either a single/list of updates using a `CIS2Contract` instance. The response will be an object containing information about the function invocation. -```js +```ts const owner = '4UC8o4m8AgTxt5VBFMdLwMCwwJQVJwjesNzW7RPXkACynrULmd'; const type = 'add'; // or 'remove'; const address = '3ybJ66spZ2xdWF3avgxQb2meouYa7mpvMWNPmUnczU8FoF8cGB'; // Address to add as operator of owner diff --git a/docs/gRPC.md b/docs/gRPC.md index 18539311e..08adbfa69 100644 --- a/docs/gRPC.md +++ b/docs/gRPC.md @@ -391,11 +391,11 @@ Note that some of the parts of the context are optional: ## getModuleSource This commands gets the source of a module on the chain. -Note that this returns the raw bytes of the source, as a Uint8Array. ```ts -const blockHash = 'fe88ff35454079c3df11d8ae13d5777babd61f28be58494efe51b6593e30716e'; -const moduleRef = '7e8398adc406a97db4d869c3fd7adc813a3183667a3a7db078ebae6f7dce5f64'; -const source = await client.getModuleSource(moduleReference, blockHash); +const versionedSource = await client.getModuleSource(moduleReference, blockHash); + +const version: 0 | 1 = versionedSource.version +const rawSource: Buffer = versionedSource.source ``` ## getBlocks diff --git a/docs/grpc-v1.md b/docs/grpc-v1.md index 372333fc6..317eec021 100644 --- a/docs/grpc-v1.md +++ b/docs/grpc-v1.md @@ -35,7 +35,7 @@ a concordium-node. ## Creating a client The current node setup only allows for insecure connections, which can be set up in the following way. The access is controlled by the credentials and the metadata. -```js +```ts import { credentials, Metadata } from "@grpc/grpc-js"; import { ConcordiumNodeClient } from "@concordium/node-sdk"; @@ -58,7 +58,7 @@ The following example demonstrates how to send any account transaction. See the Constructing transactions section for the [common package](../common#constructing-transactions) for how to create an account transaction. See the signing a transaction section for the [common package](../common#sign-an-account-transaction) for how to sign an account transaction. -```js +```ts let accountTransaction: AccountTransaction; // Create the transaction @@ -87,7 +87,7 @@ const transactionStatus = await client.getTransactionStatus(transactionHash); The following example demonstrates how to create a new account on an existing identity. The `credentialIndex` should be the next unused credential index for that identity, and keeping track of that index is done off-chain. Note that index `0` is used by the initial account that was created together with the identity. See [Construct IdentityInput](#Construct-identityInput-for-creating-credentials) for how to construct an IdentityInput. -```js +```ts const lastFinalizedBlockHash = (await client.getConsensusStatus()).lastFinalizedBlock; const cryptographicParameters = await client.getCryptographicParameters(lastFinalizedBlockHash); if (!cryptographicParameters) { @@ -180,7 +180,7 @@ To create accounts/credentials on that identity, this SDK expects an "IdentityIn Below is an example of how to construct the identityInput, with a plaintext id-use-data.json from the [user-cli guide](https://github.com/Concordium/concordium-base/blob/main/rust-bins/docs/user-cli.md#generate-a-request-for-the-identity-object), and an id-object file. -```js +```ts // First we load the files. We assume here that they are available as local files. const rawIdUseData = fs.readFileSync( 'path/to/id-use-data.json', @@ -212,7 +212,7 @@ const identityInput: IdentityInput = { The following is an example of how to construct the identityInput for the _i_-th identity from a mobile wallet export: -```js +```ts // We assume the export is available as a local file: const rawData = fs.readFileSync( 'path/to/export.concordiumwallet', @@ -239,7 +239,7 @@ If a credential registration id is provided, then the node returns the informati which the corresponding credential is (or was) deployed to. If there is no account that matches the address or credential id at the provided block, then undefined will be returned. -```js +```ts const accountAddress = new AccountAddress("3sAHwfehRNEnXk28W7A3XB3GzyBiuQkXLNRmDwDGPUe8JsoAcU"); const blockHash = "6b01f2043d5621192480f4223644ef659dd5cda1e54a78fc64ad642587c73def"; const accountInfo: AccountInfo = await client.getAccountInfo(accountAddress, blockHash); @@ -250,7 +250,7 @@ const nationality: string = accountInfo.accountCredentials[0].value.contents.pol ``` To check if the account is a baker or a delegator, one can use the functions `isDelegatorAccount` and `isBakerAccount`. -```js +```ts ... const accountInfo: AccountInfo = await client.getAccountInfo(accountAddress, blockHash); if (isDelegatorAccount(accountInfo)) { @@ -266,7 +266,7 @@ if (isDelegatorAccount(accountInfo)) { Furthermore there are different versions, based on Protocol version, of a baker's accountInfo. In protocol version 4 the concept of baker pools was introduced, so to get baker pool information one should confirm the version with `isBakerAccountV0` or `isBakerAccountV1`. -```js +```ts ... const accountInfo: AccountInfo = await client.getAccountInfo(accountAddress, blockHash); if (isBakerAccountV1(accountInfo)) { @@ -283,7 +283,7 @@ Retrieves the next account nonce, i.e. the nonce that must be set in the account header for the next transaction submitted by that account. Along with the nonce there is a boolean that indicates whether all transactions are finalized. If this is true, then the nonce is reliable, if not then the next nonce might be off. -```js +```ts const accountAddress = new AccountAddress("3VwCfvVskERFAJ3GeJy2mNFrzfChqUymSJJCvoLAP9rtAwMGYt"); const nextAccountNonce: NextAccountNonce = await client.getNextAccountNonce(accountAddress); const nonce: bigint = nextAccountNonce.nonce; @@ -295,28 +295,28 @@ if (allFinal) { ## getTransactionStatus Retrieves status information about a transaction. -```js +```ts const transactionHash = "f1f5f966e36b95d5474e6b85b85c273c81bac347c38621a0d8fefe68b69a430f"; const transactionStatus: TransactionStatus = await client.getTransactionStatus(transactionHash); const isFinalized = transactionStatus.status === TransactionStatusEnum.Finalized; ... ``` Note that there will be no outcomes for a transaction that has only been received: -```js +```ts if (transactionStatus.status === TransactionStatusEnum.Received) { const outcomes = Object.values(transactionStatus.outcomes); // outcomes.length === 0. } ``` If the transaction has been finalized, then there is exactly one outcome: -```js +```ts if (transactionStatus.status === TransactionStatusEnum.Finalized) { const outcomes = Object.values(transactionStatus.outcomes); // outcomes.length === 1. } ``` A transaction was successful if it is finalized and it has a successful outcome: -```js +```ts if (transactionStatus.status === TransactionStatusEnum.Finalized) { const event = Object.values(response.outcomes)[0]; if (event.result.outcome === "success") { @@ -329,7 +329,7 @@ if (transactionStatus.status === TransactionStatusEnum.Finalized) { Retrives a summary for a specific block. The summary contains information about finalization, the current chain parameters, a list of the governance keys, information about any queued chain parameter updates and a summary of any transactions within the block. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8761d08554756f42bf268a42749"; const blockSummary: BlockSummary = await client.getBlockSummary(blockHash); const numberOfFinalizers = blockSummary.finalizationData.finalizers.length; @@ -339,7 +339,7 @@ const numberOfFinalizers = blockSummary.finalizationData.finalizers.length; Blocks before protocol version 4 have a different type than those from higher protocol versions. To determine the version, use `isBlockSummaryV1` and `isBlockSummaryV0`: -```js +```ts ... const blockSummary: BlockSummary = await client.getBlockSummary(blockHash); if (isBlockSummaryV0(blockSummary)) { @@ -357,7 +357,7 @@ There are also type checks for specific fields in the summary, which can be foun ## getBlockInfo Retrieves information about a specific block. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8761d08554756f42bf268a42749"; const blockInfo: BlockInfo = await client.getBlockInfo(blockHash); const transactionsCount = blockInfo.transactionCount; @@ -366,14 +366,14 @@ const transactionsCount = blockInfo.transactionCount; ## getBlocksAtHeight Retrieves the hashes of blocks at a specific height. -```js +```ts const blockHeight: bigint = 5310n; const blocksAtHeight: string[] = await client.getBlocksAtHeight(blockHeight); ``` ## getConsensusStatus Retrieves the current consensus status from the node. -```js +```ts const consensusStatus: ConsensusStatus = await client.getConsensusStatus(); const bestBlock = consensusStatus.bestBlock; ... @@ -382,7 +382,7 @@ const bestBlock = consensusStatus.bestBlock; ## getCryptographicParameters Retrieves the global cryptographic parameters for the blockchain at a specific block. These are a required input for e.g. creating credentials. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8761d08554756f42bf268a42749" const cryptographicParameters = await client.getCryptographicParameters(blockHash); ... @@ -390,7 +390,7 @@ const cryptographicParameters = await client.getCryptographicParameters(blockHas ## getIdentityProviders Retrieves the list of identity providers at a specific block. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const identityProviders = await client.getIdentityProviders(blockHash); ... @@ -398,7 +398,7 @@ const identityProviders = await client.getIdentityProviders(blockHash); ## getAnonymityRevokers Retrieves the list of anonymity revokers at a specific block. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const identityProviders = await client.getAnonymityRevokers(blockHash); ... @@ -408,7 +408,7 @@ const identityProviders = await client.getAnonymityRevokers(blockHash); Retrieves the list of peers that the node is connected to, including some connection information about them. A boolean parameter determines if this should include bootstrapper nodes or not. -```js +```ts const peerListResponse = await client.getPeerList(false); const peersList = peerListResponse.getPeersList(); ... @@ -416,7 +416,7 @@ const peersList = peerListResponse.getPeersList(); ## getBakerList Retrieves the list of ID's for registered bakers on the network at a specific block. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const bakerIds = await client.getBakerList(blockHash); ... @@ -425,7 +425,7 @@ const bakerIds = await client.getBakerList(blockHash); ## getPoolStatus Retrieves the status of a pool (either a specific baker or passive delegation) at a specific block. If a baker ID is specified, the status of that baker is returned. To get the status of passive delegation, baker ID should be left undefined. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const bakerId = BigInt(1); @@ -436,7 +436,7 @@ const passiveDelegationStatus = await client.getPoolStatus(blockHash); ## getRewardStatus Retrieves the current amount of funds in the system at a specific block, and the state of the special accounts. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const rewardStatus = await client.getRewardStatus(blockHash); @@ -444,7 +444,7 @@ const rewardStatus = await client.getRewardStatus(blockHash); Protocol version 4 expanded the amount of information in the response, so one should check the type to access that. This information includes information about the payday and total amount of funds staked. -```js +```ts if (isRewardStatusV1(rewardStatus)) { const nextPaydayTime = rewardStatus.nextPaydayTime; ... @@ -454,7 +454,7 @@ if (isRewardStatusV1(rewardStatus)) { ## Check block for transfers with memo The following example demonstrates how to check and parse a block for transfers with a memo. -```js +```ts const blockHash = "b49bb1c06c697b7d6539c987082c5a0dc6d86d91208874517ab17da752472edf"; const blockSummary = await client.getBlockSummary(blockHash); const transactionSummaries = blockSummary.transactionSummaries; @@ -476,7 +476,7 @@ for (const transactionSummary of transactionSummaries) { ## getInstances Used to get the full list of contract instances on the chain at a specific block. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const instances = await client.getInstances(blockHash); @@ -486,7 +486,7 @@ const instances = await client.getInstances(blockHash); ## getInstanceInfo Used to get information about a specific contract instance, at a specific block. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const contractAddress = { index: 1n, subindex: 0n }; @@ -500,7 +500,7 @@ Note that only version 0 contracts returns the model. (use `isInstanceInfoV0`/`i ## invokeContract Used to simulate a contract update, and to trigger view functions. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const contractAddress = { index: 1n, subindex: 0n }; const invoker = new AccountAddress('3tXiu8d4CWeuC12irAB7YVb1hzp3YxsmmmNzzkdujCPqQ9EjDm'); @@ -541,7 +541,7 @@ Note that some of the parts of the context are optional: This commands gets the source of a module on the chain. Note that this returns the raw bytes of the source, as a buffer. -```js +```ts const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749"; const moduleReference = "c0e51cd55ccbff4fa8da9bb76c9917e83ae8286d86b47647104bf715b4821c1a"; const source = await client.getModuleSource(moduleReference, blockHash); diff --git a/examples/client/getModuleSource.ts b/examples/client/getModuleSource.ts index 2d0c62c87..9bf72821a 100644 --- a/examples/client/getModuleSource.ts +++ b/examples/client/getModuleSource.ts @@ -59,9 +59,9 @@ const client = createConcordiumClient( (async () => { const ref = new ModuleReference(cli.flags.module); - const source = await client.getModuleSource(ref, cli.flags.block); + const versionedSource = await client.getModuleSource(ref, cli.flags.block); - fs.writeFileSync(cli.flags.outPath, source); + fs.writeFileSync(cli.flags.outPath, versionedSource.source); console.log('Written module source to:', cli.flags.outPath); })(); diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 93296371f..5003c917e 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + +### Breaking changes +- Fixed bug in `getModuleSchema`. It now returns a schema with version. + ## 6.5.0 2023-5-03 ### Added diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index 1389ca011..18d4dd505 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -142,7 +142,7 @@ export default class ConcordiumNodeClient { async getModuleSource( moduleRef: ModuleReference, blockHash?: HexString - ): Promise { + ): Promise { const moduleSourceRequest: v2.ModuleSourceRequest = { blockHash: getBlockHashInput(blockHash), moduleRef: { value: moduleRef.decodedModuleRef }, @@ -151,9 +151,15 @@ export default class ConcordiumNodeClient { const response = await this.client.getModuleSource(moduleSourceRequest) .response; if (response.module.oneofKind === 'v0') { - return Buffer.from(response.module.v0.value); + return { + version: 0, + source: Buffer.from(response.module.v0.value), + }; } else if (response.module.oneofKind === 'v1') { - return Buffer.from(response.module.v1.value); + return { + version: 1, + source: Buffer.from(response.module.v1.value), + }; } else { throw Error('Invalid ModuleSource response received!'); } @@ -169,8 +175,11 @@ export default class ConcordiumNodeClient { moduleRef: ModuleReference, blockHash?: HexString ): Promise { - const source = await this.getModuleSource(moduleRef, blockHash); - return wasmToSchema(source); + const versionedSource = await this.getModuleSource( + moduleRef, + blockHash + ); + return wasmToSchema(versionedSource.source); } /** diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 8af9f2e3d..669408940 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -1207,6 +1207,11 @@ export interface DeployModulePayload { source: Buffer; } +export interface VersionedModuleSource { + version: 0 | 1; + source: Buffer; +} + export interface InitContractPayload { /** µCCD amount to transfer */ amount: CcdAmount; diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index 955138e1e..cc9fb51e5 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -341,9 +341,12 @@ test.each([clientV2, clientWeb])('getModuleSource', async (client) => { ); const localModuleHex = Buffer.from(localModuleBytes); - const moduleSource = await client.getModuleSource(moduleRef, testBlockHash); + const versionedModuleSource = await client.getModuleSource( + moduleRef, + testBlockHash + ); - expect(localModuleHex).toEqual(moduleSource); + expect(localModuleHex).toEqual(versionedModuleSource.source); }); test.each([clientV2, clientWeb])('getConsensusStatus', async (client) => { From b93a94c3618a8d7aa535209d1ee46fdd8b41e625 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Wed, 10 May 2023 15:32:21 +0200 Subject: [PATCH 03/12] `waitForTransactionFinalization` now returns a BlockItemSummary --- packages/common/src/GRPCClient.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index 1389ca011..095b28414 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -427,12 +427,12 @@ export default class ConcordiumNodeClient { * * @param transactionHash a transaction hash as a bytearray. * @param timeoutTime the number of milliseconds until the function throws error. - * @returns A blockhash as a byte array. + * @returns BlockItemSummary of the transaction. */ async waitForTransactionFinalization( transactionHash: HexString, timeoutTime?: number - ): Promise { + ): Promise { assertValidHash(transactionHash); return new Promise(async (resolve, reject) => { const abortController = new AbortController(); @@ -450,7 +450,7 @@ export default class ConcordiumNodeClient { // Simply doing `abortController.abort()` causes an error. // See: https://github.com/grpc/grpc-node/issues/1652 setTimeout(() => abortController.abort(), 0); - return resolve(response.outcome.blockHash); + return resolve(response.outcome.summary); } try { @@ -461,7 +461,7 @@ export default class ConcordiumNodeClient { ); if (response.status === 'finalized') { setTimeout(() => abortController.abort(), 0); - return resolve(response.outcome.blockHash); + return resolve(response.outcome.summary); } } From 4fc76c4c2443cf1b0d711bc4dafcb551dfdf121f Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Wed, 10 May 2023 15:39:22 +0200 Subject: [PATCH 04/12] Added change to changelog --- packages/common/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 93296371f..d03590b93 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Unreleased + +### Breaking changes +- `waitForTransactionFinalization` now returns a `BlockItemSummary` + ## 6.5.0 2023-5-03 ### Added From 00188c1819747c192f75816760766bf7a90b7d47 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 11 May 2023 09:17:31 +0200 Subject: [PATCH 05/12] Expected version --- packages/nodejs/test/clientV2.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index cc9fb51e5..acab9eb7e 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -346,6 +346,7 @@ test.each([clientV2, clientWeb])('getModuleSource', async (client) => { testBlockHash ); + expect(versionedModuleSource.version).toEqual(0); expect(localModuleHex).toEqual(versionedModuleSource.source); }); From 6718aed4c7f10856a296fed3eb2294e10ecb5358 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 11 May 2023 09:37:31 +0200 Subject: [PATCH 06/12] Return `BlockItemSummaryInBlock` in `waitForTransactionFinalization` --- packages/common/src/GRPCClient.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index 095b28414..9a82435b2 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -432,7 +432,7 @@ export default class ConcordiumNodeClient { async waitForTransactionFinalization( transactionHash: HexString, timeoutTime?: number - ): Promise { + ): Promise { assertValidHash(transactionHash); return new Promise(async (resolve, reject) => { const abortController = new AbortController(); @@ -450,7 +450,7 @@ export default class ConcordiumNodeClient { // Simply doing `abortController.abort()` causes an error. // See: https://github.com/grpc/grpc-node/issues/1652 setTimeout(() => abortController.abort(), 0); - return resolve(response.outcome.summary); + return resolve(response.outcome); } try { @@ -461,7 +461,7 @@ export default class ConcordiumNodeClient { ); if (response.status === 'finalized') { setTimeout(() => abortController.abort(), 0); - return resolve(response.outcome.summary); + return resolve(response.outcome); } } From 64510f4b939511c067f84c0b5f0ac717f7ad320d Mon Sep 17 00:00:00 2001 From: Rasmus Kirk Date: Mon, 15 May 2023 11:08:00 +0000 Subject: [PATCH 07/12] Update packages/common/CHANGELOG.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Søren Hjort <87635671+shjortConcordium@users.noreply.github.com> --- packages/common/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index d03590b93..065a2c5a4 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -3,7 +3,7 @@ ## Unreleased ### Breaking changes -- `waitForTransactionFinalization` now returns a `BlockItemSummary` +- `waitForTransactionFinalization` now returns a `BlockItemSummaryInBlock` ## 6.5.0 2023-5-03 From b32e213ccdd87d9e11cf5d84e1c2b6e2b50288af Mon Sep 17 00:00:00 2001 From: Rasmus Kirk Date: Mon, 15 May 2023 11:11:31 +0000 Subject: [PATCH 08/12] Update packages/common/CHANGELOG.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Søren Hjort <87635671+shjortConcordium@users.noreply.github.com> --- packages/common/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 5003c917e..8d0bea0ad 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -3,7 +3,7 @@ ## Unreleased ### Breaking changes -- Fixed bug in `getModuleSchema`. It now returns a schema with version. +- Added missing version return type in `getModuleSchema`. It now returns an object containing the schema source and version. ## 6.5.0 2023-5-03 From 702e1b9c2bb24f9e45da5cc460605d3eeb56940d Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Mon, 15 May 2023 14:40:23 +0200 Subject: [PATCH 09/12] Fixed changelog --- packages/common/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 7c56b8e03..193115312 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -### Changed +### Breaking changes - Updated `blockInfo` so that the `bakerId` field is optional, since it will be undefined for genesis blocks. ## 6.5.0 2023-5-03 From da65c4989e8d78dc10b2ded3a9fba95e65d3bd5d Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Mon, 15 May 2023 15:04:17 +0200 Subject: [PATCH 10/12] Bumped versions --- packages/common/CHANGELOG.md | 2 +- packages/common/package.json | 2 +- packages/nodejs/CHANGELOG.md | 9 +++++++++ packages/nodejs/package.json | 4 ++-- packages/web/CHANGELOG.md | 9 +++++++++ packages/web/package.json | 4 ++-- 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 409303f15..fabf3353e 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 7.0.0 2023-05-15 ### Breaking changes - Updated `blockInfo` so that the `bakerId` field is optional, since it will be undefined for genesis blocks. diff --git a/packages/common/package.json b/packages/common/package.json index 7dcf2a3f5..508778be2 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/common-sdk", - "version": "6.5.0", + "version": "7.0.0", "license": "Apache-2.0", "engines": { "node": ">=14.16.0" diff --git a/packages/nodejs/CHANGELOG.md b/packages/nodejs/CHANGELOG.md index 976c1538d..96be28bd8 100644 --- a/packages/nodejs/CHANGELOG.md +++ b/packages/nodejs/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 7.0.0 2023-05-15 + +### Breaking Changes + +- Bumped @concordium/common-sdk to 7.0.0: + - Updated `blockInfo` so that the `bakerId` field is optional, since it will be undefined for genesis blocks. + - `waitForTransactionFinalization` now returns a `BlockItemSummaryInBlock` + - Added missing version return type in `getModuleSchema`. It now returns an object containing the schema source and version. + ## 6.4.0 2023-5-03 ### Changed diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index 2c933d054..88f7cd767 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/node-sdk", - "version": "6.4.0", + "version": "7.0.0", "description": "Helpers for interacting with the Concordium node", "repository": { "type": "git", @@ -60,7 +60,7 @@ "build-dev": "tsc" }, "dependencies": { - "@concordium/common-sdk": "6.5.0", + "@concordium/common-sdk": "7.0.0", "@grpc/grpc-js": "^1.3.4", "@protobuf-ts/grpc-transport": "^2.8.2", "buffer": "^6.0.3", diff --git a/packages/web/CHANGELOG.md b/packages/web/CHANGELOG.md index 3ee490647..7f5e85d0f 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 4.0.0 2023-05-15 + +### Breaking Changes + +- Bumped @concordium/common-sdk to 7.0.0: + - Updated `blockInfo` so that the `bakerId` field is optional, since it will be undefined for genesis blocks. + - `waitForTransactionFinalization` now returns a `BlockItemSummaryInBlock` + - Added missing version return type in `getModuleSchema`. It now returns an object containing the schema source and version. + ## 3.5.0 2023-5-03 ### Changed diff --git a/packages/web/package.json b/packages/web/package.json index 99b8ce558..dd0719d26 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/web-sdk", - "version": "3.5.0", + "version": "4.0.0", "license": "Apache-2.0", "browser": "lib/concordium.min.js", "types": "lib/index.d.ts", @@ -48,7 +48,7 @@ "webpack-cli": "^4.9.2" }, "dependencies": { - "@concordium/common-sdk": "6.5.0", + "@concordium/common-sdk": "7.0.0", "@concordium/rust-bindings": "0.11.1", "@grpc/grpc-js": "^1.3.4", "@protobuf-ts/grpcweb-transport": "^2.8.2", From 799cca47e26ec02518cb0032aa9bbeb3e25315e4 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Mon, 15 May 2023 15:13:51 +0200 Subject: [PATCH 11/12] updated yarn.lock file --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index eaedc129f..d611c71c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1312,7 +1312,7 @@ __metadata: languageName: node linkType: hard -"@concordium/common-sdk@6.5.0, @concordium/common-sdk@workspace:packages/common": +"@concordium/common-sdk@7.0.0, @concordium/common-sdk@workspace:packages/common": version: 0.0.0-use.local resolution: "@concordium/common-sdk@workspace:packages/common" dependencies: @@ -1354,7 +1354,7 @@ __metadata: version: 0.0.0-use.local resolution: "@concordium/node-sdk@workspace:packages/nodejs" dependencies: - "@concordium/common-sdk": 6.5.0 + "@concordium/common-sdk": 7.0.0 "@grpc/grpc-js": ^1.3.4 "@noble/ed25519": ^1.7.1 "@protobuf-ts/grpc-transport": ^2.8.2 @@ -1393,7 +1393,7 @@ __metadata: version: 0.0.0-use.local resolution: "@concordium/web-sdk@workspace:packages/web" dependencies: - "@concordium/common-sdk": 6.5.0 + "@concordium/common-sdk": 7.0.0 "@concordium/rust-bindings": 0.11.1 "@grpc/grpc-js": ^1.3.4 "@protobuf-ts/grpcweb-transport": ^2.8.2 From a4f8aa72056ebf7ce5848756304803670aaac44a Mon Sep 17 00:00:00 2001 From: Hjort Date: Tue, 16 May 2023 10:31:00 +0200 Subject: [PATCH 12/12] Fixes in documentation --- docs/gRPC.md | 4 ++-- packages/common/src/GRPCClient.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/gRPC.md b/docs/gRPC.md index 0e9e856ce..4f1b6f1a9 100644 --- a/docs/gRPC.md +++ b/docs/gRPC.md @@ -920,8 +920,8 @@ if (blockFinalizationSummary.tag === "record") { Gets a stream of finalized blocks from the specified block height. The stream continues indefinitely unless receiving an abort signal. ```ts -const bis = await client.getFinalizedBlocksFrom(123n); -for await (const bi of bis) { +const blockInfoStream = await client.getFinalizedBlocksFrom(123n); +for await (const blockInfo of blockInfoStream) { // Do something with the block. } ``` diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index c64e9d4f0..f811b081d 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1192,6 +1192,7 @@ export default class ConcordiumNodeClient { /** * Find a block with lowest possible height where the predicate holds. + * Note that this function uses binary search and is only intended to work for monotone predicates. * * @template R * @param {(bi: v1.FinalizedBlockInfo) => Promise} predicate - A predicate function resolving with value of type {@link R} if the predicate holds, and undefined if not.