Skip to content

Commit

Permalink
Fix delegation transaction and improve API for baking transaction. (#311
Browse files Browse the repository at this point in the history
)
  • Loading branch information
MilkywayPirate authored Feb 12, 2024
1 parent 0411b87 commit 47576a4
Show file tree
Hide file tree
Showing 75 changed files with 587 additions and 323 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog

# Unreleased changes
- Cleanup the API a bit for configure baker transaction by using `PartsPerHundredThousands` for determining the commission rates.
- Fix serialization of `ConfigureDelegation` transaction
- Remove `AccountNonce` in favor of just using the `Nonce` type across the API.
- Fix a bug in the serialization of `AccountIndex`
- Fix a bug that caused `getAccountInfo` to fail for delegator and baker accounts if they had no stake pending changes.
This change is also propagated to the type level such that `Baker` and `AccountDelegation` retains an `Optional<PendingChange>`
Expand Down
2 changes: 1 addition & 1 deletion concordium-android-sdk/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.concordium.sdk</groupId>
<artifactId>concordium-sdk-base</artifactId>
<version>6.1.0</version>
<version>6.1.1-SNAPSHOT</version>
</parent>

<artifactId>concordium-android-sdk</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion concordium-sdk-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<dependency>
<groupId>com.concordium.sdk</groupId>
<artifactId>concordium-sdk</artifactId>
<version>6.1.0</version>
<version>6.1.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.concordium.sdk.examples;

import com.concordium.sdk.ClientV2;
import com.concordium.sdk.Connection;
import com.concordium.sdk.crypto.bakertransactions.BakerKeys;
import com.concordium.sdk.crypto.ed25519.ED25519SecretKey;
import com.concordium.sdk.exceptions.ClientInitializationException;
import com.concordium.sdk.requests.AccountQuery;
import com.concordium.sdk.requests.BlockQuery;
import com.concordium.sdk.responses.accountinfo.AccountInfo;
import com.concordium.sdk.responses.blockitemstatus.FinalizedBlockItem;
import com.concordium.sdk.responses.transactionstatus.PartsPerHundredThousand;
import com.concordium.sdk.transactions.*;
import com.concordium.sdk.types.AccountAddress;
import lombok.val;
import picocli.CommandLine;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;
import java.util.concurrent.Callable;

/**
* An example of how to configure baking for an account.
*/
@CommandLine.Command(name = "ConfigureBaking", mixinStandardHelpOptions = true)
public class ConfigureBaking implements Callable<Integer> {

@CommandLine.Option(
names = {"--endpoint"},
description = "GRPC interface of the node.",
defaultValue = "http://localhost:20002")
private String endpoint;

@CommandLine.Option(
names = {"--timeout"},
description = "GRPC request timeout in milliseconds.",
defaultValue = "100000")
private int timeout;

@Override
public Integer call() throws MalformedURLException, ClientInitializationException {
val endpointUrl = new URL(this.endpoint);

Connection connection = Connection.newBuilder()
.host(endpointUrl.getHost())
.port(endpointUrl.getPort())
.build();
val client = ClientV2.from(connection);

AccountAddress sender = AccountAddress.from("3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE");
TransactionSigner signer = TransactionSigner.from(
SignerEntry.from(Index.from(0), Index.from(0),
ED25519SecretKey
.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")));
AccountInfo accountInfo = client.getAccountInfo(BlockQuery.LAST_FINAL, AccountQuery.from(sender));
BakerKeys bakerkeys = BakerKeys.createBakerKeys();
System.out.println(bakerkeys.toJson());
val tx = TransactionFactory.newConfigureBaker()
.nonce(accountInfo.getNonce())
.expiry(Expiry.createNew().addMinutes(5))
.signer(signer)
.sender(sender)
.payload(ConfigureBakerPayload.builder()
.capital(CCDAmount.from(10000))
.openForDelegation(true)
.restakeEarnings(true)
.bakingRewardCommission(PartsPerHundredThousand.from(5000))
.finalizationRewardCommission(PartsPerHundredThousand.from(100000))
.transactionFeeCommission(PartsPerHundredThousand.from(80000))
.metadataUrl("")
.keysWithProofs(
ConfigureBakerKeysPayload
.getNewConfigureBakerKeysPayload(sender, bakerkeys))
.build())
.build();
Hash hash = client.sendTransaction(tx);
System.out.println(hash);
Optional<FinalizedBlockItem> finalizedBlockItem = client.waitUntilFinalized(hash, this.timeout);
System.out.println(finalizedBlockItem);

return 0;
}

public static void main(String[] args) {
int exitCode = new CommandLine(new ConfigureBaking()).execute(args);
System.exit(exitCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package com.concordium.sdk.examples;

import com.concordium.sdk.ClientV2;
import com.concordium.sdk.Connection;
import com.concordium.sdk.crypto.ed25519.ED25519SecretKey;
import com.concordium.sdk.exceptions.ClientInitializationException;
import com.concordium.sdk.requests.AccountQuery;
import com.concordium.sdk.requests.BlockQuery;
import com.concordium.sdk.responses.BakerId;
import com.concordium.sdk.responses.accountinfo.AccountInfo;
import com.concordium.sdk.responses.blockitemstatus.FinalizedBlockItem;
import com.concordium.sdk.responses.transactionstatus.DelegationTarget;
import com.concordium.sdk.transactions.*;
import com.concordium.sdk.types.AccountAddress;
import lombok.val;
import picocli.CommandLine;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;
import java.util.concurrent.Callable;

/**
* An example of how to configure delegation for an account.
*/
@CommandLine.Command(name = "ConfigureDelegation", mixinStandardHelpOptions = true)
public class ConfigureDelegation implements Callable<Integer> {

@CommandLine.Option(
names = {"--endpoint"},
description = "GRPC interface of the node.",
defaultValue = "http://localhost:20002")
private String endpoint;

@CommandLine.Option(
names = {"--timeout"},
description = "GRPC request timeout in milliseconds.",
defaultValue = "100000")
private int timeout;

@Override
public Integer call() throws MalformedURLException, ClientInitializationException {
val endpointUrl = new URL(this.endpoint);

Connection connection = Connection.newBuilder()
.host(endpointUrl.getHost())
.port(endpointUrl.getPort())
.build();
val client = ClientV2.from(connection);

AccountAddress sender = AccountAddress.from("3WZE6etUvVp1eyhEtTxqZrQaanTAZnZCHEmZmDyCbCwxnmQuPE");
TransactionSigner signer = TransactionSigner.from(
SignerEntry.from(Index.from(0), Index.from(0),
ED25519SecretKey
.from("56f60de843790c308dac2d59a5eec9f6b1649513f827e5a13d7038accfe31784")));
AccountInfo accountInfo = client.getAccountInfo(BlockQuery.LAST_FINAL, AccountQuery.from(sender));
val tx = TransactionFactory.newConfigureDelegation()
.nonce(accountInfo.getNonce())
.expiry(Expiry.createNew().addMinutes(5))
.signer(signer)
.sender(sender)
.payload(ConfigureDelegationPayload.builder()
.capital(CCDAmount.from(200))
.delegationTarget(DelegationTarget.builder()
.type(DelegationTarget.DelegationType.BAKER)
.bakerId(BakerId.from(207))
.build())
.build())
.build();
Hash hash = client.sendTransaction(tx);
System.out.println(hash);
Optional<FinalizedBlockItem> finalizedBlockItem = client.waitUntilFinalized(hash, this.timeout);
System.out.println(finalizedBlockItem);

return 0;
}

public static void main(String[] args) {
int exitCode = new CommandLine(new ConfigureDelegation()).execute(args);
System.exit(exitCode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.concordium.sdk.ClientV2;
import com.concordium.sdk.Connection;
import com.concordium.sdk.exceptions.ClientInitializationException;
import com.concordium.sdk.transactions.AccountNonce;
import com.concordium.sdk.types.AccountAddress;
import com.concordium.sdk.types.Nonce;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
Expand All @@ -31,7 +31,7 @@ public Integer call() throws ClientInitializationException, MalformedURLExceptio
.build();


AccountNonce nextAccountSequenceNumber = ClientV2
Nonce nextAccountSequenceNumber = ClientV2
.from(connection)
.getNextAccountSequenceNumber(ACCOUNT_ADDRESS);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.concordium.sdk.exceptions.ClientInitializationException;
import com.concordium.sdk.requests.AccountQuery;
import com.concordium.sdk.requests.BlockQuery;
import com.concordium.sdk.responses.blockitemstatus.FinalizedBlockItem;
import com.concordium.sdk.transactions.*;
import com.concordium.sdk.types.AccountAddress;
import lombok.var;
Expand All @@ -15,6 +16,7 @@

import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;
import java.util.concurrent.Callable;

@Command(name = "SendSimpleTransfer", mixinStandardHelpOptions = true)
Expand Down Expand Up @@ -52,17 +54,18 @@ public Integer call() throws MalformedURLException, ClientInitializationExceptio

var client = ClientV2.from(connection);
var senderInfo = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(sender));
var nonce = senderInfo.getAccountNonce();
var nonce = senderInfo.getNonce();
var txnHash = client.sendTransaction(TransactionFactory.newTransfer()
.sender(sender)
.receiver(receiver)
.amount(amount)
.nonce(AccountNonce.from(nonce))
.nonce(nonce)
.expiry(expiry)
.signer(signer)
.build());
System.out.println(txnHash);

Optional<FinalizedBlockItem> finalizedBlockItem = client.waitUntilFinalized(txnHash, this.timeout);
System.out.println(finalizedBlockItem);
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public Integer call() throws IOException, ClientInitializationException {
.timeout(timeout)
.build();
var client = ClientV2.from(connection);
Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce();
Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getNonce();

switch (this.methodName) {
case INIT:
Expand Down Expand Up @@ -119,7 +119,7 @@ private void handleInit(ClientV2 client, Nonce nonce) {
.sender(AccountAddress.from(SENDER_ADDRESS))
.payload(payload)
.expiry(EXPIRY)
.nonce(AccountNonce.from(nonce))
.nonce(nonce)
.signer(SIGNER)
.maxEnergyCost(UInt64.from(10000))
.build();
Expand All @@ -135,7 +135,7 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete
.sender(AccountAddress.from(SENDER_ADDRESS))
.payload(payload)
.expiry(EXPIRY)
.nonce(AccountNonce.from(nonce))
.nonce(nonce)
.signer(SIGNER)
.maxEnergyCost(UInt64.from(10000))
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public Integer call() throws Exception {
.timeout(timeout)
.build();
var client = ClientV2.from(connection);
Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getAccountNonce();
Nonce nonce = client.getAccountInfo(BlockQuery.BEST, AccountQuery.from(AccountAddress.from(SENDER_ADDRESS))).getNonce();
switch (this.methodName) {
case INIT:
handleInit(client, nonce);
Expand Down Expand Up @@ -136,7 +136,7 @@ private void handleInit(ClientV2 client, Nonce nonce) {
.sender(AccountAddress.from(SENDER_ADDRESS))
.payload(payload)
.expiry(EXPIRY)
.nonce(AccountNonce.from(nonce))
.nonce(nonce)
.signer(SIGNER)
.maxEnergyCost(UInt64.from(10000))
.build();
Expand All @@ -152,7 +152,7 @@ private void handleMethod(ClientV2 client, Nonce nonce, SchemaParameter paramete
.sender(AccountAddress.from(SENDER_ADDRESS))
.payload(payload)
.expiry(EXPIRY)
.nonce(AccountNonce.from(nonce))
.nonce(nonce)
.signer(SIGNER)
.maxEnergyCost(UInt64.from(10000))
.build();
Expand Down
2 changes: 1 addition & 1 deletion concordium-sdk/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>com.concordium.sdk</groupId>
<artifactId>concordium-sdk-base</artifactId>
<version>6.1.0</version>
<version>6.1.1-SNAPSHOT</version>
</parent>

<groupId>com.concordium.sdk</groupId>
Expand Down
13 changes: 6 additions & 7 deletions concordium-sdk/src/main/java/com/concordium/sdk/ClientV2.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import com.concordium.sdk.transactions.smartcontracts.WasmModule;
import com.concordium.sdk.types.AccountAddress;
import com.concordium.sdk.types.ContractAddress;
import com.concordium.sdk.types.Nonce;
import com.concordium.sdk.types.Timestamp;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.ByteString;
Expand Down Expand Up @@ -234,14 +235,12 @@ public Hash sendTransaction(final AccountTransaction accountTransaction) {
/**
* Sends a credential deployment transaction to the Concordium Node.
*
* @param expiry the transaction expiry, i.e. the time after which the transaction is invalid
* @param rawPayload the serialized bytes of the credential deployment transaction, including its signatures
* @param credentialDeploymentTransaction the credential deployment to send.
* @return Transaction {@link Hash}.
*/
public Hash sendCredentialDeploymentTransaction(CredentialDeploymentTransaction credentialDeploymentTransaction) {
val req = ClientV2MapperExtensions.to(credentialDeploymentTransaction);
val grpcOutput = this.server().sendBlockItem(req);

return to(grpcOutput);
}

Expand Down Expand Up @@ -304,15 +303,15 @@ public ChainParameters getChainParameters(BlockQuery blockQuery) {
}

/**
* Retrieves the next {@link AccountNonce} for an account.
* This is the {@link AccountNonce} to use for future transactions
* Retrieves the next {@link Nonce} for an account.
* This is the {@link Nonce} to use for future transactions
* E.g. when using {@link ClientV2#sendTransaction(AccountTransaction)}
* When this function is queried with a non-existent account it will report the next available account nonce to be 1 and all transactions as finalized.
*
* @param address The {@link AccountAddress}
* @return The next {@link AccountNonce}
* @return The next {@link Nonce}
*/
public AccountNonce getNextAccountSequenceNumber(AccountAddress address) {
public Nonce getNextAccountSequenceNumber(AccountAddress address) {
val grpcOutput = this.server()
.getNextAccountSequenceNumber(to(address));
return to(grpcOutput);
Expand Down
Loading

0 comments on commit 47576a4

Please sign in to comment.