diff --git a/src/test/java/com/casper/sdk/e2e/steps/SpeculativeExecutionSteps.java b/src/test/java/com/casper/sdk/e2e/steps/SpeculativeExecutionSteps.java index 18cce3ccf..fa8c55e93 100644 --- a/src/test/java/com/casper/sdk/e2e/steps/SpeculativeExecutionSteps.java +++ b/src/test/java/com/casper/sdk/e2e/steps/SpeculativeExecutionSteps.java @@ -24,12 +24,13 @@ import java.util.stream.Collectors; import static com.casper.sdk.e2e.utils.AssetUtils.getFaucetPrivateKey; -import static com.casper.sdk.e2e.utils.AssetUtils.getUserPublicKey; +import static com.casper.sdk.e2e.utils.AssetUtils.getUserPrivateKey; import static com.jayway.jsonassert.impl.matcher.IsCollectionWithSize.hasSize; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.greaterThan; +import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.notNullValue; @@ -43,22 +44,22 @@ public class SpeculativeExecutionSteps { private SpeculativeDeployData speculativeDeployData; private Entry transform; private Deploy deploy; - private PublicKey userPublicKey; - private AbstractPrivateKey faucetPrivateKey; - @Given("that a deploy is executed against a node using the speculative_exec RPC API") - public void thatADeployIsExecutedAgainstANodeUsingTheSpeculative_execRPCAPI() throws Exception { - - faucetPrivateKey = getFaucetPrivateKey(); - userPublicKey = getUserPublicKey(1); + @Given("that the {string} account transfers {long} to user-{int} account with a gas payment amount of {long} using the speculative_exec RPC API") + public void thatTheFaucetAccountTransfersToUserAccountUsingTheSpeculative_execRPCAPI(final String faucet, + final long transferAmount, + final int userId, + final long paymentAmount) throws Exception { + final AbstractPrivateKey faucetPrivateKey = getPrivateKey(faucet); + final PublicKey userPublicKey = PublicKey.fromAbstractPublicKey(getPrivateKey(userId).derivePublicKey()); deploy = CasperTransferHelper.buildTransferDeploy( faucetPrivateKey, userPublicKey, - new BigInteger("2500000000"), + BigInteger.valueOf(transferAmount), "casper-net-1", Math.abs(new Random().nextLong()), - BigInteger.valueOf(100000000L), + BigInteger.valueOf(paymentAmount), 1L, Ttl.builder().ttl("30m").build(), new Date(), @@ -67,10 +68,11 @@ public void thatADeployIsExecutedAgainstANodeUsingTheSpeculative_execRPCAPI() th speculativeDeployData = speculauaCasperService.speculativeExec(deploy); } - @Then("a valid speculative_exec_result will be returned") - public void aValidSpeculative_exec_resultWillBeReturned() { + @Then("a valid speculative_exec_result will be returned with {int} transforms") + public void aValidSpeculative_exec_resultWillBeReturned(final int transformCount) { assertThat(speculativeDeployData, is(notNullValue())); assertThat(speculativeDeployData.getExecutionResult(), is(instanceOf(Success.class))); + assertThat(speculativeDeployData.getExecutionResult().getEffect().getTransforms(), hasSize(transformCount)); } @And("the speculative_exec has an api_version of {string}") @@ -92,28 +94,55 @@ public void theExecution_resultsContainsACostOf(int cost) { public void theSpeculative_execHasAValidExecution_result() { final String key = ((Success) speculativeDeployData.getExecutionResult()).getTransfers().get(0); - // getTransform(); final Optional transform = getTransform(key); assertThat(transform.isPresent(), is(true)); this.transform = transform.get(); } - @And("the speculative_exec execution_result contains a valid transfer transform") - public void theSpeculative_execExecution_resultContainsAValidTransferTransform() throws IOException { + @And("the speculative_exec execution_result transform wth the transfer key contains the deploy_hash") + public void theSpeculative_execExecution_resultContainsAValidDeployHash() { + assertThat(this.transform.getTransform(), is(instanceOf(WriteTransfer.class))); + final WriteTransfer writeTransfer = (WriteTransfer) this.transform.getTransform(); + assertThat(writeTransfer.getTransfer().getDeployHash(), is(deploy.getHash().toString())); + } + + @And("the speculative_exec execution_result transform with the transfer key has the amount of {long}") + public void theSpeculative_execExecution_resultContainsAValidTransferTransform(final long transferAmount) { assertThat(this.transform.getTransform(), is(instanceOf(WriteTransfer.class))); final WriteTransfer writeTransfer = (WriteTransfer) this.transform.getTransform(); + assertThat(writeTransfer.getTransfer().getAmount(), is(BigInteger.valueOf(transferAmount))); + } - assertThat(writeTransfer.getTransfer().getDeployHash(), is(deploy.getHash().toString())); - assertThat(writeTransfer.getTransfer().getAmount(), is(new BigInteger("2500000000"))); - assertThat(writeTransfer.getTransfer().getTo(), is(userPublicKey.generateAccountHash(true))); - assertThat(writeTransfer.getTransfer().getFrom(), is(PublicKey.fromAbstractPublicKey(faucetPrivateKey.derivePublicKey()).generateAccountHash(true))); + @And("the speculative_exec execution_result transform with the transfer key has the {string} field set to the {string} account hash") + public void theSpeculative_execExecution_resultContainsAValidTransferFromField(final String fieldName, final String accountId) throws IOException { + + final String accountHash = getAccountHash(accountId); + final WriteTransfer writeTransfer = (WriteTransfer) this.transform.getTransform(); + if ("to".equals(fieldName)) { + assertThat(writeTransfer.getTransfer().getTo(), is(accountHash)); + } else { + assertThat(writeTransfer.getTransfer().getFrom(), is(accountHash)); + } } - @And("the speculative_exec execution_result contains a valid deploy transform") - public void theSpeculative_execExecution_resultContainsAValidDeployTransform() throws IOException { + @And("the speculative_exec execution_result transform with the transfer key has the {string} field set to the purse uref of the {string} account") + public void theSpeculative_execExecution_resultContainsAValidTransferSourceField(final String fieldName, final String accountId) throws IOException { + + String mainPurse = getAccountInfo(accountId).getAccount().getMainPurse(); + final WriteTransfer writeTransfer = (WriteTransfer) this.transform.getTransform(); + if ("source".equals(fieldName)) { + assertThat(writeTransfer.getTransfer().getSource(), is(mainPurse)); + } else { + assertThat(writeTransfer.getTransfer().getTarget().split("-")[0], is(mainPurse.split("-")[0])); + assertThat(writeTransfer.getTransfer().getTarget().split("-")[1], is(mainPurse.split("-")[1])); + } + } + + @And("the speculative_exec execution_result transform with the deploy key has the deploy_hash of the transfer's hash") + public void theSpeculative_execExecution_resultContainsAValidDeployTransformHash() { final String key = "deploy-" + deploy.getHash().toString(); final Optional transform = getTransform(key); assertThat(transform.isPresent(), is(true)); @@ -121,43 +150,58 @@ public void theSpeculative_execExecution_resultContainsAValidDeployTransform() t assertThat(transform.get().getKey(), is(key)); final WriteDeployInfo writeDeployInfo = (WriteDeployInfo) transform.get().getTransform(); - assertThat(writeDeployInfo.getDeployInfo().getGas(), is(BigInteger.valueOf(100000000L))); assertThat(writeDeployInfo.getDeployInfo().getHash(), is(deploy.getHash().toString())); - assertThat(writeDeployInfo.getDeployInfo().getFrom(), is(PublicKey.fromAbstractPublicKey(faucetPrivateKey.derivePublicKey()).generateAccountHash(true))); + } - final AccountData stateAccountInfo = casperService.getStateAccountInfo( - PublicKey.fromAbstractPublicKey(faucetPrivateKey.derivePublicKey()).getAlgoTaggedHex(), - HashBlockIdentifier.builder().hash(speculativeDeployData.getBlockHash()).build() - ); + @And("the speculative_exec execution_result transform with a deploy key has a gas field of {long}") + public void theSpeculative_execExecution_resultContainsAValidDeployTransformGas(final long gas) { + final WriteDeployInfo writeDeployInfo = getDeployTransform(); + assertThat(writeDeployInfo.getDeployInfo().getGas(), is(BigInteger.valueOf(gas))); + } - assertThat(writeDeployInfo.getDeployInfo().getSource().getJsonURef(), is(stateAccountInfo.getAccount().getMainPurse())); - assertThat(writeDeployInfo.getDeployInfo().getTransfers(), hasSize(1)); + @And("the speculative_exec execution_result transform with a deploy key has {int} transfer with a valid transfer hash") + public void theSpeculative_execExecution_resultContainsAValidDeployTransformTransfers(final int transfers) { + final WriteDeployInfo writeDeployInfo = getDeployTransform(); + assertThat(writeDeployInfo.getDeployInfo().getTransfers(), hasSize(transfers)); assertThat(writeDeployInfo.getDeployInfo().getTransfers().get(0), containsString("transfer-")); assertThat(writeDeployInfo.getDeployInfo().getTransfers().get(0).length(), is(73)); } - @And("the speculative_exec execution_result contains a valid balance transform") - public void theSpeculative_execExecution_resultContainsAValidBalanceTransform() { + @And("the speculative_exec execution_result transform with a deploy key has as from field of the {string} account hash") + public void theSpeculative_execExecution_resultContainsAValidDeployTransformFrom(final String faucet) throws IOException { + final WriteDeployInfo writeDeployInfo = getDeployTransform(); + assertThat(writeDeployInfo.getDeployInfo().getFrom(), is(getAccountHash(faucet))); + } - final AccountData stateAccountInfo = casperService.getStateAccountInfo( - PublicKey.fromAbstractPublicKey(faucetPrivateKey.derivePublicKey()).getAlgoTaggedHex(), - HashBlockIdentifier.builder().hash(speculativeDeployData.getBlockHash()).build() - ); + @And("the speculative_exec execution_result transform with a deploy key has as source field of the {string} account purse uref") + public void theSpeculative_execExecution_resultContainsAValidDeployTransformSource(final String faucet) throws IOException { + final WriteDeployInfo writeDeployInfo = getDeployTransform(); + assertThat(writeDeployInfo.getDeployInfo().getSource().getJsonURef(), is(getAccountInfo(faucet).getAccount().getMainPurse())); + } - final String mainPurse = stateAccountInfo.getAccount().getMainPurse(); - final List transforms = getBalanceTransforms(mainPurse.split("-")[1]); - assertThat(transforms.size(), is(greaterThan(4))); + @And("the speculative_exec execution_result contains at least {int} valid balance transforms") + public void theSpeculative_execExecution_resultContainsAValidBalanceTransform(final int min) throws IOException { + final List transforms = getFaucetBalanceTransforms(); + assertThat(transforms.size(), is(greaterThanOrEqualTo(min))); + } - Entry entry = transforms.get(0); + @And("the speculative_exec execution_result {int}st balance transform is an Identity transform") + public void theSpeculative_execExecution_resultContainsAValidBalanceIdentity(final int first) throws IOException { + final List transforms = getFaucetBalanceTransforms(); + final Entry entry = transforms.get(first - 1); Transform transform = entry.getTransform(); assertThat(transform, is(instanceOf(WriteContract.class))); assertThat(((WriteContract) transform).name(), is("IDENTITY")); + } - entry = transforms.get(transforms.size() - 1); - transform = entry.getTransform(); + @And("the speculative_exec execution_result last balance transform is an Identity transform is as WriteCLValue of type {string}") + public void theSpeculative_execExecution_resultContainsAValidBalanceLast(final String type) throws IOException { + final List transforms = getFaucetBalanceTransforms(); + final Entry entry = transforms.get(transforms.size() - 1); + final Transform transform = entry.getTransform(); assertThat(transform, is(instanceOf(WriteCLValue.class))); - assertThat(((WriteCLValue) transform).getClvalue().getClType().getTypeName(), is("U512")); + assertThat(((WriteCLValue) transform).getClvalue().getClType().getTypeName(), is(type)); final BigInteger value = (BigInteger) ((WriteCLValue) transform).getClvalue().getValue(); assertThat(value, is(greaterThan(BigInteger.valueOf(9999)))); } @@ -174,7 +218,8 @@ public void theSpeculative_execExecution_resultContainsAValidAddUIntTransform(lo assertThat(((AddUInt512) transform).getU512(), is(BigInteger.valueOf(value))); } - private List getBalanceTransforms(final String mainPurse) { + private List getFaucetBalanceTransforms() throws IOException { + final String mainPurse = getAccountInfo("faucet").getAccount().getMainPurse().split("-")[1]; return speculativeDeployData.getExecutionResult() .getEffect() .getTransforms() @@ -184,6 +229,41 @@ private List getBalanceTransforms(final String mainPurse) { } private Optional getTransform(final String key) { - return speculativeDeployData.getExecutionResult().getEffect().getTransforms().stream().filter(transform -> transform.getKey().equals(key)).findFirst(); + return speculativeDeployData.getExecutionResult() + .getEffect() + .getTransforms() + .stream().filter(transform -> transform.getKey().equals(key)).findFirst(); + } + + private AbstractPrivateKey getPrivateKey(final Object id) throws IOException { + if ("faucet".equals(id)) { + return getFaucetPrivateKey(); + } else { + return getUserPrivateKey(getUserId(id)); + } + } + + private int getUserId(Object id) { + return id instanceof Number ? (Integer) id : new Integer(id.toString().split("-")[1]); + } + + private String getAccountHash(Object accountId) throws IOException { + return PublicKey.fromAbstractPublicKey(getPrivateKey(accountId).derivePublicKey()).generateAccountHash(true); + } + + + private AccountData getAccountInfo(final Object accountId) throws IOException { + return casperService.getStateAccountInfo( + PublicKey.fromAbstractPublicKey(getPrivateKey(accountId).derivePublicKey()).getAlgoTaggedHex(), + HashBlockIdentifier.builder().hash(speculativeDeployData.getBlockHash()).build() + ); + } + + private WriteDeployInfo getDeployTransform() { + final String key = "deploy-" + deploy.getHash().toString(); + final Optional transform = getTransform(key); + return (WriteDeployInfo) transform + .orElseThrow(() -> new IllegalArgumentException("Missing deploy transform")) + .getTransform(); } } diff --git a/src/test/java/com/casper/sdk/e2e/utils/AssetUtils.java b/src/test/java/com/casper/sdk/e2e/utils/AssetUtils.java index f5ddf302b..5a2aad8dc 100644 --- a/src/test/java/com/casper/sdk/e2e/utils/AssetUtils.java +++ b/src/test/java/com/casper/sdk/e2e/utils/AssetUtils.java @@ -57,4 +57,11 @@ public static PublicKey getUserPublicKey(final int userId) throws IOException { publicKey.readPublicKey(user1KeyUrl.getFile()); return PublicKey.fromAbstractPublicKey(publicKey); } + + public static AbstractPrivateKey getUserPrivateKey(final int userId) throws IOException { + final URL userKeyUrl = getUserKeyAsset(1, userId, "secret_key.pem"); + final Ed25519PrivateKey privateKey = new Ed25519PrivateKey(); + privateKey.readPrivateKey(userKeyUrl.getFile()); + return privateKey; + } }