Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegation #35

Merged
merged 7 commits into from
Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 0.8.0 2022-03-15

### Added

- Support for getting baker list from node.
- Support for getting status of Baker-/L-pool (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.

### Changed

- Updated `BlockSummary` type to include new version, effective from protocol version 4.
- Updated `AccountInfo` type to include new fields related to delegation introduced with protocol version 4.

## 0.7.1 2022-03-09

### Added
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,26 @@ const peersList = peerListResponse.getPeersList();
...
```

## getBakerList
Retrieves the list of ID's for registered bakers on the network at a specific block.
```js
const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749";
const bakerIds = await client.getBakerList(blockHash);
...
```

## getPoolStatus
Retrieves the status of a pool (either L-Pool or specific baker) at a specific block.
If a baker ID is specified, the status of that baker is returned. To get the status of the L-Pool, a baker ID should be left undefined.
```js
const blockHash = "7f7409679e53875567e2ae812c9fcefe90ced8961d08554756f42bf268a42749";
const bakerId = BigInt(1);

const bakerStatus = await client.getPoolStatus(blockHash, bakerId);
const lPoolStatus = await client.getPoolStatus(blockHash);
...
```

## Check block for transfers with memo
The following example demonstrates how to check and parse a block
for transfers with a memo.
Expand Down
2 changes: 1 addition & 1 deletion deps/concordium-base
Submodule concordium-base updated 75 files
+2 −4 CHANGELOG.md
+1 −5 concordium-base.cabal
+0 −10 haskell-bins/genesis/Genesis.hs
+0 −1 haskell-bins/genesis/README.md
+8 −16 haskell-src/Concordium/Constants.hs
+1 −1 haskell-src/Concordium/Crypto/EncryptedTransfers.hs
+0 −29 haskell-src/Concordium/Genesis/Data.hs
+1 −1 haskell-src/Concordium/Genesis/Data/P2.hs
+0 −107 haskell-src/Concordium/Genesis/Data/P3.hs
+0 −107 haskell-src/Concordium/Genesis/Data/P4.hs
+5 −22 haskell-src/Concordium/ID/Types.hs
+6 −62 haskell-src/Concordium/Types.hs
+4 −21 haskell-src/Concordium/Types/Accounts.hs
+22 −738 haskell-src/Concordium/Types/Execution.hs
+170 −0 haskell-src/Concordium/Types/Instance.hs
+0 −137 haskell-src/Concordium/Types/InvokeContract.hs
+43 −0 haskell-src/Concordium/Types/Parameters.hs
+1 −22 haskell-src/Concordium/Types/ProtocolVersion.hs
+0 −9 haskell-src/Concordium/Types/Updates.hs
+0 −18 haskell-src/Concordium/Utils/Serialization.hs
+95 −196 haskell-src/Concordium/Wasm.hs
+0 −24 haskell-src/Data/FixedByteString.hs
+1 −5 haskell-tests/Spec.hs
+0 −51 haskell-tests/Types/AddressesSpec.hs
+44 −52 haskell-tests/Types/PayloadSerializationSpec.hs
+1 −2 haskell-tests/Types/TransactionGen.hs
+0 −240 haskell-tests/Types/TransactionSummarySpec.hs
+0 −7 idiss-csharp/CHANGELOG.md
+0 −12 idiss-csharp/IdissExample/IdissExample.csproj
+0 −66 idiss-csharp/IdissExample/Program.cs
+0 −21 idiss-csharp/IdissLib/Exceptions.cs
+0 −107 idiss-csharp/IdissLib/Idiss.cs
+0 −8 idiss-csharp/IdissLib/IdissLib.csproj
+0 −77 idiss-csharp/IdissLib/JsonConverters.cs
+0 −302 idiss-csharp/IdissLib/Types.cs
+0 −20 idiss-csharp/IdissLibTest/IdissLibTest.csproj
+0 −63 idiss-csharp/IdissLibTest/IdissTests.cs
+0 −70 idiss-csharp/README.md
+0 −20 idiss-csharp/data/alist.json
+0 −50 idiss-csharp/data/anonymity_revokers.json
+0 −8 idiss-csharp/data/global.json
+0 −13 idiss-csharp/data/identity_provider.pub.json
+0 −57 idiss-csharp/data/valid_request.json
+0 −62 idiss-csharp/idiss-csharp.sln
+0 −11 idiss/CHANGELOG.md
+26 −41 idiss/Cargo.lock
+10 −20 idiss/Cargo.toml
+17 −59 idiss/README.md
+0 −1 idiss/build.rs
+2 −6 idiss/example.js
+0 −163 idiss/src/cs_exports.rs
+110 −99 idiss/src/lib.rs
+16 −46 idiss/src/nodejs_exports.rs
+6 −4 mobile_wallet/scripts/android.Jenkinsfile
+4 −28 rust-bins/Cargo.lock
+1 −1 rust-bins/Cargo.toml
+3 −3 rust-bins/docs/id-client.md
+0 −58 rust-bins/docs/identity-provider-cli.md
+2 −27 rust-bins/docs/keygen.md
+0 −110 rust-bins/docs/user-cli.md
+2 −22 rust-bins/id-client-notes/instructions.md
+20 −29 rust-bins/src/bin/client.rs
+0 −236 rust-bins/src/bin/identity_provider_cli.rs
+31 −131 rust-bins/src/bin/keygen.rs
+0 −553 rust-bins/src/bin/user_cli.rs
+1 −49 rust-bins/src/lib.rs
+182 −140 rust-src/Cargo.lock
+1 −1 rust-src/crypto_common/Cargo.toml
+1 −2 rust-src/crypto_common/src/impls.rs
+2 −5 rust-src/eddsa_ed25519/src/eddsa_ed25519.rs
+12 −43 rust-src/id/src/types.rs
+0 −6 rust-src/keygen_bls/CHANGELOG.md
+1 −2 rust-src/keygen_bls/Cargo.toml
+1 −149 rust-src/keygen_bls/src/lib.rs
+1 −24 rust-src/ps_sig/src/public.rs
2 changes: 1 addition & 1 deletion deps/concordium-grpc-api
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@concordium/node-sdk",
"version": "0.7.1",
"version": "0.8.0-alpha.0",
"description": "Helpers for interacting with the Concordium node",
"repository": {
"type": "git",
Expand Down
37 changes: 37 additions & 0 deletions src/accountHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
ReduceStakePendingChange,
RemovalPendingChange,
StakePendingChange,
StakePendingChangeV1,
} from '.';
import {
AccountInfo,
AccountInfoBaker,
AccountInfoBakerV1,
AccountInfoDelegator,
} from './types';

export const isDelegatorAccount = (
ai: AccountInfo
): ai is AccountInfoDelegator =>
(ai as AccountInfoDelegator).accountDelegation !== undefined;

export const isBakerAccount = (ai: AccountInfo): ai is AccountInfoBaker =>
(ai as AccountInfoBaker).accountBaker !== undefined;

export const isBakerAccountV1 = (ai: AccountInfo): ai is AccountInfoBakerV1 =>
(ai as AccountInfoBakerV1).accountBaker?.bakerPoolInfo !== undefined;

export const isStakePendingChangeV1 = (
spc: StakePendingChange
): spc is StakePendingChangeV1 =>
(spc as StakePendingChangeV1).effectiveTime !== undefined;

export const isReduceStakePendingChange = (
spc: ReduceStakePendingChange | RemovalPendingChange
): spc is ReduceStakePendingChange =>
(spc as ReduceStakePendingChange).newStake !== undefined;

export const isRemovalPendingChange = (
spc: ReduceStakePendingChange | RemovalPendingChange
): spc is RemovalPendingChange => !isReduceStakePendingChange(spc);
34 changes: 34 additions & 0 deletions src/blockSummaryHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import {
Authorizations,
AuthorizationsV1,
BlockSummary,
BlockSummaryV1,
ChainParameters,
ChainParametersV1,
Keys,
KeysV1,
UpdateQueues,
UpdateQueuesV1,
Updates,
UpdatesV1,
} from './types';

export const isAuthorizationsV1 = (a: Authorizations): a is AuthorizationsV1 =>
(a as AuthorizationsV1).timeParameters !== undefined;

export const isChainParametersV1 = (
cp: ChainParameters
): cp is ChainParametersV1 =>
(cp as ChainParametersV1).mintPerPayday !== undefined;

export const isKeysV1 = (k: Keys): k is KeysV1 =>
isAuthorizationsV1(k.level2Keys);

export const isUpdateQueuesV1 = (uq: UpdateQueues): uq is UpdateQueuesV1 =>
(uq as UpdateQueuesV1).timeParameters !== undefined;

export const isUpdatesV1 = (u: Updates): u is UpdatesV1 =>
isUpdateQueuesV1(u.updateQueues);

export const isBlockSummaryV1 = (bs: BlockSummary): bs is BlockSummaryV1 =>
(bs as BlockSummaryV1).protocolVersion !== undefined;
178 changes: 169 additions & 9 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
BlockHeight,
Empty,
GetAddressInfoRequest,
GetPoolStatusRequest,
GetModuleSourceRequest,
PeerListResponse,
PeersRequest,
Expand All @@ -26,11 +27,8 @@ import {
AccountTransaction,
AccountTransactionSignature,
ArInfo,
BakerReduceStakePendingChange,
BakerRemovalPendingChange,
BlockInfo,
BlockSummary,
ChainParameters,
ConsensusStatus,
ContractAddress,
CredentialDeploymentTransaction,
Expand All @@ -49,9 +47,25 @@ import {
Versioned,
InstanceInfo,
InstanceInfoSerialized,
BakerId,
ChainParametersV0,
ChainParametersV1,
PoolStatus,
BakerPoolStatusDetails,
CurrentPaydayBakerPoolStatus,
LPoolStatusDetails,
KeysMatching,
BakerPoolPendingChangeReduceBakerCapitalDetails,
LPoolStatus,
BakerPoolStatus,
RewardStatusV0,
RewardStatus,
RewardStatusV1,
ReduceStakePendingChangeV0,
} from './types';
import {
buildJsonResponseReviver,
intListToStringList,
intToStringTransformer,
isValidHash,
unwrapBoolResponse,
Expand All @@ -60,6 +74,8 @@ import {
import { GtuAmount } from './types/gtuAmount';
import { ModuleReference } from './types/moduleReference';
import { Buffer as BufferFormater } from 'buffer/';
import { ReduceStakePendingChangeV1 } from '.';

/**
* A concordium-node specific gRPC client wrapper.
*
Expand Down Expand Up @@ -204,15 +220,17 @@ export default class ConcordiumNodeClient {
this.client.getAccountInfo,
getAddressInfoRequest
);
const datePropertyKeys: (keyof ReleaseSchedule)[] = ['timestamp'];
const datePropertyKeys: (
| keyof ReleaseSchedule
| keyof ReduceStakePendingChangeV1
)[] = ['timestamp', 'effectiveTime'];
const bigIntPropertyKeys: (
| keyof AccountInfo
| keyof AccountEncryptedAmount
| keyof AccountReleaseSchedule
| keyof ReleaseSchedule
| keyof AccountBakerDetails
| keyof BakerReduceStakePendingChange
| keyof BakerRemovalPendingChange
| keyof ReduceStakePendingChangeV0
)[] = [
'accountAmount',
'accountNonce',
Expand Down Expand Up @@ -318,7 +336,7 @@ export default class ConcordiumNodeClient {
| keyof PartyInfo
| keyof FinalizationData
| keyof TransactionSummary
| keyof ChainParameters
| keyof (ChainParametersV0 & ChainParametersV1)
| keyof ExchangeRate
| keyof UpdateQueue
| keyof KeysWithThreshold
Expand All @@ -332,15 +350,23 @@ export default class ConcordiumNodeClient {
'cost',
'energyCost',
'index',
'bakerCooldownEpochs',
'minimumThresholdForBaking',
'foundationAccountIndex',
'numerator',
'denominator',
'nextSequenceNumber',
'amount',
'index',
'subindex',

// v0 keys
'bakerCooldownEpochs',
'minimumThresholdForBaking',

// v1 keys
'rewardPeriodLength',
'minimumEquityCapital',
'poolOwnerCooldown',
'delegatorCooldown',
];

return unwrapJsonResponse<BlockSummary>(
Expand Down Expand Up @@ -601,6 +627,140 @@ export default class ConcordiumNodeClient {
}
}

async getRewardStatus(
blockHash: string
): Promise<RewardStatus | undefined> {
if (!isValidHash(blockHash)) {
throw new Error('The input was not a valid hash: ' + blockHash);
}

type DateKey = KeysMatching<RewardStatusV1, Date>;
type BigIntKey = KeysMatching<RewardStatusV0 & RewardStatusV1, bigint>;

const dates: DateKey[] = ['nextPaydayTime'];
const bigInts: BigIntKey[] = [
'protocolVersion',
'gasAccount',
'totalAmount',
'totalStakedCapital',
'bakingRewardAccount',
'totalEncryptedAmount',
'finalizationRewardAccount',
'foundationTransactionRewards',
];

const bh = new BlockHash();
bh.setBlockHash(blockHash);

const response = await this.sendRequest(
this.client.getRewardStatus,
bh
);

return unwrapJsonResponse<RewardStatus>(
response,
buildJsonResponseReviver(dates, bigInts),
intToStringTransformer(bigInts)
);
}

/**
* Retrieve list of bakers on the network.
* @param blockHash the block hash to get the smart contact instances at
* @returns A JSON list of baker IDs
*/
async getBakerList(blockHash: string): Promise<BakerId[] | undefined> {
if (!isValidHash(blockHash)) {
throw new Error('The input was not a valid hash: ' + blockHash);
}

const bh = new BlockHash();
bh.setBlockHash(blockHash);

const response = await this.sendRequest(this.client.getBakerList, bh);

return unwrapJsonResponse<BakerId[]>(
response,
undefined,
intListToStringList
)?.map((v) => BigInt(v));
}

/**
* Gets the status the L-pool.
* @param blockHash the block hash the status at
* @returns The status of the L-pool.
*/
async getPoolStatus(blockHash: string): Promise<LPoolStatus | undefined>;
/**
* Gets the status a baker.
* @param blockHash the block hash the status at
* @param bakerId the ID of the baker to get the status for.
* @returns The status of the corresponding baker pool.
*/
async getPoolStatus(
blockHash: string,
bakerId: BakerId
): Promise<BakerPoolStatus | undefined>;
/**
* Gets the status of either a baker, if a baker ID is supplied, or the L-pool if left undefined.
* @param blockHash the block hash the status at
* @param [bakerId] the ID of the baker to get the status for. If left undefined, the status of the L-pool is returned.
* @returns The status of the corresponding pool.
*/
async getPoolStatus(
blockHash: string,
bakerId?: BakerId
): Promise<PoolStatus | undefined>;
async getPoolStatus(
blockHash: string,
bakerId?: BakerId
): Promise<PoolStatus | undefined> {
if (!isValidHash(blockHash)) {
throw new Error('The input was not a valid hash: ' + blockHash);
}

const req = new GetPoolStatusRequest();
req.setBlockHash(blockHash);
req.setLPool(bakerId === undefined);

if (bakerId !== undefined) {
req.setBakerId(bakerId.toString());
}

type DateKey = KeysMatching<
BakerPoolPendingChangeReduceBakerCapitalDetails,
Date
>;
type BigIntKey = KeysMatching<
BakerPoolStatusDetails &
LPoolStatusDetails &
CurrentPaydayBakerPoolStatus,
bigint
>;

const dates: DateKey[] = ['effectiveTime'];
const bigInts: BigIntKey[] = [
'bakerId',
'bakerEquityCapital',
'delegatedCapital',
'delegatedCapitalCap',
'currentPaydayTransactionFeesEarned',
'currentPaydayDelegatedCapital',
'blocksBaked',
'transactionFeesEarned',
'effectiveStake',
];

const response = await this.sendRequest(this.client.getPoolStatus, req);

return unwrapJsonResponse<PoolStatus>(
response,
buildJsonResponseReviver(dates, bigInts),
intToStringTransformer(bigInts)
);
}

async getModuleSource(
blockHash: string,
moduleReference: ModuleReference
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ export {
} from './credentialDeploymentTransactions';
export { isAlias, getAlias } from './alias';
export { deserializeContractState } from './deserialization';
export * from './blockSummaryHelpers';
4 changes: 4 additions & 0 deletions src/rewardStatusHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { RewardStatus, RewardStatusV1 } from './types';

export const isRewardStatusV1 = (rs: RewardStatus): rs is RewardStatusV1 =>
(rs as RewardStatusV1).protocolVersion !== undefined;
Loading