From 3ec25a6234e424587f2b20e0b9b4b4d7db614b6f Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 24 Aug 2023 09:10:38 +0200 Subject: [PATCH 01/30] Added `getBakerEarliestWinTime` --- packages/common/src/GRPCClient.ts | 28 ++++++++++++++++++++++++++ packages/nodejs/package.json | 2 +- packages/nodejs/test/clientV2.test.ts | 9 +++++++++ yarn.lock | 29 +-------------------------- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index 5e6aaade2..a82814743 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1412,6 +1412,34 @@ export class ConcordiumGRPCClient { ); } + /** + * Get the projected earliest time at which a particular baker will be required to bake a block. + * If the current consensus version is 0, this returns the status 'Unavailable', as the endpoint + * is only supported by consensus version 1. + * + * If the baker is not a baker for the current reward period, this returns a timestamp at the + * start of the next reward period. If the baker is a baker for the current reward period, the + * earliest win time is projected from the current round forward, assuming that each round after + * the last finalized round will take the minimum block time. (If blocks take longer, or timeouts + * occur, the actual time may be later, and the reported time in subsequent queries may reflect + * this.) At the end of an epoch (or if the baker is not projected to bake before the end of the + * epoch) the earliest win time for a (current) baker will be projected as the start of the next + * epoch. This is because the seed for the leader election is updated at the epoch boundary, and + * so the winners cannot be predicted beyond that. Note that in some circumstances the returned + * timestamp can be in the past, especially at the end of an epoch. + * + * @param {v1.BakerId} baker - The baker that should be queried for. + * + * @returns {v1.Timestamp} The projected earliest time at which a particular baker will be required to bake a block, as a unix timestamp in milliseconds. + */ + async getBakerEarliestWinTime(baker: v1.BakerId): Promise { + const bakerId = { + value: baker, + }; + const winTime = await this.client.getBakerEarliestWinTime(bakerId) + .response; + return winTime.value; + } private async getConsensusHeight() { return (await this.getConsensusStatus()).lastFinalizedBlockHeight; } diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index d47381060..8a7adff5e 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -60,7 +60,7 @@ "build-dev": "tsc" }, "dependencies": { - "@concordium/common-sdk": "9.0.0", + "@concordium/common-sdk": "9.1.0-alpha.1", "@grpc/grpc-js": "^1.3.4", "@protobuf-ts/grpc-transport": "^2.8.2", "buffer": "^6.0.3", diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index 0d8319fdd..bf137b928 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -943,3 +943,12 @@ describe('findFirstFinalizedBlockNoLaterThan', () => { } ); }); + +test.each([clientV2, clientWeb])('getBakerEarliestWinTime', async (client) => { + const bakers = await streamToList(client.getBakerList()); + const earliestWinTime = await client.getBakerEarliestWinTime(bakers[0]); + + // Arbitrary eraliestWinTime measured at the time of running the test. + // Every earliestWinTime measured after this point should be greater than this. + expect(earliestWinTime).toBeGreaterThan(1692792026500n); +}); diff --git a/yarn.lock b/yarn.lock index 869a62476..b065452dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1350,26 +1350,6 @@ __metadata: languageName: unknown linkType: soft -"@concordium/common-sdk@npm:9.0.0": - version: 9.0.0 - resolution: "@concordium/common-sdk@npm:9.0.0" - dependencies: - "@concordium/rust-bindings": 1.1.0 - "@grpc/grpc-js": ^1.3.4 - "@noble/ed25519": ^1.7.1 - "@protobuf-ts/runtime-rpc": ^2.8.2 - "@scure/bip39": ^1.1.0 - bs58check: ^2.1.2 - buffer: ^6.0.3 - cross-fetch: 3.1.5 - hash.js: ^1.1.7 - iso-3166-1: ^2.1.1 - json-bigint: ^1.0.0 - uuid: ^8.3.2 - checksum: b640846415dfb18b4bb549519ab7fa7825c6b5e84adf1cfaeeea89bb54341e5176e71f00b732ea9bb375aac938842434ab1d6d5ffe2a5f360efc236ea5b0ef4a - languageName: node - linkType: hard - "@concordium/examples@workspace:examples": version: 0.0.0-use.local resolution: "@concordium/examples@workspace:examples" @@ -1395,7 +1375,7 @@ __metadata: version: 0.0.0-use.local resolution: "@concordium/node-sdk@workspace:packages/nodejs" dependencies: - "@concordium/common-sdk": 9.0.0 + "@concordium/common-sdk": 9.1.0-alpha.1 "@grpc/grpc-js": ^1.3.4 "@noble/ed25519": ^1.7.1 "@protobuf-ts/grpc-transport": ^2.8.2 @@ -1430,13 +1410,6 @@ __metadata: languageName: unknown linkType: soft -"@concordium/rust-bindings@npm:1.1.0": - version: 1.1.0 - resolution: "@concordium/rust-bindings@npm:1.1.0" - checksum: 4890306b5df5fb85012cc6c6a6daf15ec1d24c528ac487a4547e8758738a1205b2386a1d4b015dc45312811466d853819edff4b9921d3674afe13ade5cacc061 - languageName: node - linkType: hard - "@concordium/web-sdk@workspace:packages/web": version: 0.0.0-use.local resolution: "@concordium/web-sdk@workspace:packages/web" From eb9052cb4168aedff1474fbd06eab35ac925ee3c Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 24 Aug 2023 09:23:51 +0200 Subject: [PATCH 02/30] Implemented `getBlockCertificates`, see #234 --- packages/common/src/GRPCClient.ts | 23 +++ packages/common/src/GRPCTypeTranslation.ts | 59 ++++++++ packages/common/src/types.ts | 140 ++++++++++++++++++ packages/nodejs/test/clientV2.test.ts | 33 +++++ .../nodejs/test/resources/expectedJsons.ts | 49 ++++++ 5 files changed, 304 insertions(+) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index a82814743..f7ec8b537 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1440,6 +1440,29 @@ export class ConcordiumGRPCClient { .response; return winTime.value; } + + /** + * For a non-genesis block, this returns the quorum certificate, a timeout + * certificate (if present) and epoch finalization entry (if present). + * Note that, if the block being pointed to is not a product of ConcordiumBFT, + * then the response will be a grpc error (invalid argument). + * If the endpoint is not enabled by the node, then an 'unimplemented' error + * will be returned. + * + * @param blockHash optional block hash to get the cryptographic parameters at, otherwise retrieves from last finalized block. + * + * @returns the requested block certificates. + */ + async getBlockCertificates( + blockHash?: HexString + ): Promise { + const blockHashInput = getBlockHashInput(blockHash); + const blockCertificates = await this.client.getBlockCertificates( + blockHashInput + ).response; + return translate.blockCertificates(blockCertificates); + } + private async getConsensusHeight() { return (await this.getConsensusStatus()).lastFinalizedBlockHeight; } diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 02a343074..c6c3b0443 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2723,6 +2723,65 @@ export function blockFinalizationSummary( } } +export function blockCertificates( + certs: v2.BlockCertificates +): v1.BlockCertificates { + return { + ...(certs.quorumCertificate !== undefined && { + quorumCertificate: quorumCertificate(certs.quorumCertificate), + }), + ...(certs.timeoutCertificate !== undefined && { + timeoutCertificate: timeoutCertificate(certs.timeoutCertificate), + }), + ...(certs.epochFinalizationEntry !== undefined && { + epochFinalizationEntry: epochFinalizationEntry( + certs.epochFinalizationEntry + ), + }), + }; +} + +export function quorumCertificate( + cert: v2.QuorumCertificate +): v1.QuorumCertificate { + return { + blockHash: unwrapValToHex(cert.blockHash), + round: unwrap(cert.round?.value), + epoch: unwrap(cert.epoch?.value), + aggregateSignature: unwrapValToHex(cert.aggregateSignature), + signatories: cert.signatories.map((x) => unwrap(x.value)), + }; +} + +export function timeoutCertificate( + cert: v2.TimeoutCertificate +): v1.TimeoutCertificate { + return { + round: unwrap(cert.round?.value), + minEpoch: unwrap(cert.minEpoch?.value), + qcRoundsFirstEpoch: cert.qcRoundsFirstEpoch.map(finalizerRound), + qcRoundsSecondEpoch: cert.qcRoundsSecondEpoch.map(finalizerRound), + aggregateSignature: unwrapValToHex(cert.aggregateSignature), + }; +} + +export function epochFinalizationEntry( + cert: v2.EpochFinalizationEntry +): v1.EpochFinalizationEntry { + return { + finalizedQc: quorumCertificate(unwrap(cert.finalizedQc)), + successorQc: quorumCertificate(unwrap(cert.successorQc)), + successorProof: unwrapValToHex(cert.successorProof), + }; +} + +export function finalizerRound(round: v2.FinalizerRound): v1.FinalizerRound { + return { + round: unwrap(round.round?.value), + finalizers: round.finalizers.map((x) => x.value), + }; +} + // ---------------------------- // // --- V1 => V2 translation --- // // ---------------------------- // diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 3832b2de9..d9d631991 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -34,7 +34,20 @@ export type UrlString = string; export type IpAddressString = string; export type JsonString = string; +/** A smart contract module reference. This is always 32 bytes long. */ export type ModuleRef = HexString; +/** The signature of a 'QuorumCertificate'. the bytes have a fixed length of 48 bytes. */ +export type QuorumSignature = HexString; +/** The signature of a 'TimeoutCertificate'. the bytes have a fixed length of 48 bytes. */ +export type TimeoutSignature = HexString; +/** + * A proof that establishes that the successor block of + * a 'EpochFinalizationEntry' is the immediate successor of + * the finalized block. + * + * The bytes have a fixed length of 32 bytes. + */ +export type SuccessorProof = HexString; /** A number of milliseconds */ export type Duration = bigint; @@ -2016,3 +2029,130 @@ export type SmartContractTypeValues = | number | string | boolean; + +/** + * Certificates for a block for protocols supporting + * ConcordiumBFT. + */ +export interface BlockCertificates { + /** + * The quorum certificate. Is present if and only if the block is + * not a genesis block. + */ + quorumCertificate?: QuorumCertificate; + /** + * The timeout certificate. Is present only if the round prior to the + * round of the block timed out. + */ + timeoutCertificate?: TimeoutCertificate; + /** + * The epoch finalization entry. Is present only if the block initiates + * a new epoch. + */ + epochFinalizationEntry?: EpochFinalizationEntry; +} + +/** + * A quorum certificate is the certificate that the + * finalization comittee issues in order to certify a block. + * A block must be certified before it will be part of the + * authorative part of the chain. + */ +export interface QuorumCertificate { + /** + * The hash of the block that the quorum certificate refers to. + */ + blockHash: HexString; + /** + * The round of the block. + */ + round: Round; + /** + * The epoch of the block. + */ + epoch: Epoch; + /** + * The aggregated signature by the finalization committee on the block. + */ + aggregateSignature: QuorumSignature; + /** + * A list of the finalizers that formed the quorum certificate + * i.e., the ones who have contributed to the 'aggregate_siganture'. + * The finalizers are identified by their baker id as this is stable + * across protocols and epochs. + */ + signatories: BakerId[]; +} + +/** + * A timeout certificate is the certificate that the + * finalization committee issues when a round times out, + * thus making it possible for the protocol to proceed to the + * next round. + */ +export interface TimeoutCertificate { + /** + * The round that timed out. + */ + round: Round; + /** + * The minimum epoch of which signatures are included + * in the 'aggregate_signature'. + */ + minEpoch: Epoch; + /** + * The rounds of which finalizers have their best + * QCs in the 'min_epoch'. + */ + qcRoundsFirstEpoch: FinalizerRound[]; + /** + * The rounds of which finalizers have their best + * QCs in the epoch 'min_epoch' + 1. + */ + qcRoundsSecondEpoch: FinalizerRound[]; + /** + * The aggregated signature by the finalization committee that witnessed + * the 'round' timed out. + */ + aggregateSignature: TimeoutSignature; +} + +/** + * The finalizer round is a map from a 'Round' + * to the list of finalizers (identified by their 'BakerId') that signed + * off the round. + */ +export interface FinalizerRound { + /** + * The round that was signed off. + */ + round: Round; + /** + * The finalizers (identified by their 'BakerId' that + * signed off the in 'round'. + */ + finalizers: BakerId[]; +} + +/** + * The epoch finalization entry is the proof that + * makes the protocol able to advance to a new epoch. + * I.e. the 'EpochFinalizationEntry' is present if and only if + * the block is the first block of a new 'Epoch'. + */ +export interface EpochFinalizationEntry { + /** + * The quorum certificate for the finalized block. + */ + finalizedQc: QuorumCertificate; + /** + * The quorum certificate for the block that finalizes + * the block that 'finalized_qc' points to. + */ + successorQc: QuorumCertificate; + /** + * A proof that the successor block is an immediate + * successor of the finalized block. + */ + successorProof: SuccessorProof; +} diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index bf137b928..80189f91b 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -952,3 +952,36 @@ test.each([clientV2, clientWeb])('getBakerEarliestWinTime', async (client) => { // Every earliestWinTime measured after this point should be greater than this. expect(earliestWinTime).toBeGreaterThan(1692792026500n); }); + +test.each([clientV2, clientWeb])( + 'getBlockCertificates: With timeout certificate', + async (client) => { + const blockWithTimeoutCert = + 'ac94ab7628d44fd8b4edb3075ae156e4b85d4007f52f147df6936ff70083d1ef'; + const blockCertificates = await client.getBlockCertificates( + blockWithTimeoutCert + ); + + expect(blockCertificates.timeoutCertificate).toEqual( + expected.timeoutCertificate + ); + } +); + +test.each([clientV2, clientWeb])( + 'getBlockCertificates: With epoch finalization entry', + async (client) => { + const blockWithEpochFinalizationEntry = + '1ba4bcd28a6e014204f79a81a47bac7518066410acbeb7853f20b55e335b947a'; + const blockCertificates = await client.getBlockCertificates( + blockWithEpochFinalizationEntry + ); + + expect(blockCertificates.quorumCertificate).toEqual( + expected.quorumCertificate + ); + expect(blockCertificates.epochFinalizationEntry).toEqual( + expected.epochFinalizationEntry + ); + } +); diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index 00a622673..b53887619 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -5,8 +5,11 @@ import { ChainParametersV0, ChainParametersV1, ElectionInfoV0, + EpochFinalizationEntry, ModuleReference, NextUpdateSequenceNumbers, + QuorumCertificate, + TimeoutCertificate, } from '@concordium/common-sdk'; export const accountInfo = { @@ -1811,3 +1814,49 @@ export const bakers = [ 1601n, 1614n, ]; + +export const epochFinalizationEntry: EpochFinalizationEntry = { + finalizedQc: { + blockHash: + '20e3ebb41565b460615b08e994103b4a7415f4224441fc9c17c766a1ed1e040f', + round: 78524n, + epoch: 48n, + aggregateSignature: + 'a351b4f049da150731d2699bc49584af158633ec842ab6a676ab4c2402d1c917149d57c4c2ea73d3c58eae222853a6ba', + signatories: [3n, 4n, 5n, 6n, 8n, 1004n], + }, + successorQc: { + blockHash: + '524d787522286a3b2483d3c1cbec5e13ed6ba282484c6caacec56b1353a3c6bc', + round: 78525n, + epoch: 48n, + aggregateSignature: + 'b8f823d6b4c09243f77396ce62b7d33ad17d429036a0c37810d58d2cfdec293645a02c6874cf17523d41ccf373d943aa', + signatories: [3n, 4n, 5n, 6n, 8n, 1004n], + }, + successorProof: + '3c95938c7aba9c93c805390d9d93dd7f67bd868320e4dd5bcd2f27a7f6f3c011', +}; + +export const quorumCertificate: QuorumCertificate = { + blockHash: + '524d787522286a3b2483d3c1cbec5e13ed6ba282484c6caacec56b1353a3c6bc', + round: 78525n, + epoch: 48n, + aggregateSignature: + 'b8f823d6b4c09243f77396ce62b7d33ad17d429036a0c37810d58d2cfdec293645a02c6874cf17523d41ccf373d943aa', + signatories: [3n, 4n, 5n, 6n, 8n, 1004n], +}; +export const timeoutCertificate: TimeoutCertificate = { + round: 78992n, + minEpoch: 49n, + qcRoundsFirstEpoch: [ + { + round: 78991n, + finalizers: [1n, 3n, 5n, 6n, 8n, 1004n, 1010n, 1016n], + }, + ], + qcRoundsSecondEpoch: [], + aggregateSignature: + 'ad8f2c078af44f2b4002172108385c59d012e72d9c8febfa9c2cd6592697621fd4b036df2668bc65190cbf5a5c20dcad', +}; From 37c9d0cbfbeb2051dfe8f4c3d824d9c055faff21 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 24 Aug 2023 09:25:19 +0200 Subject: [PATCH 03/30] Support current `CommissionRates` in `GetPoolInfo`, see #235 --- packages/common/src/GRPCTypeTranslation.ts | 1 + packages/common/src/types.ts | 1 + packages/nodejs/test/resources/expectedJsons.ts | 5 +++++ 3 files changed, 7 insertions(+) diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index c6c3b0443..4bfdd5386 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -332,6 +332,7 @@ function transPaydayStatus( lotteryPower: status.lotteryPower, bakerEquityCapital: unwrap(status.bakerEquityCapital?.value), delegatedCapital: unwrap(status.delegatedCapital?.value), + commisionRates: trCommissionRates(status.commissionRates), }; } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index d9d631991..73b30bd22 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -1187,6 +1187,7 @@ export interface CurrentPaydayBakerPoolStatus { lotteryPower: number; bakerEquityCapital: Amount; delegatedCapital: Amount; + commisionRates: CommissionRates; } export enum BakerPoolPendingChangeType { diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index b53887619..cdbcb9178 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -1696,6 +1696,11 @@ export const bakerPoolStatus = { lotteryPower: 0.15552531374613243, bakerEquityCapital: 7344771840225046n, delegatedCapital: 0n, + commisionRates: { + bakingCommission: 0.1, + finalizationCommission: 1, + transactionCommission: 0.1, + }, }, allPoolTotalCapital: 46071942529284135n, }; From 982bd607ea585e45effe00317672a193c1264578 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 24 Aug 2023 09:25:56 +0200 Subject: [PATCH 04/30] Fixed bug in `getBlockInfo` test Would not be consistent between different nodes --- packages/nodejs/test/clientV2.test.ts | 27 ++++++++++++++++++- .../nodejs/test/resources/expectedJsons.ts | 24 ----------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index 80189f91b..b76811c05 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -623,7 +623,32 @@ test.each([clientV2, clientWeb])( test.each([clientV2, clientWeb])('getBlockInfo', async (client) => { const blockInfo = await client.getBlockInfo(testBlockHash); - expect(blockInfo).toEqual(expected.blockInfo); + expect(blockInfo.blockParent).toEqual( + '28d92ec42dbda119f0b0207d3400b0573fe8baf4b0d3dbe44b86781ad6b655cf' + ); + expect(blockInfo.blockHash).toEqual( + 'fe88ff35454079c3df11d8ae13d5777babd61f28be58494efe51b6593e30716e' + ); + expect(blockInfo.blockStateHash).toEqual( + '6e602157d76677fc4b630b2701571d2b0166e2b08e0afe8ab92356e4d0b88a6a' + ); + expect(blockInfo.blockLastFinalized).toEqual( + '28d92ec42dbda119f0b0207d3400b0573fe8baf4b0d3dbe44b86781ad6b655cf' + ); + expect(blockInfo.blockHeight).toEqual(1259179n); + expect(blockInfo.blockBaker).toEqual(4n); + expect(blockInfo.blockArriveTime).toBeDefined(); + expect(blockInfo.blockReceiveTime).toBeDefined(); + expect(blockInfo.blockSlotTime).toEqual( + new Date('2022-11-07T10:54:10.750Z') + ); + expect(blockInfo.finalized).toEqual(true); + expect(blockInfo.transactionCount).toEqual(0n); + expect(blockInfo.transactionsSize).toEqual(0n); + expect(blockInfo.transactionEnergyCost).toEqual(0n); + expect(blockInfo.genesisIndex).toEqual(1); + expect(blockInfo.eraBlockHeight).toEqual(1258806); + expect(blockInfo.protocolVersion).toEqual(4n); }); test.each([clientV2, clientWeb])('getBakerList', async (client) => { diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index cdbcb9178..7ac6d05ab 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -1767,30 +1767,6 @@ export const blocksAtHeight = [ '99ceb0dfcd36714d9c141fde08e85da1d0d624994e95b35114f14193c811b76e', ]; -export const blockInfo: BlockInfoV0 = { - blockParent: - '28d92ec42dbda119f0b0207d3400b0573fe8baf4b0d3dbe44b86781ad6b655cf', - blockHash: - 'fe88ff35454079c3df11d8ae13d5777babd61f28be58494efe51b6593e30716e', - blockStateHash: - '6e602157d76677fc4b630b2701571d2b0166e2b08e0afe8ab92356e4d0b88a6a', - blockLastFinalized: - '28d92ec42dbda119f0b0207d3400b0573fe8baf4b0d3dbe44b86781ad6b655cf', - blockHeight: 1259179n, - blockBaker: 4n, - blockSlot: 50801674n, - blockArriveTime: new Date('2022-11-07T10:54:10.899Z'), - blockReceiveTime: new Date('2022-11-07T10:54:10.892Z'), - blockSlotTime: new Date('2022-11-07T10:54:10.750Z'), - finalized: true, - transactionCount: 0n, - transactionsSize: 0n, - transactionEnergyCost: 0n, - genesisIndex: 1, - eraBlockHeight: 1258806, - protocolVersion: 4n, -}; - export const bakers = [ 1n, 3n, From 94d09df35ff1ed492f96831194ff195b5335d907 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 24 Aug 2023 10:15:29 +0200 Subject: [PATCH 05/30] Added `getBakersRewardPeriod`, see #232 --- packages/common/src/GRPCClient.ts | 11 ++++ packages/common/src/GRPCTypeTranslation.ts | 20 +++++++ packages/common/src/types.ts | 68 ++++++++++++++++++++++ packages/nodejs/test/clientV2.test.ts | 20 +++++++ 4 files changed, 119 insertions(+) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index f7ec8b537..a280f6861 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1463,6 +1463,17 @@ export class ConcordiumGRPCClient { return translate.blockCertificates(blockCertificates); } + /** + * Get all bakers in the reward period of a block. + * This endpoint is only supported for protocol version 6 and onwards. + * If the protocol does not support the endpoint then an 'IllegalArgument' error is returned. + */ + getBakersRewardPeriod(blockHash?: HexString): AsyncIterable { + const blockHashInput = getBlockHashInput(blockHash); + const bakersRewardPeriod = this.client.getBakersRewardPeriod(blockHashInput).responses; + return mapStream(bakersRewardPeriod, translate.bakerRewardPeriodInfo); + } + private async getConsensusHeight() { return (await this.getConsensusStatus()).lastFinalizedBlockHeight; } diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 4bfdd5386..f4e29f3b1 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2783,6 +2783,26 @@ export function finalizerRound(round: v2.FinalizerRound): v1.FinalizerRound { }; } +export function bakerRewardPeriodInfo(bakerRewardPeriod: v2.BakerRewardPeriodInfo): v1.BakerRewardPeriodInfo { + return { + baker: bakerInfo(unwrap(bakerRewardPeriod.baker)), + effectiveStake: unwrap(bakerRewardPeriod.effectiveStake?.value), + commissionRates: trCommissionRates(bakerRewardPeriod.commissionRates), + equityCapital: unwrap(bakerRewardPeriod.equityCapital?.value), + delegatedCapital: unwrap(bakerRewardPeriod.equityCapital?.value), + isFinalizer: unwrap(bakerRewardPeriod.isFinalizer), + } +} + +export function bakerInfo(bakerInfo: v2.BakerInfo): v1.BakerInfo { + return { + bakerId: unwrap(bakerInfo.bakerId?.value), + electionKey: unwrapValToHex(bakerInfo.electionKey), + signatureKey: unwrapValToHex(bakerInfo.signatureKey), + aggregationKey: unwrapValToHex(bakerInfo.aggregationKey), + } +} + // ---------------------------- // // --- V1 => V2 translation --- // // ---------------------------- // diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 73b30bd22..467201aa9 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -48,6 +48,16 @@ export type TimeoutSignature = HexString; * The bytes have a fixed length of 32 bytes. */ export type SuccessorProof = HexString; +/** Baker's public key used to check whether they won the lottery or not. */ +export type BakerElectionVerifyKey = HexString +/** Baker's public key used to check that they are indeed the ones who produced the block. */ +export type BakerSignatureVerifyKey = HexString +/** + * Baker's public key used to check signatures on finalization records. + * This is only used if the baker has sufficient stake to participate in + * finalization. + */ +export type BakerAggregationVerifyKey = HexString /** A number of milliseconds */ export type Duration = bigint; @@ -2157,3 +2167,61 @@ export interface EpochFinalizationEntry { */ successorProof: SuccessorProof; } + +/** + * Information about a particular baker with respect to + * the current reward period. + */ +export interface BakerRewardPeriodInfo { + /** + * The baker id and public keys for the baker. + */ + baker: BakerInfo; + /** + * The effective stake of the baker for the consensus protocol. + * The returned amount accounts for delegation, capital bounds and leverage bounds. + */ + effectiveStake: Amount; + /** + * The effective commission rate for the baker that applies for the reward period. + */ + commissionRates: CommissionRates; + /** + * The amount staked by the baker itself. + */ + equityCapital: Amount; + /** + * The total amount of capital delegated to this baker pool. + */ + delegatedCapital: Amount; + /** + * Whether the baker is a finalizer or not. + */ + isFinalizer: boolean; +} + +/** + * Information about a baker. + */ +export interface BakerInfo { + /** + * Identity of the baker. This is actually the account index of + * the account controlling the baker. + */ + bakerId: BakerId; + /** + * Baker's public key used to check whether they won the lottery or not. + */ + electionKey: BakerElectionVerifyKey; + /** + * Baker's public key used to check that they are indeed the ones who + * produced the block. + */ + signatureKey: BakerSignatureVerifyKey; + /** + * Baker's public key used to check signatures on finalization records. + * This is only used if the baker has sufficient stake to participate in + * finalization. + */ + aggregationKey: BakerAggregationVerifyKey; +} diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index b76811c05..bb0e22fdf 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -1010,3 +1010,23 @@ test.each([clientV2, clientWeb])( ); } ); + +test.each([clientV2, clientWeb])( + 'getBakersRewardPeriod', + async (client) => { + const bakerRewardPeriodInfo = await streamToList(client.getBakersRewardPeriod()); + const brpi = bakerRewardPeriodInfo[0]; + + expect(typeof brpi.baker.bakerId).toEqual('bigint'); + expect(brpi.baker.electionKey.length).toEqual(64); + expect(brpi.baker.signatureKey.length).toEqual(64); + expect(brpi.baker.aggregationKey.length).toEqual(192); + expect(brpi.baker.aggregationKey.length).toEqual(192); + expect(typeof brpi.commissionRates.bakingCommission).toEqual('number'); + expect(typeof brpi.commissionRates.finalizationCommission).toEqual('number'); + expect(typeof brpi.commissionRates.transactionCommission).toEqual('number'); + expect(typeof brpi.effectiveStake).toEqual('bigint'); + expect(typeof brpi.equityCapital).toEqual('bigint'); + expect(typeof brpi.isFinalizer).toEqual('boolean'); + } +); From ee36bcc182605bd77f427aebb10b6902ba2c547f Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Thu, 24 Aug 2023 10:30:50 +0200 Subject: [PATCH 06/30] Updated changelog --- packages/common/CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index d27dd5830..d717f7728 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## Unreleased + + +### Added + +New consensus endpoints: +- `getBakerEarliestWinTime` +- `getBlockCertificates` +- `getBakersRewardPeriod` + +### Breaking changes + +- `commissionRates` is now added to the `getPoolInfo` under `bakerPoolStatus.PoolInfo` + ## 9.1.0 ### Added From 46e610a187ceb11a082b011e7a56f6021810853e Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Sun, 27 Aug 2023 15:52:57 +0200 Subject: [PATCH 07/30] Implemented `getWinningBakersEpoch` --- packages/common/src/GRPCClient.ts | 47 ++++++++++++++++++++++ packages/common/src/GRPCTypeTranslation.ts | 8 ++++ packages/common/src/types.ts | 42 +++++++++++++++++++ 3 files changed, 97 insertions(+) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index a280f6861..d1d6dab2f 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1474,6 +1474,32 @@ export class ConcordiumGRPCClient { return mapStream(bakersRewardPeriod, translate.bakerRewardPeriodInfo); } + /** + * Get the list of bakers that won the lottery in a particular historical epoch (i.e. the + * last finalized block is in a later epoch). This lists the winners for each round in the + * epoch, starting from the round after the last block in the previous epoch, running to + * the round before the first block in the next epoch. It also indicates if a block in each + * round was included in the finalized chain. + * + * The following error cases are possible: + * @throw `NOT_FOUND` if the query specifies an unknown block. + * @throw `UNAVAILABLE` if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. + * @throw `INVALID_ARGUMENT` if the query is for an epoch that is not finalized for a past genesis index. + * @throw `INVALID_ARGUMENT` if the query is for a genesis index at consensus version 0. + * @throw `INVALID_ARGUMENT` if the input `EpochRequest` is malformed. + * @throw `UNAVAILABLE` if the endpoint is disabled on the node. + * + * @param {v1.HexString | v1.RelativeEpochRequest } epochRequest - consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. + * + * @returns {v1.Timestamp} The projected earliest time at which a particular baker will be required to bake a block, as a unix timestamp in milliseconds. + */ + getWinningBakersEpoch(epochRequest?: HexString | v1.RelativeEpochRequest ): AsyncIterable { + const req = getEpochRequest(epochRequest); + const winningBakers = this.client.getWinningBakersEpoch(req).responses; + + return mapStream(winningBakers, translate.winningBaker); + } + private async getConsensusHeight() { return (await this.getConsensusStatus()).lastFinalizedBlockHeight; } @@ -1557,6 +1583,27 @@ export function getInvokerInput( } } +function getEpochRequest(epochRequest?: HexString | v1.RelativeEpochRequest): v2.EpochRequest { + if (typeof epochRequest === 'string' || typeof epochRequest === 'undefined') { + return { + epochRequestInput: { + oneofKind: "blockHash", + blockHash: getBlockHashInput(epochRequest), + }, + } + } else { + return { + epochRequestInput: { + oneofKind: "relativeEpoch", + relativeEpoch: { + genesisIndex: { value: epochRequest.genesisIndex }, + epoch: { value: epochRequest.epoch }, + }, + }, + } + } +} + function assertValidIp(ip: v1.IpAddressString): void { if (!isValidIp(ip)) { throw new Error('The input was not a valid ip: ' + ip); diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index f4e29f3b1..7f7387bc7 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2803,6 +2803,14 @@ export function bakerInfo(bakerInfo: v2.BakerInfo): v1.BakerInfo { } } +export function winningBaker(winningBaker: v2.WinningBaker): v1.WinningBaker { + return { + round: unwrap(winningBaker.round?.value), + winner: unwrap(winningBaker.winner?.value), + present: unwrap(winningBaker.present), + } +} + // ---------------------------- // // --- V1 => V2 translation --- // // ---------------------------- // diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 467201aa9..5a477b63e 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -68,6 +68,14 @@ export type Round = bigint; /** An amount of energy */ export type Energy = bigint; +/** + * The number of chain restarts via a protocol update. An effected + * protocol update instruction might not change the protocol version + * specified in the previous field, but it always increments the genesis + * index. + */ +export type GenesisIndex = number; + /** * Returns a union of all keys of type T with values matching type V. */ @@ -2225,3 +2233,37 @@ export interface BakerInfo { */ aggregationKey: BakerAggregationVerifyKey; } + + +/** + * Request an epoch by number at a given genesis index. + */ +export interface RelativeEpochRequest { + /** + * The genesis index to query at. The query is restricted to this genesis index, and + * will not return results for other indices even if the epoch number is out of bounds. + */ + genesisIndex: GenesisIndex; + /** + * The epoch number to query at. + */ + epoch: Epoch; +} + +/** + * Details of which baker won the lottery in a given round in consensus version 1. + */ +export interface WinningBaker { + /** + * The round number. + */ + round: Round; + /** + * The baker that won the round. + */ + winner: BakerId; + /** + * True if the baker produced a block in this round on the finalized chain, and False otherwise. + */ + present: boolean; +} From d9126caf0bf9765da55376736c1eb96020578ffd Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Sun, 27 Aug 2023 15:59:52 +0200 Subject: [PATCH 08/30] Implemented `getFirstBlockEpoch` --- packages/common/src/GRPCClient.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index d1d6dab2f..6fd2a9bf1 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1500,6 +1500,27 @@ export class ConcordiumGRPCClient { return mapStream(winningBakers, translate.winningBaker); } + /** + * Get the block hash of the first finalized block in a specified epoch. + * + * The following error cases are possible: + * @throw - `NOT_FOUND` if the query specifies an unknown block. + * @throw - `UNAVAILABLE` if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. + * @throw - `INVALID_ARGUMENT` if the query is for an epoch with no finalized blocks for a past genesis index. + * @throw - `INVALID_ARGUMENT` if the input `EpochRequest` is malformed. + * @throw - `UNAVAILABLE` if the endpoint is disabled on the node. + * + * @param {v1.HexString | v1.RelativeEpochRequest } epochRequest - consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. + * + * @returns {v1.HexString} The block hash as a hex encoded string. + */ + async getFirstBlockEpoch(epochRequest?: HexString | v1.RelativeEpochRequest): Promise{ + const req = getEpochRequest(epochRequest); + const blockHash = await this.client.getFirstBlockEpoch(req).response; + + return translate.unwrapValToHex(blockHash); + } + private async getConsensusHeight() { return (await this.getConsensusStatus()).lastFinalizedBlockHeight; } From 998fb61b2b67a7757aa74caa47099aa52819cb18 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Sun, 27 Aug 2023 16:02:14 +0200 Subject: [PATCH 09/30] Minor fixes --- 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 6fd2a9bf1..d3de3e935 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -303,7 +303,7 @@ export class ConcordiumGRPCClient { * * @param transaction the transaction to send to the node * @param signature the signatures on the signing digest of the transaction - * @returns The transaction hash as a byte array + * @returns The transaction hash as a hex-encoded string */ async sendAccountTransaction( transaction: v1.AccountTransaction, @@ -1489,7 +1489,7 @@ export class ConcordiumGRPCClient { * @throw `INVALID_ARGUMENT` if the input `EpochRequest` is malformed. * @throw `UNAVAILABLE` if the endpoint is disabled on the node. * - * @param {v1.HexString | v1.RelativeEpochRequest } epochRequest - consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. + * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * * @returns {v1.Timestamp} The projected earliest time at which a particular baker will be required to bake a block, as a unix timestamp in milliseconds. */ @@ -1510,9 +1510,9 @@ export class ConcordiumGRPCClient { * @throw - `INVALID_ARGUMENT` if the input `EpochRequest` is malformed. * @throw - `UNAVAILABLE` if the endpoint is disabled on the node. * - * @param {v1.HexString | v1.RelativeEpochRequest } epochRequest - consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. + * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * - * @returns {v1.HexString} The block hash as a hex encoded string. + * @returns {HexString} The block hash as a hex encoded string. */ async getFirstBlockEpoch(epochRequest?: HexString | v1.RelativeEpochRequest): Promise{ const req = getEpochRequest(epochRequest); From 10b99fb7f6a0927ca88bee8f03d49460bf93da10 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Sun, 27 Aug 2023 16:10:14 +0200 Subject: [PATCH 10/30] Added better documentation --- packages/common/src/GRPCClient.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index a280f6861..ab4cb806c 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1414,8 +1414,6 @@ export class ConcordiumGRPCClient { /** * Get the projected earliest time at which a particular baker will be required to bake a block. - * If the current consensus version is 0, this returns the status 'Unavailable', as the endpoint - * is only supported by consensus version 1. * * If the baker is not a baker for the current reward period, this returns a timestamp at the * start of the next reward period. If the baker is a baker for the current reward period, the @@ -1428,6 +1426,8 @@ export class ConcordiumGRPCClient { * so the winners cannot be predicted beyond that. Note that in some circumstances the returned * timestamp can be in the past, especially at the end of an epoch. * + * @throws an `UNAVAILABLE` RPC error if the current consensus version is 0, as the endpoint is only supported by consensus version 1. + * * @param {v1.BakerId} baker - The baker that should be queried for. * * @returns {v1.Timestamp} The projected earliest time at which a particular baker will be required to bake a block, as a unix timestamp in milliseconds. @@ -1446,8 +1446,8 @@ export class ConcordiumGRPCClient { * certificate (if present) and epoch finalization entry (if present). * Note that, if the block being pointed to is not a product of ConcordiumBFT, * then the response will be a grpc error (invalid argument). - * If the endpoint is not enabled by the node, then an 'unimplemented' error - * will be returned. + * + * @throws an `UNIMPLEMENTED` RPC error if the endpoint is not enabled by the node. * * @param blockHash optional block hash to get the cryptographic parameters at, otherwise retrieves from last finalized block. * @@ -1466,7 +1466,12 @@ export class ConcordiumGRPCClient { /** * Get all bakers in the reward period of a block. * This endpoint is only supported for protocol version 6 and onwards. - * If the protocol does not support the endpoint then an 'IllegalArgument' error is returned. + * + * @throws an `IllegalArgument` RPC error if the protocol does not support the endpoint. + * + * @param blockHash optional block hash to get the cryptographic parameters at, otherwise retrieves from last finalized block. + * + * @returns All bakers in the reward period of a block */ getBakersRewardPeriod(blockHash?: HexString): AsyncIterable { const blockHashInput = getBlockHashInput(blockHash); From c73d40a1090f2dbf58aa2b88e47bd7a3110a7246 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Sun, 27 Aug 2023 16:11:57 +0200 Subject: [PATCH 11/30] Improved documentation --- packages/common/src/GRPCClient.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index d3de3e935..ea2682337 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1482,12 +1482,12 @@ export class ConcordiumGRPCClient { * round was included in the finalized chain. * * The following error cases are possible: - * @throw `NOT_FOUND` if the query specifies an unknown block. - * @throw `UNAVAILABLE` if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. - * @throw `INVALID_ARGUMENT` if the query is for an epoch that is not finalized for a past genesis index. - * @throw `INVALID_ARGUMENT` if the query is for a genesis index at consensus version 0. - * @throw `INVALID_ARGUMENT` if the input `EpochRequest` is malformed. - * @throw `UNAVAILABLE` if the endpoint is disabled on the node. + * @throw a `NOT_FOUND` RPC error if the query specifies an unknown block. + * @throw an `UNAVAILABLE` RPC error if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. + * @throw an `INVALID_ARGUMENT` RPC error if the query is for an epoch that is not finalized for a past genesis index. + * @throw an `INVALID_ARGUMENT` RPC error if the query is for a genesis index at consensus version 0. + * @throw an `INVALID_ARGUMENT` RPC error if the input `EpochRequest` is malformed. + * @throw an `UNAVAILABLE` RPC error if the endpoint is disabled on the node. * * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * @@ -1504,11 +1504,11 @@ export class ConcordiumGRPCClient { * Get the block hash of the first finalized block in a specified epoch. * * The following error cases are possible: - * @throw - `NOT_FOUND` if the query specifies an unknown block. - * @throw - `UNAVAILABLE` if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. - * @throw - `INVALID_ARGUMENT` if the query is for an epoch with no finalized blocks for a past genesis index. - * @throw - `INVALID_ARGUMENT` if the input `EpochRequest` is malformed. - * @throw - `UNAVAILABLE` if the endpoint is disabled on the node. + * @throw - a `NOT_FOUND` RPC error if the query specifies an unknown block. + * @throw - an `UNAVAILABLE` RPC error if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. + * @throw - an `INVALID_ARGUMENT` RPC error if the query is for an epoch with no finalized blocks for a past genesis index. + * @throw - an `INVALID_ARGUMENT` RPC error if the input `EpochRequest` is malformed. + * @throw - an `UNAVAILABLE` RPC error if the endpoint is disabled on the node. * * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * From 79a358dc4e3ba9f93b9204d321c0b5d9615daa4b Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 08:58:39 +0200 Subject: [PATCH 12/30] Added tests and linted --- packages/common/src/GRPCClient.ts | 34 +++++++---- packages/common/src/GRPCTypeTranslation.ts | 10 ++-- packages/common/src/types.ts | 7 +-- packages/nodejs/test/clientV2.test.ts | 68 +++++++++++++++++----- 4 files changed, 85 insertions(+), 34 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index bc8b716b6..12ecffe14 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1473,9 +1473,12 @@ export class ConcordiumGRPCClient { * * @returns All bakers in the reward period of a block */ - getBakersRewardPeriod(blockHash?: HexString): AsyncIterable { + getBakersRewardPeriod( + blockHash?: HexString + ): AsyncIterable { const blockHashInput = getBlockHashInput(blockHash); - const bakersRewardPeriod = this.client.getBakersRewardPeriod(blockHashInput).responses; + const bakersRewardPeriod = + this.client.getBakersRewardPeriod(blockHashInput).responses; return mapStream(bakersRewardPeriod, translate.bakerRewardPeriodInfo); } @@ -1498,7 +1501,9 @@ export class ConcordiumGRPCClient { * * @returns {v1.Timestamp} The projected earliest time at which a particular baker will be required to bake a block, as a unix timestamp in milliseconds. */ - getWinningBakersEpoch(epochRequest?: HexString | v1.RelativeEpochRequest ): AsyncIterable { + getWinningBakersEpoch( + epochRequest?: HexString | v1.RelativeEpochRequest + ): AsyncIterable { const req = getEpochRequest(epochRequest); const winningBakers = this.client.getWinningBakersEpoch(req).responses; @@ -1518,8 +1523,10 @@ export class ConcordiumGRPCClient { * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * * @returns {HexString} The block hash as a hex encoded string. - */ - async getFirstBlockEpoch(epochRequest?: HexString | v1.RelativeEpochRequest): Promise{ + */ + async getFirstBlockEpoch( + epochRequest?: HexString | v1.RelativeEpochRequest + ): Promise { const req = getEpochRequest(epochRequest); const blockHash = await this.client.getFirstBlockEpoch(req).response; @@ -1609,24 +1616,29 @@ export function getInvokerInput( } } -function getEpochRequest(epochRequest?: HexString | v1.RelativeEpochRequest): v2.EpochRequest { - if (typeof epochRequest === 'string' || typeof epochRequest === 'undefined') { +function getEpochRequest( + epochRequest?: HexString | v1.RelativeEpochRequest +): v2.EpochRequest { + if ( + typeof epochRequest === 'string' || + typeof epochRequest === 'undefined' + ) { return { epochRequestInput: { - oneofKind: "blockHash", + oneofKind: 'blockHash', blockHash: getBlockHashInput(epochRequest), }, - } + }; } else { return { epochRequestInput: { - oneofKind: "relativeEpoch", + oneofKind: 'relativeEpoch', relativeEpoch: { genesisIndex: { value: epochRequest.genesisIndex }, epoch: { value: epochRequest.epoch }, }, }, - } + }; } } diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 7f7387bc7..f7137dab2 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2783,7 +2783,9 @@ export function finalizerRound(round: v2.FinalizerRound): v1.FinalizerRound { }; } -export function bakerRewardPeriodInfo(bakerRewardPeriod: v2.BakerRewardPeriodInfo): v1.BakerRewardPeriodInfo { +export function bakerRewardPeriodInfo( + bakerRewardPeriod: v2.BakerRewardPeriodInfo +): v1.BakerRewardPeriodInfo { return { baker: bakerInfo(unwrap(bakerRewardPeriod.baker)), effectiveStake: unwrap(bakerRewardPeriod.effectiveStake?.value), @@ -2791,7 +2793,7 @@ export function bakerRewardPeriodInfo(bakerRewardPeriod: v2.BakerRewardPeriodInf equityCapital: unwrap(bakerRewardPeriod.equityCapital?.value), delegatedCapital: unwrap(bakerRewardPeriod.equityCapital?.value), isFinalizer: unwrap(bakerRewardPeriod.isFinalizer), - } + }; } export function bakerInfo(bakerInfo: v2.BakerInfo): v1.BakerInfo { @@ -2800,7 +2802,7 @@ export function bakerInfo(bakerInfo: v2.BakerInfo): v1.BakerInfo { electionKey: unwrapValToHex(bakerInfo.electionKey), signatureKey: unwrapValToHex(bakerInfo.signatureKey), aggregationKey: unwrapValToHex(bakerInfo.aggregationKey), - } + }; } export function winningBaker(winningBaker: v2.WinningBaker): v1.WinningBaker { @@ -2808,7 +2810,7 @@ export function winningBaker(winningBaker: v2.WinningBaker): v1.WinningBaker { round: unwrap(winningBaker.round?.value), winner: unwrap(winningBaker.winner?.value), present: unwrap(winningBaker.present), - } + }; } // ---------------------------- // diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 5a477b63e..a01b922bc 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -49,15 +49,15 @@ export type TimeoutSignature = HexString; */ export type SuccessorProof = HexString; /** Baker's public key used to check whether they won the lottery or not. */ -export type BakerElectionVerifyKey = HexString +export type BakerElectionVerifyKey = HexString; /** Baker's public key used to check that they are indeed the ones who produced the block. */ -export type BakerSignatureVerifyKey = HexString +export type BakerSignatureVerifyKey = HexString; /** * Baker's public key used to check signatures on finalization records. * This is only used if the baker has sufficient stake to participate in * finalization. */ -export type BakerAggregationVerifyKey = HexString +export type BakerAggregationVerifyKey = HexString; /** A number of milliseconds */ export type Duration = bigint; @@ -2234,7 +2234,6 @@ export interface BakerInfo { aggregationKey: BakerAggregationVerifyKey; } - /** * Request an epoch by number at a given genesis index. */ diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index bb0e22fdf..2e7c83c42 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -1011,22 +1011,60 @@ test.each([clientV2, clientWeb])( } ); +test.each([clientV2, clientWeb])('getBakersRewardPeriod', async (client) => { + const bakerRewardPeriodInfo = await streamToList( + client.getBakersRewardPeriod() + ); + const brpi = bakerRewardPeriodInfo[0]; + + expect(typeof brpi.baker.bakerId).toEqual('bigint'); + expect(brpi.baker.electionKey.length).toEqual(64); + expect(brpi.baker.signatureKey.length).toEqual(64); + expect(brpi.baker.aggregationKey.length).toEqual(192); + expect(brpi.baker.aggregationKey.length).toEqual(192); + expect(typeof brpi.commissionRates.bakingCommission).toEqual('number'); + expect(typeof brpi.commissionRates.finalizationCommission).toEqual( + 'number' + ); + expect(typeof brpi.commissionRates.transactionCommission).toEqual('number'); + expect(typeof brpi.effectiveStake).toEqual('bigint'); + expect(typeof brpi.equityCapital).toEqual('bigint'); + expect(typeof brpi.isFinalizer).toEqual('boolean'); +}); + test.each([clientV2, clientWeb])( - 'getBakersRewardPeriod', + 'getFirstBlockEpoch - block hash', async (client) => { - const bakerRewardPeriodInfo = await streamToList(client.getBakersRewardPeriod()); - const brpi = bakerRewardPeriodInfo[0]; - - expect(typeof brpi.baker.bakerId).toEqual('bigint'); - expect(brpi.baker.electionKey.length).toEqual(64); - expect(brpi.baker.signatureKey.length).toEqual(64); - expect(brpi.baker.aggregationKey.length).toEqual(192); - expect(brpi.baker.aggregationKey.length).toEqual(192); - expect(typeof brpi.commissionRates.bakingCommission).toEqual('number'); - expect(typeof brpi.commissionRates.finalizationCommission).toEqual('number'); - expect(typeof brpi.commissionRates.transactionCommission).toEqual('number'); - expect(typeof brpi.effectiveStake).toEqual('bigint'); - expect(typeof brpi.equityCapital).toEqual('bigint'); - expect(typeof brpi.isFinalizer).toEqual('boolean'); + const firstBlockEpoch = await client.getFirstBlockEpoch(testBlockHash); + + expect(firstBlockEpoch).toEqual( + '1ffd2823aa0dff331cc1ec98cf8269cf22120b94e2087c107874c7e84190317b' + ); } ); + +test.each([clientV2, clientWeb])( + 'getFirstBlockEpoch - relative epoch request', + async (client) => { + const req = { + genesisIndex: 1, + epoch: 5n, + }; + const firstBlockEpoch = await client.getFirstBlockEpoch(req); + + expect(firstBlockEpoch).toEqual( + 'ea2a11db1d20658e9dc91f70116fe3f83a5fc49ac318d8ed1848295ae93c66fa' + ); + } +); + +test.each([clientV2, clientWeb])('getWinningBakersEpoch', async (client) => { + const blockHash = + 'ae4a8e864bb71dc2b6043a31c429be4fc4a110955143753ab3963c6a829c8818'; + const winningBakers = await streamToList( + client.getWinningBakersEpoch(blockHash) + ); + const round = winningBakers.filter((x) => x.round === 296651n)[0]; + + expect(round).toEqual({ round: 296651n, winner: 5n, present: true }); +}); From 3493d901a57590dbe1b6353d4fd76f83cc296654 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 09:00:42 +0200 Subject: [PATCH 13/30] Updated changelog --- packages/common/CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index d717f7728..8b5cf6189 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -2,13 +2,14 @@ ## Unreleased - ### Added New consensus endpoints: - `getBakerEarliestWinTime` - `getBlockCertificates` - `getBakersRewardPeriod` +- `getWinningBakersEpoch` +- `getFirstBlockEpoch` ### Breaking changes From 622b5b598d5edc05ef8a2ba92f8ae53c9447b675 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 09:05:27 +0200 Subject: [PATCH 14/30] linted --- packages/common/src/GRPCClient.ts | 7 +++- packages/common/src/GRPCTypeTranslation.ts | 8 ++-- packages/common/src/types.ts | 6 +-- packages/nodejs/test/clientV2.test.ts | 39 ++++++++++--------- .../nodejs/test/resources/expectedJsons.ts | 1 - 5 files changed, 33 insertions(+), 28 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index ab4cb806c..905f01d23 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1473,9 +1473,12 @@ export class ConcordiumGRPCClient { * * @returns All bakers in the reward period of a block */ - getBakersRewardPeriod(blockHash?: HexString): AsyncIterable { + getBakersRewardPeriod( + blockHash?: HexString + ): AsyncIterable { const blockHashInput = getBlockHashInput(blockHash); - const bakersRewardPeriod = this.client.getBakersRewardPeriod(blockHashInput).responses; + const bakersRewardPeriod = + this.client.getBakersRewardPeriod(blockHashInput).responses; return mapStream(bakersRewardPeriod, translate.bakerRewardPeriodInfo); } diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index f4e29f3b1..4873a86dd 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2783,7 +2783,9 @@ export function finalizerRound(round: v2.FinalizerRound): v1.FinalizerRound { }; } -export function bakerRewardPeriodInfo(bakerRewardPeriod: v2.BakerRewardPeriodInfo): v1.BakerRewardPeriodInfo { +export function bakerRewardPeriodInfo( + bakerRewardPeriod: v2.BakerRewardPeriodInfo +): v1.BakerRewardPeriodInfo { return { baker: bakerInfo(unwrap(bakerRewardPeriod.baker)), effectiveStake: unwrap(bakerRewardPeriod.effectiveStake?.value), @@ -2791,7 +2793,7 @@ export function bakerRewardPeriodInfo(bakerRewardPeriod: v2.BakerRewardPeriodInf equityCapital: unwrap(bakerRewardPeriod.equityCapital?.value), delegatedCapital: unwrap(bakerRewardPeriod.equityCapital?.value), isFinalizer: unwrap(bakerRewardPeriod.isFinalizer), - } + }; } export function bakerInfo(bakerInfo: v2.BakerInfo): v1.BakerInfo { @@ -2800,7 +2802,7 @@ export function bakerInfo(bakerInfo: v2.BakerInfo): v1.BakerInfo { electionKey: unwrapValToHex(bakerInfo.electionKey), signatureKey: unwrapValToHex(bakerInfo.signatureKey), aggregationKey: unwrapValToHex(bakerInfo.aggregationKey), - } + }; } // ---------------------------- // diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 467201aa9..70bee6eb0 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -49,15 +49,15 @@ export type TimeoutSignature = HexString; */ export type SuccessorProof = HexString; /** Baker's public key used to check whether they won the lottery or not. */ -export type BakerElectionVerifyKey = HexString +export type BakerElectionVerifyKey = HexString; /** Baker's public key used to check that they are indeed the ones who produced the block. */ -export type BakerSignatureVerifyKey = HexString +export type BakerSignatureVerifyKey = HexString; /** * Baker's public key used to check signatures on finalization records. * This is only used if the baker has sufficient stake to participate in * finalization. */ -export type BakerAggregationVerifyKey = HexString +export type BakerAggregationVerifyKey = HexString; /** A number of milliseconds */ export type Duration = bigint; diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index bb0e22fdf..1b0079eba 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -1011,22 +1011,23 @@ test.each([clientV2, clientWeb])( } ); -test.each([clientV2, clientWeb])( - 'getBakersRewardPeriod', - async (client) => { - const bakerRewardPeriodInfo = await streamToList(client.getBakersRewardPeriod()); - const brpi = bakerRewardPeriodInfo[0]; - - expect(typeof brpi.baker.bakerId).toEqual('bigint'); - expect(brpi.baker.electionKey.length).toEqual(64); - expect(brpi.baker.signatureKey.length).toEqual(64); - expect(brpi.baker.aggregationKey.length).toEqual(192); - expect(brpi.baker.aggregationKey.length).toEqual(192); - expect(typeof brpi.commissionRates.bakingCommission).toEqual('number'); - expect(typeof brpi.commissionRates.finalizationCommission).toEqual('number'); - expect(typeof brpi.commissionRates.transactionCommission).toEqual('number'); - expect(typeof brpi.effectiveStake).toEqual('bigint'); - expect(typeof brpi.equityCapital).toEqual('bigint'); - expect(typeof brpi.isFinalizer).toEqual('boolean'); - } -); +test.each([clientV2, clientWeb])('getBakersRewardPeriod', async (client) => { + const bakerRewardPeriodInfo = await streamToList( + client.getBakersRewardPeriod() + ); + const brpi = bakerRewardPeriodInfo[0]; + + expect(typeof brpi.baker.bakerId).toEqual('bigint'); + expect(brpi.baker.electionKey.length).toEqual(64); + expect(brpi.baker.signatureKey.length).toEqual(64); + expect(brpi.baker.aggregationKey.length).toEqual(192); + expect(brpi.baker.aggregationKey.length).toEqual(192); + expect(typeof brpi.commissionRates.bakingCommission).toEqual('number'); + expect(typeof brpi.commissionRates.finalizationCommission).toEqual( + 'number' + ); + expect(typeof brpi.commissionRates.transactionCommission).toEqual('number'); + expect(typeof brpi.effectiveStake).toEqual('bigint'); + expect(typeof brpi.equityCapital).toEqual('bigint'); + expect(typeof brpi.isFinalizer).toEqual('boolean'); +}); diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index 7ac6d05ab..271b7a732 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -1,6 +1,5 @@ import { AccountAddress, - BlockInfoV0, CcdAmount, ChainParametersV0, ChainParametersV1, From 5ded88cc1535ddc803a27baf8d6ac1bd4f79a4ff Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 09:12:00 +0200 Subject: [PATCH 15/30] Removed unnecessary unwrap --- packages/common/src/GRPCTypeTranslation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index f7137dab2..fed66ad86 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2809,7 +2809,7 @@ export function winningBaker(winningBaker: v2.WinningBaker): v1.WinningBaker { return { round: unwrap(winningBaker.round?.value), winner: unwrap(winningBaker.winner?.value), - present: unwrap(winningBaker.present), + present: winningBaker.present, }; } From 0061c41bf94f4e4b91d024ed7c0e4ffa891bd933 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 09:13:37 +0200 Subject: [PATCH 16/30] Removed unnecessary unwrap --- packages/common/src/GRPCTypeTranslation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 4873a86dd..3878e7eef 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -2792,7 +2792,7 @@ export function bakerRewardPeriodInfo( commissionRates: trCommissionRates(bakerRewardPeriod.commissionRates), equityCapital: unwrap(bakerRewardPeriod.equityCapital?.value), delegatedCapital: unwrap(bakerRewardPeriod.equityCapital?.value), - isFinalizer: unwrap(bakerRewardPeriod.isFinalizer), + isFinalizer: bakerRewardPeriod.isFinalizer, }; } From e335228b3e30b093931d46027962ee79a49276f8 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 09:29:03 +0200 Subject: [PATCH 17/30] CI nows runs on feature branches --- .github/workflows/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index d0202a4b6..fb67cba27 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -3,9 +3,9 @@ name: Build, lint and typecheck examples on: # Triggers the workflow on push or pull request events but only for the main branch push: - branches: [main, release**] + branches: [main, release**, feature**] pull_request: - branches: [main, release**] + branches: [main, release**, feature**] # Don't run on draft PR's, see: https://github.com/orgs/community/discussions/25722#discussioncomment-3248917 types: [opened, synchronize, reopened, ready_for_review] # Allows us to run the workflow manually from the Actions tab From 3804295ef4a6e2af39f3d3be673c8c093d5659b0 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 09:44:21 +0200 Subject: [PATCH 18/30] Added feature branches to CI --- .github/workflows/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index d0202a4b6..fb67cba27 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -3,9 +3,9 @@ name: Build, lint and typecheck examples on: # Triggers the workflow on push or pull request events but only for the main branch push: - branches: [main, release**] + branches: [main, release**, feature**] pull_request: - branches: [main, release**] + branches: [main, release**, feature**] # Don't run on draft PR's, see: https://github.com/orgs/community/discussions/25722#discussioncomment-3248917 types: [opened, synchronize, reopened, ready_for_review] # Allows us to run the workflow manually from the Actions tab From bcb82d65787656b2c4727a0c084c5a7fc35cc488 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 29 Aug 2023 09:46:42 +0200 Subject: [PATCH 19/30] Formatted rust code from previous PR --- packages/rust-bindings/src/external_functions.rs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/rust-bindings/src/external_functions.rs b/packages/rust-bindings/src/external_functions.rs index 8656e0a84..5dd2a2a26 100644 --- a/packages/rust-bindings/src/external_functions.rs +++ b/packages/rust-bindings/src/external_functions.rs @@ -375,14 +375,10 @@ pub fn get_verifiable_credential_public_key_ext( #[wasm_bindgen(js_name = getVerifiableCredentialBackupEncryptionKey)] pub fn get_verifiable_credential_backup_encryption_key_ext( - seed_as_hex: HexString, - raw_net: &str, + seed_as_hex: HexString, + raw_net: &str, ) -> JsResult { - get_verifiable_credential_backup_encryption_key_aux( - seed_as_hex, - raw_net, - ) - .map_err(to_js_error) + get_verifiable_credential_backup_encryption_key_aux(seed_as_hex, raw_net).map_err(to_js_error) } #[wasm_bindgen(js_name = serializeCredentialDeploymentPayload)] From c06059baf917bfe25c6c5ad5821d0efd302dff4a Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 5 Sep 2023 10:37:36 +0200 Subject: [PATCH 20/30] Fixed `commissionRates` --- packages/common/CHANGELOG.md | 3 --- packages/common/src/GRPCTypeTranslation.ts | 2 +- packages/common/src/types.ts | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 8b5cf6189..1af05e88a 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -10,9 +10,6 @@ New consensus endpoints: - `getBakersRewardPeriod` - `getWinningBakersEpoch` - `getFirstBlockEpoch` - -### Breaking changes - - `commissionRates` is now added to the `getPoolInfo` under `bakerPoolStatus.PoolInfo` ## 9.1.0 diff --git a/packages/common/src/GRPCTypeTranslation.ts b/packages/common/src/GRPCTypeTranslation.ts index 6b598318e..b1197209b 100644 --- a/packages/common/src/GRPCTypeTranslation.ts +++ b/packages/common/src/GRPCTypeTranslation.ts @@ -332,7 +332,7 @@ function transPaydayStatus( lotteryPower: status.lotteryPower, bakerEquityCapital: unwrap(status.bakerEquityCapital?.value), delegatedCapital: unwrap(status.delegatedCapital?.value), - commisionRates: trCommissionRates(status.commissionRates), + commissionRates: trCommissionRates(status.commissionRates), }; } diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index a01b922bc..93d4efdfe 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -1205,7 +1205,7 @@ export interface CurrentPaydayBakerPoolStatus { lotteryPower: number; bakerEquityCapital: Amount; delegatedCapital: Amount; - commisionRates: CommissionRates; + commissionRates: CommissionRates; } export enum BakerPoolPendingChangeType { From aa3afca53ebc754c0f6e2c04bb860e47eaa1ebd0 Mon Sep 17 00:00:00 2001 From: Rasmus Kirk Date: Tue, 5 Sep 2023 09:20:11 +0000 Subject: [PATCH 21/30] Update packages/common/src/GRPCClient.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Søren Bruus Zeppelin --- packages/common/src/GRPCClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index 12ecffe14..b3160cc98 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1426,7 +1426,7 @@ export class ConcordiumGRPCClient { * so the winners cannot be predicted beyond that. Note that in some circumstances the returned * timestamp can be in the past, especially at the end of an epoch. * - * @throws an `UNAVAILABLE` RPC error if the current consensus version is 0, as the endpoint is only supported by consensus version 1. + * @throws an `UNAVAILABLE` RPC error if the current consensus version is 0 (prior to protocol version 6), as the endpoint is only supported from consensus version 1 (from protocol version 6). * * @param {v1.BakerId} baker - The baker that should be queried for. * From ad2ff85ff1ca690ba08cde65dabf6c1197fd0e60 Mon Sep 17 00:00:00 2001 From: Rasmus Kirk Date: Tue, 5 Sep 2023 09:21:09 +0000 Subject: [PATCH 22/30] Update packages/common/src/GRPCClient.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Søren Bruus Zeppelin --- packages/common/src/GRPCClient.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index b3160cc98..7b5932ef9 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1490,12 +1490,12 @@ export class ConcordiumGRPCClient { * round was included in the finalized chain. * * The following error cases are possible: - * @throw a `NOT_FOUND` RPC error if the query specifies an unknown block. - * @throw an `UNAVAILABLE` RPC error if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. - * @throw an `INVALID_ARGUMENT` RPC error if the query is for an epoch that is not finalized for a past genesis index. - * @throw an `INVALID_ARGUMENT` RPC error if the query is for a genesis index at consensus version 0. - * @throw an `INVALID_ARGUMENT` RPC error if the input `EpochRequest` is malformed. - * @throw an `UNAVAILABLE` RPC error if the endpoint is disabled on the node. + * @throws a `NOT_FOUND` RPC error if the query specifies an unknown block. + * @throws an `UNAVAILABLE` RPC error if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. + * @throws an `INVALID_ARGUMENT` RPC error if the query is for an epoch that is not finalized for a past genesis index. + * @throws an `INVALID_ARGUMENT` RPC error if the query is for a genesis index at consensus version 0. + * @throws an `INVALID_ARGUMENT` RPC error if the input `EpochRequest` is malformed. + * @throws an `UNAVAILABLE` RPC error if the endpoint is disabled on the node. * * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * From 4bdba4059f44d44f590365dd4932142c0d92ecc1 Mon Sep 17 00:00:00 2001 From: Rasmus Kirk Date: Tue, 5 Sep 2023 09:21:16 +0000 Subject: [PATCH 23/30] Update packages/common/src/GRPCClient.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Søren Bruus Zeppelin --- packages/common/src/GRPCClient.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index 7b5932ef9..fa4e4317f 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1514,11 +1514,11 @@ export class ConcordiumGRPCClient { * Get the block hash of the first finalized block in a specified epoch. * * The following error cases are possible: - * @throw - a `NOT_FOUND` RPC error if the query specifies an unknown block. - * @throw - an `UNAVAILABLE` RPC error if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. - * @throw - an `INVALID_ARGUMENT` RPC error if the query is for an epoch with no finalized blocks for a past genesis index. - * @throw - an `INVALID_ARGUMENT` RPC error if the input `EpochRequest` is malformed. - * @throw - an `UNAVAILABLE` RPC error if the endpoint is disabled on the node. + * @throws - a `NOT_FOUND` RPC error if the query specifies an unknown block. + * @throws - an `UNAVAILABLE` RPC error if the query is for an epoch that is not finalized in the current genesis index, or is for a future genesis index. + * @throws - an `INVALID_ARGUMENT` RPC error if the query is for an epoch with no finalized blocks for a past genesis index. + * @throws - an `INVALID_ARGUMENT` RPC error if the input `EpochRequest` is malformed. + * @throws - an `UNAVAILABLE` RPC error if the endpoint is disabled on the node. * * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * From c846706d29a53f76b605f220a7f23d48da518f39 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 5 Sep 2023 11:27:27 +0200 Subject: [PATCH 24/30] Added a @throws to `getBlockCertificates` doc comment --- packages/common/src/GRPCClient.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index fa4e4317f..fb0b6cd39 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1444,10 +1444,9 @@ export class ConcordiumGRPCClient { /** * For a non-genesis block, this returns the quorum certificate, a timeout * certificate (if present) and epoch finalization entry (if present). - * Note that, if the block being pointed to is not a product of ConcordiumBFT, - * then the response will be a grpc error (invalid argument). * * @throws an `UNIMPLEMENTED` RPC error if the endpoint is not enabled by the node. + * @throws an `INVALID_ARGUMENT` if the block being pointed to is not a product of ConcordiumBFT * * @param blockHash optional block hash to get the cryptographic parameters at, otherwise retrieves from last finalized block. * From b04f4bf3c1dcf5fd16fecc44cb7db2af88b5d46c Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Tue, 10 Oct 2023 15:22:47 +0200 Subject: [PATCH 25/30] Minor fixes --- packages/nodejs/test/clientV2.test.ts | 4 +++- packages/nodejs/test/resources/expectedJsons.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/nodejs/test/clientV2.test.ts b/packages/nodejs/test/clientV2.test.ts index 2e7c83c42..500352778 100644 --- a/packages/nodejs/test/clientV2.test.ts +++ b/packages/nodejs/test/clientV2.test.ts @@ -1066,5 +1066,7 @@ test.each([clientV2, clientWeb])('getWinningBakersEpoch', async (client) => { ); const round = winningBakers.filter((x) => x.round === 296651n)[0]; - expect(round).toEqual({ round: 296651n, winner: 5n, present: true }); + expect(round.round).toEqual(296651n); + expect(round.winner).toEqual(5n); + expect(round.present).toEqual(true); }); diff --git a/packages/nodejs/test/resources/expectedJsons.ts b/packages/nodejs/test/resources/expectedJsons.ts index 271b7a732..36b94be4c 100644 --- a/packages/nodejs/test/resources/expectedJsons.ts +++ b/packages/nodejs/test/resources/expectedJsons.ts @@ -1695,7 +1695,7 @@ export const bakerPoolStatus = { lotteryPower: 0.15552531374613243, bakerEquityCapital: 7344771840225046n, delegatedCapital: 0n, - commisionRates: { + commissionRates: { bakingCommission: 0.1, finalizationCommission: 1, transactionCommission: 0.1, From 48e9b1edb962e597d682e4cc4b5f263a12093df0 Mon Sep 17 00:00:00 2001 From: Rasmus Kirk Date: Fri, 13 Oct 2023 10:38:41 +0000 Subject: [PATCH 26/30] 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 Bruus Zeppelin --- packages/common/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 31eee50c6..2f3565a87 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -61,7 +61,6 @@ New consensus endpoints: ### Fixes - `verifyWeb3IdCredentialSignature` now supports dates/timestamp attributes. - `canProveAtomicStatement` now supports timestamp attributes, handles undefined attribute value correctly and handles strings correctly for range statements. ->>>>>>> origin/main ## 9.1.0 From aaf8fbd6fccc5eda4b866efbbb6f1b75862191f7 Mon Sep 17 00:00:00 2001 From: rasmus-kirk Date: Wed, 18 Oct 2023 08:30:40 +0200 Subject: [PATCH 27/30] Addressed comments: added genesis index type alias to more types --- packages/common/src/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index f6cd7b8ae..b0329cd42 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -822,7 +822,7 @@ export interface BlockInfoCommon { * The genesis index for the block. This counst the number of protocol updates that have * preceeded this block, and defines the era of the block. */ - genesisIndex: number; + genesisIndex: GenesisIndex; /** The height of this block relative to the (re)genesis block of its era */ eraBlockHeight: number; /** The protocol version the block belongs to */ @@ -856,7 +856,7 @@ export type FinalizedBlockInfo = CommonBlockInfo; export type AbsoluteBlocksAtHeightRequest = bigint; export interface RelativeBlocksAtHeightRequest { - genesisIndex: number; + genesisIndex: GenesisIndex; height: bigint; restrict: boolean; } @@ -937,7 +937,7 @@ export interface ConsensusStatusCommon { * specified in the previous field, but it always increments the genesis * index. */ - genesisIndex: number; + genesisIndex: GenesisIndex; /** Currently active protocol version. */ protocolVersion: bigint; From bb59a4bb89f466172d58c663d331b8863c16123c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 19 Oct 2023 09:31:02 +0200 Subject: [PATCH 28/30] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Emil Holm Gjørup --- packages/common/src/types.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index b0329cd42..5baa8ffc2 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -2128,7 +2128,7 @@ export interface QuorumCertificate { aggregateSignature: QuorumSignature; /** * A list of the finalizers that formed the quorum certificate - * i.e., the ones who have contributed to the 'aggregate_siganture'. + * i.e., the ones who have contributed to the 'aggregateSignature'. * The finalizers are identified by their baker id as this is stable * across protocols and epochs. */ @@ -2153,12 +2153,12 @@ export interface TimeoutCertificate { minEpoch: Epoch; /** * The rounds of which finalizers have their best - * QCs in the 'min_epoch'. + * quorum certificates in the 'minEpoch'. */ qcRoundsFirstEpoch: FinalizerRound[]; /** * The rounds of which finalizers have their best - * QCs in the epoch 'min_epoch' + 1. + * quorum certificates in the epoch 'minEpoch' + 1. */ qcRoundsSecondEpoch: FinalizerRound[]; /** @@ -2198,7 +2198,7 @@ export interface EpochFinalizationEntry { finalizedQc: QuorumCertificate; /** * The quorum certificate for the block that finalizes - * the block that 'finalized_qc' points to. + * the block that 'finalizedQc' points to. */ successorQc: QuorumCertificate; /** From 837c37de9cfadb43fb7b3c0c6bda192f005f7579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 19 Oct 2023 09:34:09 +0200 Subject: [PATCH 29/30] Ensure correct docs of added grpc functions --- packages/common/src/GRPCClient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/src/GRPCClient.ts b/packages/common/src/GRPCClient.ts index b7ab9a546..d8631d373 100644 --- a/packages/common/src/GRPCClient.ts +++ b/packages/common/src/GRPCClient.ts @@ -1589,7 +1589,7 @@ export class ConcordiumGRPCClient { * * @param {HexString | v1.RelativeEpochRequest } epochRequest - Consists of either a hex-encoded block hash or a relative epoch request consisting of a genesis index and an epoch. If none is passed, it queries the last finalized block. * - * @returns {v1.Timestamp} The projected earliest time at which a particular baker will be required to bake a block, as a unix timestamp in milliseconds. + * @returns {v1.WinningBaker} A stream of winning bakers for a given epoch. */ getWinningBakersEpoch( epochRequest?: HexString | v1.RelativeEpochRequest From 0a3526b313ad51d3d1a6c815024bd60d17c0e519 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Bruus=20Zeppelin?= Date: Thu, 19 Oct 2023 09:43:59 +0200 Subject: [PATCH 30/30] Version bump --- packages/common/CHANGELOG.md | 281 ++++++++++++++++++----------------- packages/common/package.json | 2 +- packages/nodejs/CHANGELOG.md | 10 +- packages/nodejs/package.json | 4 +- packages/web/CHANGELOG.md | 8 +- packages/web/package.json | 4 +- yarn.lock | 27 +++- 7 files changed, 184 insertions(+), 152 deletions(-) diff --git a/packages/common/CHANGELOG.md b/packages/common/CHANGELOG.md index 2f3565a87..5f1f8b753 100644 --- a/packages/common/CHANGELOG.md +++ b/packages/common/CHANGELOG.md @@ -1,10 +1,11 @@ # Changelog -## Unreleased +## 9.5.0 ### Added New consensus endpoints: + - `getBakerEarliestWinTime` - `getBlockCertificates` - `getBakersRewardPeriod` @@ -22,12 +23,12 @@ New consensus endpoints: - Smart contract related types `ContractName`, `EntrypointName` and helper functions `isInitName`, `isReceiveName`, `getContractNameFromInit` and `getNamesFromReceive`. ### Fixed + - Added missing fields to `getBlockChainParameters` response. (rootKeys, level1Keys, level2Keys) - Use of bigint exponentiation causing issues in web. ## 9.3.0 - ### Added - `sendRawAccountTransaction` to the gRPC Client. @@ -47,26 +48,28 @@ New consensus endpoints: ### Added -- `CIS4Contract` class for seemlessly interacting with contracts adhering to the CIS4 standard. -- Validation of type values when verifying statements. -- Exposed `replaceDateWithTimeStampAttribute` and `reviveDateFromTimeStampAttribute`. +- `CIS4Contract` class for seemlessly interacting with contracts adhering to the CIS4 standard. +- Validation of type values when verifying statements. +- Exposed `replaceDateWithTimeStampAttribute` and `reviveDateFromTimeStampAttribute`. ### Fixed -- Aligned credential schema types with the tested types in the browser wallet. -- `addMinimumAge` now creates the precise age statement instead of one day off. +- Aligned credential schema types with the tested types in the browser wallet. +- `addMinimumAge` now creates the precise age statement instead of one day off. ## 9.1.1 ### Fixes - - `verifyWeb3IdCredentialSignature` now supports dates/timestamp attributes. - - `canProveAtomicStatement` now supports timestamp attributes, handles undefined attribute value correctly and handles strings correctly for range statements. + +- `verifyWeb3IdCredentialSignature` now supports dates/timestamp attributes. +- `canProveAtomicStatement` now supports timestamp attributes, handles undefined attribute value correctly and handles strings correctly for range statements. ## 9.1.0 ### Added Added a functions that handle conversions between CCD and micro CCD. The CCD amounts are handled as `Big`'s: + - `toMicroCcd` returns the amount of micro CCD as a `Big`. - `toCcd`: returns the amount of CCD as a `Big`. - `fromCcd`: constructs a `CcdAmount` from an amount of CCD passed as a `Big` @@ -89,337 +92,337 @@ All function parameters now also accepts strings, these strings can use comma as ### Breaking changes -- Renamed `AccountTransactionType.TransferWithScheduleWithMemo` to `AccountTransactionType.TransferWithScheduleAndMemo`. +- Renamed `AccountTransactionType.TransferWithScheduleWithMemo` to `AccountTransactionType.TransferWithScheduleAndMemo`. ### Changed -- Bumped @concordium/rust-bindings to 1.1.0 (adds `display_type_schema_template` function) +- Bumped @concordium/rust-bindings to 1.1.0 (adds `display_type_schema_template` function) ### Added -- `getTransactionKindString` function. -- `displayTypeSchemaTemplate` function. +- `getTransactionKindString` function. +- `displayTypeSchemaTemplate` function. ## 8.0.0 ### Breaking changes -- Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) -- Updated `types.ts` to conform to updated GRPC API, which includes adding more variants to existing types (all new variants take effect from protocol version 6): - - `ChainParametersV2` added to `ChainParameters` - - `BlockInfo` changed to `BlockInfoV0 | BlockInfoV1` - - `ConsensusStatus` changed to `ConsensusStatusV0 | ConsensusStatusV1` - - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` +- Bumped @concordium/rust-bindings to 1.0.0. (Throws proper `Error`s when execution fails for any WASM entrypoint, with improved error messages) +- Updated `types.ts` to conform to updated GRPC API, which includes adding more variants to existing types (all new variants take effect from protocol version 6): + - `ChainParametersV2` added to `ChainParameters` + - `BlockInfo` changed to `BlockInfoV0 | BlockInfoV1` + - `ConsensusStatus` changed to `ConsensusStatusV0 | ConsensusStatusV1` + - `ElectionInfo` changed to `ElectionInfoV0 | ElectionInfoV1` ### Fixed -- Cost calculation for `deployModule` transaction. -- Fixed a bug where protocol version was different (i.e. 1 less than what it should be) when using the gRPCv2 API (compared to what is returned by the gRPCv1 API). +- Cost calculation for `deployModule` transaction. +- Fixed a bug where protocol version was different (i.e. 1 less than what it should be) when using the gRPCv2 API (compared to what is returned by the gRPCv1 API). ### Changes -- Function `uleb128Decode` now parses correctly and throws an error if the given input contains more than a single ULEB128 encoded number. +- Function `uleb128Decode` now parses correctly and throws an error if the given input contains more than a single ULEB128 encoded number. ### Added -- A `parseWallet` function to parse wallet export files -- Helper functions to determine version of versioned types mentioned in "Breaking Changes" have been added. -- Support for new chain update types. -- Function `uleb128DecodeWithIndex` that can also parse more than a single ULEB128 bigint -- Added `tokenAddressFromBase58` and `tokenAddressToBase58` to CIS2 +- A `parseWallet` function to parse wallet export files +- Helper functions to determine version of versioned types mentioned in "Breaking Changes" have been added. +- Support for new chain update types. +- Function `uleb128DecodeWithIndex` that can also parse more than a single ULEB128 bigint +- Added `tokenAddressFromBase58` and `tokenAddressToBase58` to CIS2 ### Changed -- The following functions now all have an additional parameter controlling whether errors are in a verbose format or not: - - `deserializeContractState` - - `deserializeReceiveReturnValue` - - `deserializeReceiveError` - - `deserializeInitError` - - `deserializeTypeValue` - - `serializeInitContractParameters` - - `serializeUpdateContractParameters` - - `serializeTypeValue` +- The following functions now all have an additional parameter controlling whether errors are in a verbose format or not: + - `deserializeContractState` + - `deserializeReceiveReturnValue` + - `deserializeReceiveError` + - `deserializeInitError` + - `deserializeTypeValue` + - `serializeInitContractParameters` + - `serializeUpdateContractParameters` + - `serializeTypeValue` ## 7.0.1 2023-05-25 ### Fixed -- Cost calculation for `deployModule` transaction. +- Cost calculation for `deployModule` transaction. ## 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. -- `waitForTransactionFinalization` now returns a `BlockItemSummaryInBlock` -- Added missing version return type in `getModuleSchema`. It now returns an object containing the schema source and version. +- 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. ### Added -- Helpers for calculating energy cost for a transaction and microCCD cost from energy cost: - - `getEnergyCost` - - `getExchangeRate` - - `convertEnergyToMicroCcd` -- Utility functions for extracting information from `BlockItemSummary`: - - `isInitContractSummary` - - `isUpdateContractSummary` - - `isTransferLikeSummary` - - `isRejectTransaction` - - `isSuccessTransaction` - - `getTransactionRejectReason` - - `getReceiverAccount` - - `affectedContracts` - - `affectedAccounts` -- Utility functions for extracting information from `BlockSpecialEvent`: - - `specialEventAffectedAccounts` -- Helper methods on `GRPCClient` for chain traversal: - - `getFinalizedBlocksFrom` - - `findEarliestFinalized` - - `findInstanceCreation` - - `findFirstFinalizedBlockNoLaterThan` -- Extended HdWallet with support for verifiable credential key deriviation. +- Helpers for calculating energy cost for a transaction and microCCD cost from energy cost: + - `getEnergyCost` + - `getExchangeRate` + - `convertEnergyToMicroCcd` +- Utility functions for extracting information from `BlockItemSummary`: + - `isInitContractSummary` + - `isUpdateContractSummary` + - `isTransferLikeSummary` + - `isRejectTransaction` + - `isSuccessTransaction` + - `getTransactionRejectReason` + - `getReceiverAccount` + - `affectedContracts` + - `affectedAccounts` +- Utility functions for extracting information from `BlockSpecialEvent`: + - `specialEventAffectedAccounts` +- Helper methods on `GRPCClient` for chain traversal: + - `getFinalizedBlocksFrom` + - `findEarliestFinalized` + - `findInstanceCreation` + - `findFirstFinalizedBlockNoLaterThan` +- Extended HdWallet with support for verifiable credential key deriviation. ### Changed -- Bumped @concordium/rust-bindings to 0.12.0. (Adds key derivation for verifiable credentials) +- Bumped @concordium/rust-bindings to 0.12.0. (Adds key derivation for verifiable credentials) ## 6.5.0 2023-5-03 ### Added -- Utility functions `uleb128Decode` and `uleb128Encode` functions for decoding and encoding as unsigned leb128 respectively. -- `CIS2Contract` class for interacting with smart contracts adhering to the CIS-2 standard. -- `cis0Supports` function for checking standard support in smart contracts. -- Made the `streamToList` function public. -- Made the `unwrap` function public. -- Added `wasmToSchema` utility function. -- Added `getEmbeddedSchema` to client. -- Exposed `RpcError` type and created helper `isRpcError`. -- Build function `buildAccountSigner` for creating `AccountSigner` objects from genesis format, wallet export format, and a simple representation of credentials with keys. +- Utility functions `uleb128Decode` and `uleb128Encode` functions for decoding and encoding as unsigned leb128 respectively. +- `CIS2Contract` class for interacting with smart contracts adhering to the CIS-2 standard. +- `cis0Supports` function for checking standard support in smart contracts. +- Made the `streamToList` function public. +- Made the `unwrap` function public. +- Added `wasmToSchema` utility function. +- Added `getEmbeddedSchema` to client. +- Exposed `RpcError` type and created helper `isRpcError`. +- Build function `buildAccountSigner` for creating `AccountSigner` objects from genesis format, wallet export format, and a simple representation of credentials with keys. ### Changed -- Fixed bug where `AccountCreationSummary` type did not have fields: `index`, `energyCost`, `hash` +- Fixed bug where `AccountCreationSummary` type did not have fields: `index`, `energyCost`, `hash` ## 6.4.2 2023-04-21 ### Changed -- `generateBakerKeys` now also returns the private baker keys. +- `generateBakerKeys` now also returns the private baker keys. ## 6.4.1 2023-03-31 ### Changed -- Replace use of `setImmediate` with `setTimeout` since the former is not +- Replace use of `setImmediate` with `setTimeout` since the former is not supported in browsers. ## 6.4.0 2023-03-22 ### Added -- General function for deserializing smart contract values `deserializeTypeValue`. +- General function for deserializing smart contract values `deserializeTypeValue`. ### Changed -- Bumped @concordium/rust-bindings to 0.11.0. (Includes a fix to serialization of negative numbers for smart contract values) -- `signMessage` and `verifyMessageSignature` can now handle the message being a buffer/Uint8Array instead of only a utf8 string. +- Bumped @concordium/rust-bindings to 0.11.0. (Includes a fix to serialization of negative numbers for smart contract values) +- `signMessage` and `verifyMessageSignature` can now handle the message being a buffer/Uint8Array instead of only a utf8 string. ### Fixed -- `serializeTypeValue` now reports an error when called with invalid data, such as a receive function with missing schema, or a schema that cannot be parsed. +- `serializeTypeValue` now reports an error when called with invalid data, such as a receive function with missing schema, or a schema that cannot be parsed. ## 6.3.0 2023-02-27 ### Added -- Added a client for version 2 of the Concordium gRPC API to communicate with a Concordium node. +- Added a client for version 2 of the Concordium gRPC API to communicate with a Concordium node. - - including helper function `waitForTransactionFinalization` that returns a promise that resolves when the transaction finalizes. + - including helper function `waitForTransactionFinalization` that returns a promise that resolves when the transaction finalizes. -- Serialization: +- Serialization: - - `serializeAccountTransactionPayload` - - `serializeCredentialDeploymentPayload` + - `serializeAccountTransactionPayload` + - `serializeCredentialDeploymentPayload` -- Credential deployment helpers: +- Credential deployment helpers: - - `createCredentialTransaction` - - `createCredentialTransactionNoSeed` - - `signCredentialTransaction` + - `createCredentialTransaction` + - `createCredentialTransactionNoSeed` + - `signCredentialTransaction` -- Function to generate baker keys: `generateBakerKeys`. +- Function to generate baker keys: `generateBakerKeys`. ### Fixed -- `getInitContractParameterSchema`, `getUpdateContractParameterSchema`, +- `getInitContractParameterSchema`, `getUpdateContractParameterSchema`, `serializeInitContractParameters` and `serializeUpdateContractParameters` now report an error when called with invalid data, such as a receive function with missing schema, or a schema that cannot be parsed. ### Deprecated -- The JSON-RPC client has been deprecated in favor of the new gRPC v2 client. -- Various types and helper functions used by the JSON-RPC client (and the v1 gRPC client) have also been deprecated. +- The JSON-RPC client has been deprecated in favor of the new gRPC v2 client. +- Various types and helper functions used by the JSON-RPC client (and the v1 gRPC client) have also been deprecated. ## 6.2.0 2023-01-04 ### Added -- `serializeTypeValue` that allows smart contract types to be serialized using the specific schema, instead of only by providing the entire module's schema. -- `getInitContractParameterSchema` Given a buffer containing the schema for a module, extract the schema for a given contract's init function's parameters. -- `getReceiveContractParameterSchema` Given a buffer containing the schema for a module, extract the schema for a given contract's receive methods' parameters. +- `serializeTypeValue` that allows smart contract types to be serialized using the specific schema, instead of only by providing the entire module's schema. +- `getInitContractParameterSchema` Given a buffer containing the schema for a module, extract the schema for a given contract's init function's parameters. +- `getReceiveContractParameterSchema` Given a buffer containing the schema for a module, extract the schema for a given contract's receive methods' parameters. ## 6.1.0 2022-11-30 ### Added -- `IdStatementBuilder` class to help build id statements. -- `verifyIdStatement` function to verify that a statement is well-formed and complies with rules for id statements. -- `getIdProof` function to prove a statement holds for the given identity/account. -- Enums for sex and idDocType values. +- `IdStatementBuilder` class to help build id statements. +- `verifyIdStatement` function to verify that a statement is well-formed and complies with rules for id statements. +- `getIdProof` function to prove a statement holds for the given identity/account. +- Enums for sex and idDocType values. ## 6.0.0 2022-11-15 ### Breaking changes -- Change AccountTransactionType names/string values to align with those in Concordium base. -- Change some field names in UpdateConcractPayload, InitContractPayload and DeployModule to align with those in Concordium base. -- Rename GtuAmount class to CcdAmount. And change the microGtuAmount field to microCcdAmount. -- Add custom toJSON methods for the classes CcdAmount, AccountAddress, ModuleReference, CredentialRegistrationId, DataBlob and TransactionExpiry, in order to match the serialisation of their equivalents in Concordium base. +- Change AccountTransactionType names/string values to align with those in Concordium base. +- Change some field names in UpdateConcractPayload, InitContractPayload and DeployModule to align with those in Concordium base. +- Rename GtuAmount class to CcdAmount. And change the microGtuAmount field to microCcdAmount. +- Add custom toJSON methods for the classes CcdAmount, AccountAddress, ModuleReference, CredentialRegistrationId, DataBlob and TransactionExpiry, in order to match the serialisation of their equivalents in Concordium base. ### Added -- The ability to deserialize error values of receive and init functions using `deserializeReceiveError()` and `deserializeInitError()` respectfully. -- Refactored the `upserializeUpdateContractParameters()` and `serializeInitContractParameters()` to call into rust functions. +- The ability to deserialize error values of receive and init functions using `deserializeReceiveError()` and `deserializeInitError()` respectfully. +- Refactored the `upserializeUpdateContractParameters()` and `serializeInitContractParameters()` to call into rust functions. ## 5.2.0 2022-11-8 ### Added -- The ability to deserialize the return values of receive functions using `deserializeReceiveReturnValue()`. +- The ability to deserialize the return values of receive functions using `deserializeReceiveReturnValue()`. ## 5.1.0 2022-9-29 ### Added -- Additional arguments to the JSON-RPC HttpProvider, to enable is to receive and forward cookies. +- Additional arguments to the JSON-RPC HttpProvider, to enable is to receive and forward cookies. ### Fixed -- getAccountInfo no longer relies on instanceof to determine the type of input. +- getAccountInfo no longer relies on instanceof to determine the type of input. ## 5.0.0 2022-9-29 ### Added -- `getCredentialId` to the HdWallet. +- `getCredentialId` to the HdWallet. ### Breaking changes -- Updated the signature of helper functions for accounts to sign messages. (and changed the prepend) +- Updated the signature of helper functions for accounts to sign messages. (and changed the prepend) ## 4.0.0 2022-8-26 ### Breaking changes -- ConcordiumHdWallet methods now take the identity provider index as arguments. -- Bumped @concordium/rust-bindings to 0.4.0. +- ConcordiumHdWallet methods now take the identity provider index as arguments. +- Bumped @concordium/rust-bindings to 0.4.0. ### Fixed -- Added missing `accountAddress` field to `AccountInfo` types. +- Added missing `accountAddress` field to `AccountInfo` types. ## 3.0.0 2022-8-26 ### Added -- Support for new V2 schemas which can specify error types. +- Support for new V2 schemas which can specify error types. ### Breaking changes -- SchemaVersion, Module, and schema types are now 0-indexed instead of 1-indexed. This means that the schemas used for V0 contracts are now version 0, and so is the associated types. And the first schema version for V1 contracts are now version 1. +- SchemaVersion, Module, and schema types are now 0-indexed instead of 1-indexed. This means that the schemas used for V0 contracts are now version 0, and so is the associated types. And the first schema version for V1 contracts are now version 1. ## 2.4.0 2022-8-15 ### Added -- `createIdentityRequest`, to create identity requests. -- `createCredentialV1`, to create credentials using a seedPhrase. -- `createIdentityRecoveryRequest`, to create identity recovery requests. -- Added `sendCredentialDeployment` to send credentials created from `createCredentialV1` to the chain. -- `getSignedCredentialDeploymentTransactionHash` to get the transaction hash of credentials created from `createCredentialV1`. -- Added `ConfigureBaker` to `AccountTransactionType` enum. -- Added `ConcordiumHdWallet` with functions to get keys and randomness from a seed phrase. +- `createIdentityRequest`, to create identity requests. +- `createCredentialV1`, to create credentials using a seedPhrase. +- `createIdentityRecoveryRequest`, to create identity recovery requests. +- Added `sendCredentialDeployment` to send credentials created from `createCredentialV1` to the chain. +- `getSignedCredentialDeploymentTransactionHash` to get the transaction hash of credentials created from `createCredentialV1`. +- Added `ConfigureBaker` to `AccountTransactionType` enum. +- Added `ConcordiumHdWallet` with functions to get keys and randomness from a seed phrase. ## 2.3.2 2022-7-26 ### Fixed -- `deserializeTransaction` no longer throws an error on expired transactions. +- `deserializeTransaction` no longer throws an error on expired transactions. ## 2.3.1 2022-7-26 ### Fixed -- `deserializeTransaction` is now exported from index. +- `deserializeTransaction` is now exported from index. ## 2.3.0 2022-7-25 ### Added -- `deserializeTransaction` function to deserialize transaction created by `serializeAccountTransactionForSubmission` and `serializeCredentialDeploymentTransactionForSubmission`. (Currently SimpleTransfer, SimpleTransferWithMemo and RegisterData are the only supported account transactions kinds) +- `deserializeTransaction` function to deserialize transaction created by `serializeAccountTransactionForSubmission` and `serializeCredentialDeploymentTransactionForSubmission`. (Currently SimpleTransfer, SimpleTransferWithMemo and RegisterData are the only supported account transactions kinds) ## 2.2.0 2022-7-21 ### Added -- Add support for getAccountInfo, InvokeContract, getCryptographicParameters and getModuleSource with JSON-RPC +- Add support for getAccountInfo, InvokeContract, getCryptographicParameters and getModuleSource with JSON-RPC ## 2.1.1 2022-7-8 ### Fixed -- Fixed contract schema serialization for ByteList +- Fixed contract schema serialization for ByteList ## 2.1.0 2022-7-5 ### Added -- Support deserializing new schema types: ULeb128, ILeb128, ByteArray and ByteList. -- Support deserializing schemas with versioning information. +- Support deserializing new schema types: ULeb128, ILeb128, ByteArray and ByteList. +- Support deserializing schemas with versioning information. ### Changes -- The function for deserializing a module schema `deserialModuleFromBuffer` now have the schema version as an optional argument. The function will try to extract the version from the buffer. When a version is provided it falls back to this, otherwise it throws an error. +- The function for deserializing a module schema `deserialModuleFromBuffer` now have the schema version as an optional argument. The function will try to extract the version from the buffer. When a version is provided it falls back to this, otherwise it throws an error. ## 2.0.1 2022-6-27 ### Fixed -- @noble/ed25519 and cross-fetch moved from devDependencies to dependencies. +- @noble/ed25519 and cross-fetch moved from devDependencies to dependencies. ## 2.0.0 2022-6-24 ### Added -- Support deserializing version 2 schemas. -- Support serializing parameters for contracts using version 2 schemas. -- Support for deploying versioned smart contract modules, which is the format used in cargo-concordium v2+. (This is done by not supplying the version field in the payload) +- Support deserializing version 2 schemas. +- Support serializing parameters for contracts using version 2 schemas. +- Support for deploying versioned smart contract modules, which is the format used in cargo-concordium v2+. (This is done by not supplying the version field in the payload) ### Breaking changes -- `serializeInitContractParameters` and `serializeUpdateContractParameters` each have an additional parameter, which denotes the version of the schema provided. For existing users that are using V0 contracts, that parameter should be `SchemaVersion.V1`. -- Deserialization of schemas have been changed: types and functions have been renamed and `deserialModuleFromBuffer` have an additional parameter. +- `serializeInitContractParameters` and `serializeUpdateContractParameters` each have an additional parameter, which denotes the version of the schema provided. For existing users that are using V0 contracts, that parameter should be `SchemaVersion.V1`. +- Deserialization of schemas have been changed: types and functions have been renamed and `deserialModuleFromBuffer` have an additional parameter. ## 1.0.1 2022-6-2 ### Fixed -- Fixed JSON-RPC client crash on empty response when calling getInstanceInfo. +- Fixed JSON-RPC client crash on empty response when calling getInstanceInfo. (And update the format of the arguments for the server) -- Fixed issue by bumping rust bindings version +- Fixed issue by bumping rust bindings version ## 1.0.0 2022-5-25 -- Initial release +- Initial release diff --git a/packages/common/package.json b/packages/common/package.json index dcc1523d5..9a2a0dcfb 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/common-sdk", - "version": "9.4.0", + "version": "9.5.0", "license": "Apache-2.0", "engines": { "node": ">=14.16.0" diff --git a/packages/nodejs/CHANGELOG.md b/packages/nodejs/CHANGELOG.md index 754e61ba6..894b8fcdd 100644 --- a/packages/nodejs/CHANGELOG.md +++ b/packages/nodejs/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 9.5.0 + +- Bumped @concordium/common-sdk to 9.5.0. + ## 9.4.0 - Bumped @concordium/common-sdk to 9.4.0. @@ -91,6 +95,7 @@ - Bumped @concordium/common-sdk to 6.0.0. (Which changes transaction type names and field names to be aligned with other implementations) ## 5.0.0 2022-11-8 + Breaking Changes - Bumped @concordium/common-sdk to 5.2.0. (Which changes the function signature of ConcordiumHdWallet and sign helpers functions) @@ -189,8 +194,8 @@ Breaking Changes - Support for getting baker list from node. - Support for getting status of a Baker Pool/Passive delegation (required node to have protocol version 4 or later). - Support for getting reward status of chain at specific block. -- Helper functions for determining the version of `BlockSummary` and nested types. -- Helper functions for determining the version of `AccountInfo` variants. +- Helper functions for determining the version of `BlockSummary` and nested types. +- Helper functions for determining the version of `AccountInfo` variants. - Support for the new "configure delegation" transaction type. ### Changed @@ -210,7 +215,6 @@ Breaking Changes ## 0.7.2 2022-05-05 - ### Added - Export of serializeAccountTransactionForSubmission. diff --git a/packages/nodejs/package.json b/packages/nodejs/package.json index de0dc3cee..3ab511a11 100644 --- a/packages/nodejs/package.json +++ b/packages/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/node-sdk", - "version": "9.4.0", + "version": "9.5.0", "description": "Helpers for interacting with the Concordium node", "repository": { "type": "git", @@ -60,7 +60,7 @@ "build-dev": "tsc" }, "dependencies": { - "@concordium/common-sdk": "9.4.0", + "@concordium/common-sdk": "9.5.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 4f1bbfa8b..e741898ba 100644 --- a/packages/web/CHANGELOG.md +++ b/packages/web/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 6.5.0 + +- Bumped @concordium/common-sdk to 9.5.0. + ## 6.4.0 - Bumped @concordium/common-sdk to 9.4.0. @@ -189,8 +193,8 @@ ## 0.1.1 -- Fixed issue with wasm from rust bindings +- Fixed issue with wasm from rust bindings ## 0.1.0 -- Initial release +- Initial release diff --git a/packages/web/package.json b/packages/web/package.json index cbb07e69c..f3c13a3cb 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -1,6 +1,6 @@ { "name": "@concordium/web-sdk", - "version": "6.4.0", + "version": "6.5.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": "9.4.0", + "@concordium/common-sdk": "9.5.0", "@concordium/rust-bindings": "1.2.0", "@grpc/grpc-js": "^1.3.4", "@protobuf-ts/grpcweb-transport": "^2.8.2", diff --git a/yarn.lock b/yarn.lock index 1f15a7dc1..0cddf50d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1334,7 +1334,7 @@ __metadata: languageName: unknown linkType: soft -"@concordium/common-sdk@9.4.0, @concordium/common-sdk@workspace:^, @concordium/common-sdk@workspace:packages/common": +"@concordium/common-sdk@9.5.0, @concordium/common-sdk@workspace:^, @concordium/common-sdk@workspace:packages/common": version: 0.0.0-use.local resolution: "@concordium/common-sdk@workspace:packages/common" dependencies: @@ -1374,6 +1374,27 @@ __metadata: languageName: unknown linkType: soft +"@concordium/common-sdk@npm:9.4.0": + version: 9.4.0 + resolution: "@concordium/common-sdk@npm:9.4.0" + dependencies: + "@concordium/rust-bindings": 1.2.0 + "@grpc/grpc-js": ^1.3.4 + "@noble/ed25519": ^1.7.1 + "@protobuf-ts/runtime-rpc": ^2.8.2 + "@scure/bip39": ^1.1.0 + big.js: ^6.2.0 + bs58check: ^2.1.2 + buffer: ^6.0.3 + cross-fetch: 3.1.5 + hash.js: ^1.1.7 + iso-3166-1: ^2.1.1 + json-bigint: ^1.0.0 + uuid: ^8.3.2 + checksum: 09b4f3303cca7677f48842c26dcc5692ef6c38bfd8c86f8b790a9f57ce942637264aaeccbcc4bf45313b88afbfff4bd3ef46bc6cbced5a29271df486819c41ad + languageName: node + linkType: hard + "@concordium/examples@workspace:examples": version: 0.0.0-use.local resolution: "@concordium/examples@workspace:examples" @@ -1402,7 +1423,7 @@ __metadata: version: 0.0.0-use.local resolution: "@concordium/node-sdk@workspace:packages/nodejs" dependencies: - "@concordium/common-sdk": 9.4.0 + "@concordium/common-sdk": 9.5.0 "@grpc/grpc-js": ^1.3.4 "@noble/ed25519": ^1.7.1 "@protobuf-ts/grpc-transport": ^2.8.2 @@ -1441,7 +1462,7 @@ __metadata: version: 0.0.0-use.local resolution: "@concordium/web-sdk@workspace:packages/web" dependencies: - "@concordium/common-sdk": 9.4.0 + "@concordium/common-sdk": 9.5.0 "@concordium/rust-bindings": 1.2.0 "@grpc/grpc-js": ^1.3.4 "@protobuf-ts/grpcweb-transport": ^2.8.2