Skip to content
This repository has been archived by the owner on Sep 26, 2019. It is now read-only.

Commit

Permalink
Acceptance test - configurable gas price (#1023)
Browse files Browse the repository at this point in the history
  • Loading branch information
CjHare authored Mar 4, 2019
1 parent d630e3c commit fd60946
Show file tree
Hide file tree
Showing 6 changed files with 243 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
*/
package tech.pegasys.pantheon.tests.acceptance;

import static org.web3j.utils.Convert.Unit.ETHER;

import tech.pegasys.pantheon.tests.acceptance.dsl.AcceptanceTestBase;
import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account;
import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.Amount;
import tech.pegasys.pantheon.tests.acceptance.dsl.node.Node;

import org.junit.Before;
Expand All @@ -27,14 +26,17 @@ public class CreateAccountAcceptanceTest extends AcceptanceTestBase {

@Before
public void setUp() throws Exception {
minerNode = pantheon.createMinerNode("node1");
cluster.start(minerNode, pantheon.createArchiveNode("node2"));
minerNode = pantheon.createMinerNode("minerNode");
cluster.start(minerNode, pantheon.createArchiveNode("archiveNode"));
}

@Test
public void shouldCreateAnAccount() {
final Account account = accounts.createAccount("a-new-account");
minerNode.execute(transactions.createTransfer(account, 20));
cluster.verify(account.balanceEquals("20", ETHER));
final Account account = accounts.createAccount("account-one");
final Amount balance = Amount.ether(20);

minerNode.execute(transactions.createTransfer(account, balance));

cluster.verify(account.balanceEquals(balance));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import tech.pegasys.pantheon.crypto.SECP256K1.PrivateKey;
import tech.pegasys.pantheon.ethereum.core.Address;
import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.Amount;
import tech.pegasys.pantheon.tests.acceptance.dsl.condition.Condition;
import tech.pegasys.pantheon.tests.acceptance.dsl.condition.account.ExpectAccountBalance;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eth.EthTransactions;
Expand Down Expand Up @@ -69,4 +70,9 @@ public Condition balanceEquals(final String expectedBalance, final Unit balanceU
public Condition balanceEquals(final int expectedBalance) {
return balanceEquals(String.valueOf(expectedBalance), Unit.ETHER);
}

public Condition balanceEquals(final Amount expectedBalance) {
return new ExpectAccountBalance(
eth, this, expectedBalance.getValue(), expectedBalance.getUnit());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.tests.acceptance.dsl.blockchain;

import static org.web3j.utils.Convert.Unit.ETHER;
import static org.web3j.utils.Convert.Unit.WEI;

import java.math.BigInteger;

import org.web3j.utils.Convert;
import org.web3j.utils.Convert.Unit;

public class Amount {

private String value;
private Unit unit;

private Amount(final long value, final Unit unit) {
this.value = String.valueOf(value);
this.unit = unit;
}

private Amount(final BigInteger value, final Unit unit) {
this.value = value.toString();
this.unit = unit;
}

public String getValue() {
return value;
}

public Unit getUnit() {
return unit;
}

public Amount subtract(final Amount subtracting) {

final Unit denominator;
if (unit.getWeiFactor().compareTo(subtracting.unit.getWeiFactor()) == -1) {
denominator = unit;
} else {
denominator = subtracting.unit;
}

final BigInteger result =
Convert.fromWei(
Convert.toWei(value, unit)
.subtract(Convert.toWei(subtracting.value, subtracting.unit)),
denominator)
.toBigInteger();

return new Amount(result, denominator);
}

public static Amount ether(final long value) {
return new Amount(value, ETHER);
}

public static Amount wei(final BigInteger value) {
return new Amount(value, WEI);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account;
import tech.pegasys.pantheon.tests.acceptance.dsl.account.Accounts;
import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.Amount;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.account.TransferTransaction;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.account.TransferTransactionBuilder;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.account.TransferTransactionSet;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaGetTransactionReceiptTransaction;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.eea.EeaSendRawTransactionTransaction;
Expand All @@ -33,7 +35,6 @@
import java.util.List;

import org.web3j.tx.Contract;
import org.web3j.utils.Convert.Unit;

public class Transactions {

Expand All @@ -47,14 +48,46 @@ public TransferTransaction createTransfer(final Account recipient, final int amo
return createTransfer(accounts.getPrimaryBenefactor(), recipient, amount);
}

public TransferTransaction createTransfer(final Account recipient, final Amount amount) {
return createTransfer(accounts.getPrimaryBenefactor(), recipient, amount);
}

public TransferTransaction createTransfer(
final Account sender, final Account recipient, final int amount) {
return new TransferTransaction(sender, recipient, String.valueOf(amount), Unit.ETHER);
return new TransferTransactionBuilder()
.sender(sender)
.recipient(recipient)
.amount(Amount.ether(amount))
.build();
}

public TransferTransaction createTransfer(
final Account sender, final Account recipient, final Amount amount, final Amount gasPrice) {
return new TransferTransactionBuilder()
.sender(sender)
.recipient(recipient)
.amount(amount)
.gasPrice(gasPrice)
.build();
}

public TransferTransaction createTransfer(
final Account sender, final Account recipient, final Amount amount) {
return new TransferTransactionBuilder()
.sender(sender)
.recipient(recipient)
.amount(amount)
.build();
}

public TransferTransaction createTransfer(
final Account sender, final Account recipient, final int amount, final BigInteger nonce) {
return new TransferTransaction(sender, recipient, String.valueOf(amount), Unit.ETHER, nonce);
return new TransferTransactionBuilder()
.sender(sender)
.recipient(recipient)
.amount(Amount.ether(amount))
.nonce(nonce)
.build();
}

public EeaSendRawTransactionTransaction createPrivateRawTransaction(
Expand All @@ -65,9 +98,14 @@ public EeaSendRawTransactionTransaction createPrivateRawTransaction(
public TransferTransactionSet createIncrementalTransfers(
final Account sender, final Account recipient, final int etherAmount) {
final List<TransferTransaction> transfers = new ArrayList<>();
final TransferTransactionBuilder transferOneEther =
new TransferTransactionBuilder()
.sender(sender)
.recipient(recipient)
.amount(Amount.ether(1));

for (int i = 1; i <= etherAmount; i++) {
transfers.add(new TransferTransaction(sender, recipient, "1", Unit.ETHER));
transfers.add(transferOneEther.build());
}

return new TransferTransactionSet(transfers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import tech.pegasys.pantheon.ethereum.core.Hash;
import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account;
import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.Amount;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.JsonRequestFactories;
import tech.pegasys.pantheon.tests.acceptance.dsl.transaction.Transaction;

Expand All @@ -30,35 +31,31 @@

public class TransferTransaction implements Transaction<Hash> {

/** Price for each for each GAS units in this transaction (wei). */
private static final BigInteger MINIMUM_GAS_PRICE = BigInteger.valueOf(1000);
private static final BigInteger TRANSFER_GAS_COST = BigInteger.valueOf(21000);

/** Number of GAS units that the transaction will cost. */
private static final BigInteger INTRINSIC_GAS = BigInteger.valueOf(21000);

private final Account sender;
private final Account recipient;
private final String amount;
private final Unit unit;
private final Optional<BigInteger> nonce;

public TransferTransaction(
final Account sender, final Account recipient, final String amount, final Unit unit) {
this(sender, recipient, amount, unit, null);
}
private final String transferAmount;
private final Unit transferUnit;
private final BigInteger gasPrice;
private final BigInteger nonce;

public TransferTransaction(
final Account sender,
final Account recipient,
final String amount,
final Unit unit,
final Amount transferAmount,
final Amount gasPrice,
final BigInteger nonce) {
this.sender = sender;
this.recipient = recipient;
this.amount = amount;
this.unit = unit;
if (nonce != null) {
this.nonce = Optional.of(nonce);
} else {
this.nonce = Optional.empty();
}
this.transferAmount = transferAmount.getValue();
this.transferUnit = transferAmount.getUnit();
this.gasPrice = gasPrice == null ? MINIMUM_GAS_PRICE : convertGasPriceToWei(gasPrice);
this.nonce = nonce;
}

@Override
Expand All @@ -72,15 +69,39 @@ public Hash execute(final JsonRequestFactories node) {
}
}

public Amount executionCost() {
return Amount.wei(INTRINSIC_GAS.multiply(gasPrice));
}

public String signedTransactionData() {
final Optional<BigInteger> nonce = getNonce();

final RawTransaction transaction =
RawTransaction.createEtherTransaction(
nonce.orElse(nonce.orElseGet(sender::getNextNonce)),
MINIMUM_GAS_PRICE,
TRANSFER_GAS_COST,
gasPrice,
INTRINSIC_GAS,
recipient.getAddress(),
Convert.toWei(amount, unit).toBigIntegerExact());
Convert.toWei(transferAmount, transferUnit).toBigIntegerExact());

return toHexString(TransactionEncoder.signMessage(transaction, sender.web3jCredentials()));
}

private Optional<BigInteger> getNonce() {
return nonce == null ? Optional.empty() : Optional.of(nonce);
}

private BigInteger convertGasPriceToWei(final Amount unconverted) {
final BigInteger price =
Convert.toWei(unconverted.getValue(), unconverted.getUnit()).toBigInteger();

if (MINIMUM_GAS_PRICE.compareTo(price) == 1) {
throw new IllegalArgumentException(
String.format(
"Gas price: %s WEI, is below the accepted minimum: %s WEI",
price, MINIMUM_GAS_PRICE));
}

return price;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2019 ConsenSys AG.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package tech.pegasys.pantheon.tests.acceptance.dsl.transaction.account;

import tech.pegasys.pantheon.tests.acceptance.dsl.account.Account;
import tech.pegasys.pantheon.tests.acceptance.dsl.blockchain.Amount;

import java.math.BigInteger;

public class TransferTransactionBuilder {

private Account sender;
private Account recipient;
private Amount transferAmount;
private Amount gasPrice;
private BigInteger nonce;

public TransferTransactionBuilder sender(final Account sender) {
this.sender = sender;
validateSender();
return this;
}

public TransferTransactionBuilder recipient(final Account recipient) {
this.recipient = recipient;
return this;
}

public TransferTransactionBuilder amount(final Amount transferAmount) {
this.transferAmount = transferAmount;
validateTransferAmount();
return this;
}

public TransferTransactionBuilder nonce(final BigInteger nonce) {
this.nonce = nonce;
return this;
}

public TransferTransactionBuilder gasPrice(final Amount gasPrice) {
this.gasPrice = gasPrice;
return this;
}

public TransferTransaction build() {
validateSender();
validateTransferAmount();
return new TransferTransaction(sender, recipient, transferAmount, gasPrice, nonce);
}

private void validateSender() {
if (sender == null) {
throw new IllegalArgumentException("NULL sender is not allowed.");
}
}

private void validateTransferAmount() {
if (transferAmount == null) {
throw new IllegalArgumentException("NULL transferAmount is not allowed.");
}
}
}

0 comments on commit fd60946

Please sign in to comment.