Skip to content

Commit

Permalink
issue #133 - refactoring + stub for delegated harvesting
Browse files Browse the repository at this point in the history
network currency and network harvesting mosaics sorted out a bit
  • Loading branch information
tonowie committed Nov 24, 2019
1 parent ef92335 commit 1a88f48
Show file tree
Hide file tree
Showing 9 changed files with 400 additions and 225 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ public class NetworkCurrencyMosaic extends Mosaic {
public static final boolean LEVYMUTABLE = false;

/** one of network currency taking the divisibility into account */
public static final NetworkCurrencyMosaic ONE = NetworkCurrencyMosaic.createRelative(BigDecimal.ONE);
public static final Mosaic ONE = createRelative(BigDecimal.ONE);
/** ten of network currency taking the divisibility into account */
public static final NetworkCurrencyMosaic TEN = NetworkCurrencyMosaic.createRelative(BigDecimal.TEN);
public static final Mosaic TEN = createRelative(BigDecimal.TEN);

/**
* create specified amount of micro XPX
*
* @param amount amount of micro XPX
*/
public NetworkCurrencyMosaic(BigInteger amount) {
super(NetworkCurrencyMosaic.ID, amount);
super(ID, amount);
}

/**
Expand All @@ -76,8 +76,8 @@ public NetworkCurrencyMosaic(BigInteger amount) {
* @param amount amount to send
* @return a XPX instance
*/
public static NetworkCurrencyMosaic createRelative(BigDecimal amount) {
BigInteger relativeAmount = BigDecimal.valueOf(Math.pow(10, NetworkCurrencyMosaic.DIVISIBILITY)).multiply(amount).toBigInteger();
public static Mosaic createRelative(BigDecimal amount) {
BigInteger relativeAmount = BigDecimal.valueOf(Math.pow(10, DIVISIBILITY)).multiply(amount).toBigInteger();
return new NetworkCurrencyMosaic(relativeAmount);
}

Expand All @@ -87,7 +87,7 @@ public static NetworkCurrencyMosaic createRelative(BigDecimal amount) {
* @param amount amount to send
* @return a XPX instance
*/
public static NetworkCurrencyMosaic createAbsolute(BigInteger amount) {
public static Mosaic createAbsolute(BigInteger amount) {
return new NetworkCurrencyMosaic(amount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,26 @@
import java.math.BigInteger;

import io.proximax.sdk.model.namespace.NamespaceId;
import io.proximax.sdk.model.transaction.UInt64Id;

/**
* NetworkHarvestMosaic mosaic
*
* This represents the per-network harvest mosaic. This mosaicId is aliased with namespace name `cat.harvest`.
*
* @since 0.10.2
* <p>
* This represents the per-network harvest mosaic
* </p>
* <p>
* <b>WARNING</b> this is not used at the moment
* </p>
*/
public class NetworkHarvestMosaic extends Mosaic {
/**
* Namespace with alias to the network currency mosaic
*/
public static final String MOSAIC_NAMESPACE = "prx.harvest";

/**
* ID of `harvest` namespace.
* ID of network currency
*/
public static final NamespaceId ID = new NamespaceId("cat.harvest");
public static final UInt64Id ID = new NamespaceId(MOSAIC_NAMESPACE);
/**
* Divisibility
*/
Expand All @@ -49,38 +55,44 @@ public class NetworkHarvestMosaic extends Mosaic {
* Is supply mutable
*/
public static final boolean SUPPLYMUTABLE = true;
/**
* Is levy mutable
*/
public static final boolean LEVYMUTABLE = false;

/** one of network currency taking the divisibility into account */
public static final Mosaic ONE = createRelative(BigDecimal.ONE);
/** ten of network currency taking the divisibility into account */
public static final Mosaic TEN = createRelative(BigDecimal.TEN);

/**
* create new instance of network harvest mosaic of specified amount
* create specified amount of micro XPX
*
* @param amount amount of mosaic irrespective of divisibility
* @param amount amount of micro XPX
*/
public NetworkHarvestMosaic(BigInteger amount) {

super(NetworkHarvestMosaic.ID, amount);
super(ID, amount);
}

/**
* Create xem with using xem as unit.
* Create XPX with using XPX as unit.
*
* @param amount amount to send
* @return a NetworkCurrencyMosaic instance
* @return a XPX instance
*/
public static NetworkHarvestMosaic createRelative(BigInteger amount) {

BigInteger relativeAmount = BigDecimal.valueOf(Math.pow(10, NetworkHarvestMosaic.DIVISIBILITY)).toBigInteger()
.multiply(amount);
public static Mosaic createRelative(BigDecimal amount) {
BigInteger relativeAmount = BigDecimal.valueOf(Math.pow(10, DIVISIBILITY)).multiply(amount)
.toBigInteger();
return new NetworkHarvestMosaic(relativeAmount);
}

/**
* Create xem with using micro xem as unit, 1 NetworkCurrencyMosaic = 1000000 micro NetworkCurrencyMosaic.
* Create XPX with using micro XPX as unit, 1 XPX = 1000000 micro XPX.
*
* @param amount amount to send
* @return a NetworkCurrencyMosaic instance
* @return a XPX instance
*/
public static NetworkHarvestMosaic createAbsolute(BigInteger amount) {

public static Mosaic createAbsolute(BigInteger amount) {
return new NetworkHarvestMosaic(amount);
}
}
138 changes: 138 additions & 0 deletions src/main/java/io/proximax/sdk/utils/AccountHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Copyright 2019 ProximaX Limited. All rights reserved.
* Use of this source code is governed by the Apache 2.0
* license that can be found in the LICENSE file.
*/
package io.proximax.sdk.utils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import io.proximax.sdk.BlockchainApi;
import io.proximax.sdk.BlockchainRepository;
import io.proximax.sdk.ListenerRepository;
import io.proximax.sdk.TransactionRepository;
import io.proximax.sdk.model.account.Account;
import io.proximax.sdk.model.account.PublicAccount;
import io.proximax.sdk.model.blockchain.NetworkType;
import io.proximax.sdk.model.mosaic.NetworkHarvestMosaic;
import io.proximax.sdk.model.transaction.AccountLinkTransaction;
import io.proximax.sdk.model.transaction.AggregateTransaction;
import io.proximax.sdk.model.transaction.LockFundsTransaction;
import io.proximax.sdk.model.transaction.Message;
import io.proximax.sdk.model.transaction.ModifyMultisigAccountTransaction;
import io.proximax.sdk.model.transaction.TransferTransaction;

/**
* TODO add proper description
*/
public class AccountHelper extends BaseHelper {

/**
* </p>
* create new helper instance
* </p>
* <p>
* note this might require connection to the network if network type is not known to the provided api
* </p>
*
* @param api
*/
public AccountHelper(BlockchainApi api) {
super(api);
}

/**
* get infinite source of new, random accounts
*
* @return stream of random accounts
*/
public Stream<Account> accountRandom() {
final NetworkType network = api.getNetworkType();
return Stream.generate(() -> Account.generateNewAccount(network));
}

/**
* generate specified number of account instances
*
* @param count the count of items in the returned list of accounts
* @return list of accounts
*/
public List<Account> accountRandom(int count) {
// generate specified number of random accounts
return accountRandom().limit(count).collect(Collectors.toList());
}

/**
* convert account to multisig account
*
* @param account
* @param cosigners
* @param minApprovals
* @param minRemovals
* @param optinBlocks
* @param confirmationTimeoutSeconds
*/
public void accountToMultisig(Account account, List<PublicAccount> cosigners, int minApprovals, int minRemovals,
int optinBlocks, int confirmationTimeoutSeconds) {
// prepare transaction repo
TransactionRepository transactions = api.createTransactionRepository();
// prepare listener
ListenerRepository listener = createListener();
// first prepare the actual transaction to change account to multisig account
ModifyMultisigAccountTransaction multisigChangeTrans = transact.multisigModification()
.changeToMultisig(cosigners, minApprovals, minRemovals).build();
// aggregate bonded transaction is required for cosigner opt-in so create that
AggregateTransaction aggregateTrans = transact.aggregateBonded()
.innerTransactions(multisigChangeTrans.toAggregate(account.getPublicAccount())).build();
// aggregate bonded transaction requires lock funds
LockFundsTransaction lockTrans = transact.lockFunds()
.forAggregate(BigInteger.valueOf(optinBlocks), api.sign(aggregateTrans, account)).build();
// announce lock funds and wait for confirmation
transactionConfirmed(transactions, listener, lockTrans, account, confirmationTimeoutSeconds);
// !!! wait a bit for server to get into consistent state !!!
sleepForAWhile();
// now announce the aggregate transaction
transactionBondedAdded(transactions, listener, aggregateTrans, account, confirmationTimeoutSeconds);
}

/**
* activate delegated harvesting for an account
*
* @param account the account that will get delegated harvesting activated
* @param nodePublicKey node public key (use {@link BlockchainRepository#getNodeInfo()} or /node/info)
* @param confirmationTimeoutSeconds transaction timeout in seconds
* @return the remote account which is used for delegated harvesting
* @deprecated not supported yet
*/
@Deprecated
public Account activateDelegatedHarvesting(Account account, String nodePublicKey, int confirmationTimeoutSeconds) {
// prepare transaction repo
TransactionRepository transactions = api.createTransactionRepository();
// prepare listener
ListenerRepository listener = createListener();
// prepare new account that will be sent to the node
Account remoteAccount = Account.generateNewAccount(api.getNetworkType());
// link accounts
AccountLinkTransaction link = transact.accountLink().link(remoteAccount.getPublicAccount()).build();
// send 500 harvest currency to node public key
PublicAccount node = PublicAccount.createFromPublicKey(nodePublicKey, api.getNetworkType());
// TODO figure out the message!!!
Message message = null;
TransferTransaction transfer = transact.transfer()
.mosaics(NetworkHarvestMosaic.createRelative(BigDecimal.valueOf(500))).to(node.getAddress())
.message(message).build();
// wrap both transactions to aggregate complete transaction
AggregateTransaction transaction = transact.aggregateComplete()
.innerTransactions(link.toAggregate(account.getPublicAccount()),
transfer.toAggregate(account.getPublicAccount()))
.build();
// wait for confirmation
transactionConfirmed(transactions, listener, transaction, account, confirmationTimeoutSeconds);
// upon successful execution return the remote account
return remoteAccount;
}
}
Loading

0 comments on commit 1a88f48

Please sign in to comment.