Skip to content

Commit

Permalink
Merge pull request #29 from Concordium/delegation
Browse files Browse the repository at this point in the history
Add delegation functionality
  • Loading branch information
soerenbf authored Mar 9, 2022
2 parents 0984d20 + a373deb commit 8beea46
Show file tree
Hide file tree
Showing 15 changed files with 1,141 additions and 76 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 0.7.0 2022-03-09

### 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)
- Helper functions for determining the version of `BlockSummary` and nested types.
- Support for initiating and updating contracts with parameters.

### 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.6.0 2022-02-02

### 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.6.0",
"version": "0.7.0",
"description": "Helpers for interacting with the Concordium node",
"repository": {
"type": "git",
Expand Down
17 changes: 17 additions & 0 deletions src/accountHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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;
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;
174 changes: 166 additions & 8 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,10 @@ import {
AccountTransaction,
AccountTransactionSignature,
ArInfo,
BakerReduceStakePendingChange,
BakerRemovalPendingChange,
ReduceStakePendingChange,
RemovalPendingChange,
BlockInfo,
BlockSummary,
ChainParameters,
ConsensusStatus,
ContractAddress,
CredentialDeploymentTransaction,
Expand All @@ -49,9 +49,24 @@ import {
Versioned,
InstanceInfo,
InstanceInfoSerialized,
BakerId,
ChainParametersV0,
ChainParametersV1,
PoolStatus,
BakerPoolStatusDetails,
CurrentPaydayBakerPoolStatus,
LPoolStatusDetails,
KeysMatching,
BakerPoolPendingChangeReduceBakerCapitalDetails,
LPoolStatus,
BakerPoolStatus,
RewardStatusV0,
RewardStatus,
RewardStatusV1,
} from './types';
import {
buildJsonResponseReviver,
intListToStringList,
intToStringTransformer,
isValidHash,
unwrapBoolResponse,
Expand All @@ -60,6 +75,7 @@ import {
import { GtuAmount } from './types/gtuAmount';
import { ModuleReference } from './types/moduleReference';
import { Buffer as BufferFormater } from 'buffer/';

/**
* A concordium-node specific gRPC client wrapper.
*
Expand Down Expand Up @@ -211,8 +227,8 @@ export default class ConcordiumNodeClient {
| keyof AccountReleaseSchedule
| keyof ReleaseSchedule
| keyof AccountBakerDetails
| keyof BakerReduceStakePendingChange
| keyof BakerRemovalPendingChange
| keyof ReduceStakePendingChange
| keyof RemovalPendingChange
)[] = [
'accountAmount',
'accountNonce',
Expand Down Expand Up @@ -318,7 +334,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 +348,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 +625,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

0 comments on commit 8beea46

Please sign in to comment.