Skip to content

Commit

Permalink
Fee calculation strategies and transaction builders (#116)
Browse files Browse the repository at this point in the history
* issue #99 - fee calculation strategies and transaction builders

* issue #99 - adding ZERO strategy meaning no fees

* issue #99 - refactoring + account link transaction

* added account link transaction and builder
* renamed transaction factory to transaction builder factory
* made transaction builder factory available to all e2e tests
* removed duplication of aggregate transaction size calculation

* issue #99 - updates to account link, aggregate and alias transactions

* issue #99 - LockFundsTransaction added

* issue #99 - fee calculation is now fully owned by the builder

* issue #99 - more transactions added, e2e tests updated, comments

* issue #99 - junit test updates

* issue #99 - fixed copy-paste error

* issue #99 - adding blockchain config/upgrade + modify contract

* issue #99 - refactoring tests to match constructors

* issue #99 - size adding more transactions + fixes

fixes for builder setter names and for size calculation

* issue #99 - secret lock and proof + account properties

* issue #99 - finished refactoring. e2e tests pass

* issue #99 - api cleanup and fixed junit tests

* issue #99 - first batch of builder junit tests

* issue #99 - wrote tests for builders and couple transactions
  • Loading branch information
tonowie authored Sep 3, 2019
1 parent ad7c709 commit 4035778
Show file tree
Hide file tree
Showing 103 changed files with 7,267 additions and 3,024 deletions.
11 changes: 3 additions & 8 deletions src/e2e/java/io/proximax/sdk/E2EAccountLinkTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.math.BigInteger;
import java.util.concurrent.TimeUnit;

import org.junit.jupiter.api.BeforeAll;
Expand All @@ -32,7 +31,6 @@
import io.proximax.core.crypto.KeyPair;
import io.proximax.sdk.model.account.Account;
import io.proximax.sdk.model.account.AccountInfo;
import io.proximax.sdk.model.transaction.AccountLinkAction;
import io.proximax.sdk.model.transaction.AccountLinkTransaction;
import io.proximax.sdk.model.transaction.TransactionStatusError;

Expand All @@ -59,8 +57,7 @@ void test01linkAccounts() {

@Test
void test02unlinkAccounts() {
AccountLinkTransaction link = new AccountLinkTransaction(remoteAccount.getPublicAccount(),
AccountLinkAction.UNLINK, getNetworkType(), getDeadline(), BigInteger.ZERO);
AccountLinkTransaction link = transact.accountLink().unlink(remoteAccount.getPublicAccount()).build();
transactionHttp.announce(api.sign(link, localAccount)).blockingFirst();
listener.confirmed(localAccount.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();

Expand All @@ -82,16 +79,14 @@ void test03relinkAccounts() {
@Test
void test04overLinkAccounts() {
Account remoteAccount2 = new Account(new KeyPair(), getNetworkType());
AccountLinkTransaction link = new AccountLinkTransaction(remoteAccount2.getPublicAccount(),
AccountLinkAction.LINK, getNetworkType(), getDeadline(), BigInteger.ZERO);
AccountLinkTransaction link = transact.accountLink().link(remoteAccount2.getPublicAccount()).build();
transactionHttp.announce(api.sign(link, localAccount)).blockingFirst();
TransactionStatusError error = listener.status(localAccount.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
assertEquals("Failure_AccountLink_Link_Already_Exists", error.getStatus());
}

private void linkAndTestAccounts(Account localAccount, Account remoteAccount) {
AccountLinkTransaction link = new AccountLinkTransaction(remoteAccount.getPublicAccount(), AccountLinkAction.LINK,
getNetworkType(), getDeadline(), BigInteger.ZERO);
AccountLinkTransaction link = transact.accountLink().link(remoteAccount.getPublicAccount()).build();
transactionHttp.announce(api.sign(link, localAccount)).blockingFirst();
listener.confirmed(localAccount.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();

Expand Down
251 changes: 112 additions & 139 deletions src/e2e/java/io/proximax/sdk/E2EAccountTest.java

Large diffs are not rendered by default.

164 changes: 67 additions & 97 deletions src/e2e/java/io/proximax/sdk/E2EAggregateTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,20 @@ public class E2EAggregateTest extends E2EBaseTest {
private final Account bob = new Account(new KeyPair(), getNetworkType());
private final Account mike = new Account(new KeyPair(), getNetworkType());

private final MosaicId mosaicX = new MosaicId(UInt64Utils.fromLongArray(new long[] {481110499,231112638}));
private final MosaicId mosaicY = new MosaicId(UInt64Utils.fromLongArray(new long[] {519256100,642862634}));


private final MosaicId mosaicX = new MosaicId(UInt64Utils.fromLongArray(new long[] { 481110499, 231112638 }));
private final MosaicId mosaicY = new MosaicId(UInt64Utils.fromLongArray(new long[] { 519256100, 642862634 }));

@BeforeAll
void addListener() {
disposables.add(listener.status(alice.getAddress())
.subscribe(err -> logger.error("Operation failed for alice: {}", err), t -> logger.error("exception thrown", t)));
disposables.add(listener.status(bob.getAddress())
.subscribe(err -> logger.error("Operation failed for bob: {}", err), t -> logger.error("exception thrown", t)));
disposables.add(listener.status(mike.getAddress())
.subscribe(err -> logger.error("Operation failed for mike: {}", err), t -> logger.error("exception thrown", t)));
disposables.add(
listener.status(alice.getAddress()).subscribe(err -> logger.error("Operation failed for alice: {}", err),
t -> logger.error("exception thrown", t)));
disposables
.add(listener.status(bob.getAddress()).subscribe(err -> logger.error("Operation failed for bob: {}", err),
t -> logger.error("exception thrown", t)));
disposables
.add(listener.status(mike.getAddress()).subscribe(err -> logger.error("Operation failed for mike: {}", err),
t -> logger.error("exception thrown", t)));
// send funds to alice and bob
logger.info("Mosaic X: {}", mosaicX.getIdAsHex());
logger.info("Mosaic Y: {}", mosaicY.getIdAsHex());
Expand Down Expand Up @@ -97,36 +99,28 @@ void escrowBetweenTwoParties() {
sendMosaic(seedAccount, bob.getAddress(), new Mosaic(mosaicY, BigInteger.TEN));
logger.info("Escrow between {} and {}", alice, bob);
// send mosaic X from alice to bob
TransferTransaction aliceToBob = TransferTransaction.create(getDeadline(),
bob.getAddress(),
Arrays.asList(NetworkCurrencyMosaic.ONE),
PlainMessage.Empty,
getNetworkType());
TransferTransaction aliceToBob = transact.transfer().mosaics(NetworkCurrencyMosaic.ONE).to(bob.getAddress())
.build();
// send mosaic Y from bob to alice
TransferTransaction bobToAlice = TransferTransaction.create(getDeadline(),
alice.getAddress(),
Arrays.asList(new Mosaic(mosaicY, BigInteger.TEN)),
PlainMessage.Empty,
getNetworkType());
TransferTransaction bobToAlice = transact.transfer().mosaics(new Mosaic(mosaicY, BigInteger.TEN))
.to(alice.getAddress()).build();
// aggregate bonded with the 2 transactions - escrow
AggregateTransaction escrow = AggregateTransaction.createBonded(getDeadline(),
Arrays.asList(aliceToBob.toAggregate(alice.getPublicAccount()),
bobToAlice.toAggregate(bob.getPublicAccount())),
getNetworkType());
AggregateTransaction escrow = transact.aggregateBonded()
.innerTransactions(aliceToBob.toAggregate(alice.getPublicAccount()),
bobToAlice.toAggregate(bob.getPublicAccount()))
.build();
// alice sign the escrow trans
SignedTransaction signedEscrow = api.sign(escrow, alice);
// lock funds for escrow
LockFundsTransaction lock = LockFundsTransaction.create(getDeadline(),
NetworkCurrencyMosaic.TEN,
BigInteger.valueOf(480),
signedEscrow,
getNetworkType());
LockFundsTransaction lock = transact.lockFunds().mosaic(NetworkCurrencyMosaic.TEN)
.duration(BigInteger.valueOf(480)).signedTransaction(signedEscrow).build();
// alice sign and announce the lock
logger.info("announcing {}", lock);
SignedTransaction signedLock = api.sign(lock, alice);
transactionHttp.announce(signedLock).blockingFirst();
// wait for lock confirmation
logger.info("got confirmation: {}", listener.confirmed(alice.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst());
logger.info("got confirmation: {}",
listener.confirmed(alice.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst());
sleepForAWhile();
// announce escrow
logger.info("announcing {}", escrow);
Expand All @@ -135,7 +129,8 @@ void escrowBetweenTwoParties() {
listener.aggregateBondedAdded(alice.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();

// bob sign the escrow
AggregateTransaction pendingEscrow = accountHttp.aggregateBondedTransactions(bob.getPublicAccount()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
AggregateTransaction pendingEscrow = accountHttp.aggregateBondedTransactions(bob.getPublicAccount())
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
CosignatureSignedTransaction signedCosig = CosignatureTransaction.create(pendingEscrow).signWith(bob);
// bob announce the cosignature
logger.info("announcing escrow");
Expand Down Expand Up @@ -166,7 +161,7 @@ void escrowBetweenTwoParties() {
}
});
}

@Test
void escrowBetweenTwoPartiesComplete() {
returnAllToSeed(alice);
Expand All @@ -176,22 +171,16 @@ void escrowBetweenTwoPartiesComplete() {
sendMosaic(seedAccount, bob.getAddress(), new Mosaic(mosaicY, BigInteger.TEN));
logger.info("Escrow between {} and {}", alice, bob);
// send mosaic X from alice to bob
TransferTransaction aliceToBob = TransferTransaction.create(getDeadline(),
bob.getAddress(),
Arrays.asList(NetworkCurrencyMosaic.ONE),
PlainMessage.Empty,
getNetworkType());
TransferTransaction aliceToBob = transact.transfer().mosaics(NetworkCurrencyMosaic.ONE).to(bob.getAddress())
.build();
// send mosaic Y from bob to alice
TransferTransaction bobToAlice = TransferTransaction.create(getDeadline(),
alice.getAddress(),
Arrays.asList(new Mosaic(mosaicY, BigInteger.TEN)),
PlainMessage.Empty,
getNetworkType());
TransferTransaction bobToAlice = transact.transfer().mosaics(new Mosaic(mosaicY, BigInteger.TEN))
.to(alice.getAddress()).build();
// aggregate bonded with the 2 transactions - escrow
AggregateTransaction escrow = AggregateTransaction.createComplete(getDeadline(),
Arrays.asList(aliceToBob.toAggregate(alice.getPublicAccount()),
bobToAlice.toAggregate(bob.getPublicAccount())),
getNetworkType());
AggregateTransaction escrow = transact.aggregateComplete()
.innerTransactions(aliceToBob.toAggregate(alice.getPublicAccount()),
bobToAlice.toAggregate(bob.getPublicAccount()))
.build();
// alice sign the escrow trans
SignedTransaction signedEscrow = api.signWithCosigners(escrow, alice, Arrays.asList(bob));
// announce escrow
Expand Down Expand Up @@ -223,7 +212,7 @@ void escrowBetweenTwoPartiesComplete() {
}
});
}

@Test
void escrowBetweenThreeParties() {
returnAllToSeed(alice);
Expand All @@ -236,38 +225,25 @@ void escrowBetweenThreeParties() {
sleepForAWhile();
logger.info("Escrow between {}, {} and {}", alice, bob, mike);
// send mosaic X from alice to bob
TransferTransaction aliceToBob = TransferTransaction.create(getDeadline(),
bob.getAddress(),
Arrays.asList(NetworkCurrencyMosaic.ONE),
PlainMessage.Empty,
getNetworkType());
TransferTransaction aliceToBob = transact.transfer().mosaics(NetworkCurrencyMosaic.ONE).to(bob.getAddress())
.build();
// send mosaic Y from bob to alice
TransferTransaction bobToAlice = TransferTransaction.create(getDeadline(),
alice.getAddress(),
Arrays.asList(new Mosaic(mosaicY, BigInteger.TEN)),
PlainMessage.Empty,
getNetworkType());
TransferTransaction bobToAlice = transact.transfer().mosaics(new Mosaic(mosaicY, BigInteger.TEN))
.to(alice.getAddress()).build();
// send mosaic Y from bob to alice
TransferTransaction mikeToAlice = TransferTransaction.create(getDeadline(),
alice.getAddress(),
Arrays.asList(NetworkCurrencyMosaic.ONE),
PlainMessage.Empty,
getNetworkType());
TransferTransaction mikeToAlice = transact.transfer().mosaics(NetworkCurrencyMosaic.ONE).to(alice.getAddress())
.build();
// aggregate bonded with the 3 transactions - escrow
AggregateTransaction escrow = AggregateTransaction.createBonded(getDeadline(),
Arrays.asList(
aliceToBob.toAggregate(alice.getPublicAccount()),
AggregateTransaction escrow = transact.aggregateBonded()
.innerTransactions(aliceToBob.toAggregate(alice.getPublicAccount()),
bobToAlice.toAggregate(bob.getPublicAccount()),
mikeToAlice.toAggregate(mike.getPublicAccount())),
getNetworkType());
mikeToAlice.toAggregate(mike.getPublicAccount()))
.build();
// alice sign the escrow trans
SignedTransaction signedEscrow = api.sign(escrow, alice);
// lock funds for escrow
LockFundsTransaction lock = LockFundsTransaction.create(getDeadline(),
NetworkCurrencyMosaic.TEN,
BigInteger.valueOf(480),
signedEscrow,
getNetworkType());
LockFundsTransaction lock = transact.lockFunds().mosaic(NetworkCurrencyMosaic.TEN)
.duration(BigInteger.valueOf(480)).signedTransaction(signedEscrow).build();
// alice sign and announce the lock
logger.info("announcing {}", lock);
SignedTransaction signedLock = api.sign(lock, alice);
Expand All @@ -280,18 +256,20 @@ void escrowBetweenThreeParties() {
transactionHttp.announceAggregateBonded(signedEscrow).blockingFirst();
// wait for escrow confirmation
listener.aggregateBondedAdded(alice.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();

// bob sign the escrow
AggregateTransaction pendingEscrowBob = accountHttp.aggregateBondedTransactions(bob.getPublicAccount()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
AggregateTransaction pendingEscrowBob = accountHttp.aggregateBondedTransactions(bob.getPublicAccount())
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
CosignatureSignedTransaction signedCosigBob = CosignatureTransaction.create(pendingEscrowBob).signWith(bob);
// bob announce the cosignature
logger.info("announcing cosig bob");
transactionHttp.announceAggregateBondedCosignature(signedCosigBob).blockingFirst();
// wait for cosig event
listener.cosignatureAdded(bob.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();

// mike sign the escrow
AggregateTransaction pendingEscrowMike = accountHttp.aggregateBondedTransactions(mike.getPublicAccount()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
AggregateTransaction pendingEscrowMike = accountHttp.aggregateBondedTransactions(mike.getPublicAccount())
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
CosignatureSignedTransaction signedCosigMike = CosignatureTransaction.create(pendingEscrowMike).signWith(mike);
// mike announce the cosignature
logger.info("announcing cosig mike");
Expand Down Expand Up @@ -329,7 +307,7 @@ void escrowBetweenThreeParties() {
List<Mosaic> mikeMosaics = accountHttp.getAccountInfo(mike.getAddress()).blockingFirst().getMosaics();
assertTrue(mikeMosaics.isEmpty());
}

@Test
void askforMoney() {
returnAllToSeed(alice);
Expand All @@ -338,30 +316,21 @@ void askforMoney() {
sendMosaic(seedAccount, bob.getAddress(), new Mosaic(mosaicY, BigInteger.TEN));
logger.info("Alice asks for money");
// send mosaic X from alice to bob
TransferTransaction aliceToBob = TransferTransaction.create(getDeadline(),
bob.getAddress(),
Arrays.asList(),
PlainMessage.create("send me 10 Y"),
getNetworkType());
TransferTransaction aliceToBob = transact.transfer().to(bob.getAddress())
.message(PlainMessage.create("send me 10 Y")).build();
// send mosaic Y from bob to alice
TransferTransaction bobToAlice = TransferTransaction.create(getDeadline(),
alice.getAddress(),
Arrays.asList(new Mosaic(mosaicY, BigInteger.TEN)),
PlainMessage.Empty,
getNetworkType());
TransferTransaction bobToAlice = transact.transfer().mosaics(new Mosaic(mosaicY, BigInteger.TEN))
.to(alice.getAddress()).build();
// aggregate bonded with the 2 transactions - escrow
AggregateTransaction escrow = AggregateTransaction.createBonded(getDeadline(),
Arrays.asList(aliceToBob.toAggregate(alice.getPublicAccount()),
bobToAlice.toAggregate(bob.getPublicAccount())),
getNetworkType());
AggregateTransaction escrow = transact.aggregateBonded()
.innerTransactions(aliceToBob.toAggregate(alice.getPublicAccount()),
bobToAlice.toAggregate(bob.getPublicAccount()))
.build();
// alice sign the escrow trans
SignedTransaction signedEscrow = api.sign(escrow, alice);
// lock funds for escrow
LockFundsTransaction lock = LockFundsTransaction.create(getDeadline(),
NetworkCurrencyMosaic.TEN,
BigInteger.valueOf(480),
signedEscrow,
getNetworkType());
LockFundsTransaction lock = transact.lockFunds().mosaic(NetworkCurrencyMosaic.TEN)
.duration(BigInteger.valueOf(480)).signedTransaction(signedEscrow).build();
// alice sign and announce the lock
logger.info("announcing {}", lock);
SignedTransaction signedLock = api.sign(lock, alice);
Expand All @@ -375,7 +344,8 @@ void askforMoney() {
// wait for escrow confirmation
listener.aggregateBondedAdded(alice.getAddress()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst();
// bob sign the escrow
AggregateTransaction pendingEscrow = accountHttp.aggregateBondedTransactions(bob.getPublicAccount()).timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
AggregateTransaction pendingEscrow = accountHttp.aggregateBondedTransactions(bob.getPublicAccount())
.timeout(getTimeoutSeconds(), TimeUnit.SECONDS).blockingFirst().get(0);
CosignatureSignedTransaction signedCosig = CosignatureTransaction.create(pendingEscrow).signWith(bob);
// bob announce the cosignature
logger.info("announcing escrow");
Expand Down
Loading

0 comments on commit 4035778

Please sign in to comment.